Skip to content

feat(ui): Add static asset caching#5113

Merged
SoloJacobs merged 2 commits intoprometheus:mainfrom
SoloJacobs:cache-assets
Mar 30, 2026
Merged

feat(ui): Add static asset caching#5113
SoloJacobs merged 2 commits intoprometheus:mainfrom
SoloJacobs:cache-assets

Conversation

@SoloJacobs
Copy link
Copy Markdown
Contributor

@SoloJacobs SoloJacobs commented Mar 26, 2026

This PR uses vite to build the Elm ui. This has a number of consequences, which are detailed in the commit messages.
Most importantly, it introduces caching for static assets and removes the script.js build artifact from our repo.

This is an overview over the files provided by Alertmanager v0.31.1 via the ui, which might be handy for debugging:

URL Content-Type
/favicon.ico image/vnd.microsoft.icon
/ text/html; charset=utf-8
/script.js text/javascript; charset=utf-8
/lib/bootstrap-4.6.2-dist/css/bootstrap.min.css text/css; charset=utf-8
/lib/bootstrap-4.6.2-dist/css/bootstrap.min.css.map text/plain; charset=utf-8
/lib/elm-datepicker/css/elm-datepicker.css text/css; charset=utf-8
/lib/font-awesome-4.7.0/css/font-awesome.css text/css; charset=utf-8
/lib/font-awesome-4.7.0/css/font-awesome.min.css text/css; charset=utf-8
/lib/font-awesome-4.7.0/fonts/FontAwesome.otf application/vnd.oasis.opendocument.formula-template
/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.eot application/vnd.ms-fontobject
/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.svg image/svg+xml
/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf font/ttf
/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff font/woff
/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 font/woff2

Pull Request Checklist

  • Is this a new feature?
    • I have added tests that test the new feature's functionality
  • Does this change affect performance?
    • I have provided benchmarks comparison that shows performance is improved or is not degraded
      (I checked the binary sizes, and vite will show the web artifacts.)
  • Is this a breaking change?
    • Yes, you have to now locally build the ui. This can be done via a work space:
    go work use /home/solomonjacobs/git/alertmanager
  • Is this a breaking change?
    • My changes do not break the existing cluster messages
    • My changes do not break the existing api
  • I have added/updated the required documentation
  • I have signed-off my commits
  • I will follow best practices for contributing to this project

Which user-facing changes does this PR introduce?

FEATURE: Cache static assets with Cache-Control
CHANGE: `go get github.com/prometheus/alertmanager/ui` is no longer possible

Summary by CodeRabbit

  • New Features

    • Frontend build system upgraded to Vite for improved performance and development experience.
  • Tests

    • Enhanced web serving test coverage for asset delivery and route handling.
  • Chores

    • Updated build requirements: now requires Go and Node.js; run make build instead of go install.
    • Simplified frontend initialization and asset loading process.
    • Updated UI dependencies including Bootstrap and Font Awesome libraries.

Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.

URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}

FontAwesome.otf was removed entirely, this is not a web font.

Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).

In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.

This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:

```sh
go get github.com/prometheus/alertmanager/ui
```

Users now must build `ui/app/dist` from source.

The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.

Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, the Makefile used `:=` for the TEMPOPENAPI variable, causing
`mktemp` to run at parse time on every `make` invocation. The temp dir
was only cleaned up inside the `src/Data` recipe.

In the GitHub workflow, this left a root-owned `700` directory on the
host, which blocks `hashFiles` in post-job cleanups. Because of this, it
was previously not possible to invoke any `ui/app/Makefile` command
during the `test` stage.

Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

This pull request migrates the Alertmanager frontend from a simple script-based build to a modern Vite-based pipeline with OpenAPI code generation, removing CSS-loading logic from the Elm application and restructuring static asset serving.

Changes

Cohort / File(s) Summary
Build System Configuration
Makefile, ui/app/Makefile
Updated root Makefile to add ui-elm phony target and make build, lint, and assets depend on it. Added test phony target. Replaced ui/app/script.js rule with $(FRONTEND_DIR)/src/Data generated from api/v2/openapi.yaml. Reorganized ui/app/Makefile to build src/Data via containerized OpenAPI generator with fixed container name and trap-based cleanup, added incremental .build_stamp-based build target invoking npm run build, and changed clean to remove .build_stamp and dist.
Documentation
README.md
Removed go install instructions and replaced with source-build instructions explicitly requiring Go and Node.js, directing users to clone and run make build.
Frontend Dependency Management
ui/app/package.json
Added build npm script (vite build). Introduced vite, vite-plugin-elm, bootstrap, and font-awesome dependencies; removed uglify-js.
Elm Application Architecture
ui/app/src/Main.elm, ui/app/src/Types.elm, ui/app/src/Updates.elm, ui/app/src/Views.elm
Removed three Loading fields from Model initialization. Eliminated bootstrapCSS, fontAwesomeCSS, elmDatepickerCSS model fields and corresponding *CSSLoaded message handlers. Removed CSS-load gating from view; navbar and content now render unconditionally. Deleted CSS-related helpers (failureView, renderCSS, cssNode).
Frontend Entry Point & Build Configuration
ui/app/index.html, ui/app/src/main.js, ui/app/vite.config.mjs
Replaced inline Elm bootstrapping and asset loading in index.html with <div id="root"></div> container and ES module <script type="module"> pointing to /src/main.js. New main.js initializes Elm with localStorage-sourced flags and registers Elm ports for preference persistence. Added vite.config.mjs with base: "./" and elm() plugin.
Asset Management
ui/app/.gitignore, ui/app/lib/font-awesome-4.7.0/css/*
Modified .gitignore to untrack /openapi-* and track /.build_stamp. Deleted Font Awesome 4.7.0 stylesheet files (moving to npm dependency via package.json).
Server Asset Serving
ui/web.go, ui/web_test.go
Changed embedded asset source from app to app/dist. Replaced FileServerFS with custom serve helper using http.ServeContent and file-extension-based Content-Type derivation. Removed /script.js and /lib/* handlers; added / and /favicon.ico handlers plus /assets/*path with immutable caching (public, max-age=31536000, immutable). Introduced setCachePolicy to control cache headers. Updated tests to validate embedded filesystem end-to-end via HTTP, including per-asset 200 checks, caching headers, 404 responses, and route-prefix support.

Sequence Diagrams

sequenceDiagram
    participant Dev as Developer
    participant Make as make build
    participant Docker as OpenAPI<br/>Generator
    participant Node as npm build<br/>(Vite)
    participant Elm as Elm Compiler
    participant Dist as dist/

    Dev->>Make: Invoke make build
    Make->>Docker: Run container<br/>api/v2/openapi.yaml
    Docker->>Docker: Generate src/Data
    Docker->>Make: Copy src/Data & src/DateTime.elm
    Make->>Node: Invoke npm run build<br/>(src/main.js entry)
    Node->>Elm: Transform Elm modules
    Elm->>Node: Compiled JS + CSS
    Node->>Dist: Write dist/ + .build_stamp
Loading
sequenceDiagram
    participant Browser
    participant Server as ui/web.go
    participant Dist as app/dist<br/>(embedded FS)
    participant LocalStorage as Browser<br/>localStorage
    participant Elm as Elm.Main
    participant Port as Elm Ports

    Browser->>Server: GET /
    Server->>Dist: Lookup index.html
    Dist->>Server: Return index.html
    Server->>Browser: Serve index.html

    Browser->>Browser: Load <script type="module"><br/>src/main.js
    Browser->>LocalStorage: Read flags<br/>(firstDayOfWeek, etc.)
    LocalStorage->>Browser: flags object
    Browser->>Elm: Initialize with flags,<br/>node id="root"
    Elm->>Browser: Render UI

    User->>Browser: Change setting
    Browser->>Port: persistDefaultCreator
    Port->>LocalStorage: Store preference
    LocalStorage->>LocalStorage: Persist
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Poem

🐰 From script to Vite, our build takes flight,
OpenAPI schemas dance in the night,
Elm ports persist what users hold dear,
Assets immutable, caching crystal clear,
A modern frontend, rebuilt with care! 🚀

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description provides context and release notes but is incomplete against template requirements. Missing signed-off commits assertion, issue linking (no Fixes #X), benchmark details despite performance claims, and incomplete breaking change checklist.
Title check ✅ Passed The title 'feat(ui): Add static asset caching' clearly and concisely summarizes the main change—introducing caching for static assets in the UI—which is the primary objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
ui/app/src/main.js (1)

6-14: Consider guarding JSON.parse calls against corrupted localStorage values.

JSON.parse(localStorage.getItem('firstDayOfWeek')) and JSON.parse(localStorage.getItem('groupExpandAll')) will throw if the stored value is malformed (e.g., manually edited or corrupted). While the Elm decoder handles null gracefully via Result.withDefault, a parse error would crash initialization.

🛡️ Optional: Add defensive parsing
+function safeJsonParse(key, fallback) {
+    try {
+        const item = localStorage.getItem(key);
+        return item !== null ? JSON.parse(item) : fallback;
+    } catch {
+        return fallback;
+    }
+}
+
 const app = Elm.Main.init({
     node: document.getElementById('root'),
     flags: {
         production: true,
-        firstDayOfWeek: JSON.parse(localStorage.getItem('firstDayOfWeek')),
+        firstDayOfWeek: safeJsonParse('firstDayOfWeek', null),
         defaultCreator: localStorage.getItem('defaultCreator'),
-        groupExpandAll: JSON.parse(localStorage.getItem('groupExpandAll'))
+        groupExpandAll: safeJsonParse('groupExpandAll', null)
     }
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ui/app/src/main.js` around lines 6 - 14, Guard the JSON.parse calls used in
the Elm startup flags to avoid throwing on malformed localStorage values: wrap
parsing of localStorage.getItem('firstDayOfWeek') and
localStorage.getItem('groupExpandAll') in a safe parse (e.g., try/catch or a
small helper like safeJSONParse) and fall back to null or a sensible default
when parsing fails, then pass those safe values into Elm.Main.init(flags)
alongside defaultCreator; update the code around Elm.Main.init and the flags
construction to use the safe parser for firstDayOfWeek and groupExpandAll.
ui/app/Makefile (2)

21-30: The test target should also be declared .PHONY.

Similar to all, the test target should be declared .PHONY to ensure it always runs regardless of whether a file named test exists. This is flagged by checkmake.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ui/app/Makefile` around lines 21 - 30, Add the `test` target to the `.PHONY`
declaration so Make always executes the `test` recipe regardless of a file named
"test"; update the existing `.PHONY` line (alongside the `all` target) to
include `test` (referencing the Makefile's `test` target) so checkmake warnings
are resolved.

9-9: Declare all as .PHONY to prevent file collision.

If a file named all exists in the directory, Make will consider the target up-to-date and skip execution. The all target should be declared .PHONY.

Suggested fix

Add this declaration near line 56 (with the existing .PHONY declarations):

+.PHONY: all
+all: src/Data build test
+
-.PHONY: build
+.PHONY: build test
 build: .build_stamp
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ui/app/Makefile` at line 9, The `all` Make target is not declared phony, so
if a file named "all" exists Make may skip running targets; update the Makefile
to include `all` in the existing `.PHONY` declaration (add `all` to the
comma/space-separated list with the other phony targets) so the `all: src/Data
build test` target always executes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@ui/app/Makefile`:
- Around line 21-30: Add the `test` target to the `.PHONY` declaration so Make
always executes the `test` recipe regardless of a file named "test"; update the
existing `.PHONY` line (alongside the `all` target) to include `test`
(referencing the Makefile's `test` target) so checkmake warnings are resolved.
- Line 9: The `all` Make target is not declared phony, so if a file named "all"
exists Make may skip running targets; update the Makefile to include `all` in
the existing `.PHONY` declaration (add `all` to the comma/space-separated list
with the other phony targets) so the `all: src/Data build test` target always
executes.

In `@ui/app/src/main.js`:
- Around line 6-14: Guard the JSON.parse calls used in the Elm startup flags to
avoid throwing on malformed localStorage values: wrap parsing of
localStorage.getItem('firstDayOfWeek') and
localStorage.getItem('groupExpandAll') in a safe parse (e.g., try/catch or a
small helper like safeJSONParse) and fall back to null or a sensible default
when parsing fails, then pass those safe values into Elm.Main.init(flags)
alongside defaultCreator; update the code around Elm.Main.init and the flags
construction to use the safe parser for firstDayOfWeek and groupExpandAll.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 25288fc3-3dc4-4e02-bbf8-278dd0d76d21

📥 Commits

Reviewing files that changed from the base of the PR and between 8a11f85 and 1723d90.

⛔ Files ignored due to path filters (9)
  • ui/app/lib/bootstrap-4.6.2-dist/css/bootstrap.min.css.map is excluded by !**/*.map
  • ui/app/lib/font-awesome-4.7.0/fonts/FontAwesome.otf is excluded by !**/*.otf
  • ui/app/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.eot is excluded by !**/*.eot
  • ui/app/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.svg is excluded by !**/*.svg
  • ui/app/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf is excluded by !**/*.ttf
  • ui/app/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff is excluded by !**/*.woff
  • ui/app/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 is excluded by !**/*.woff2
  • ui/app/package-lock.json is excluded by !**/package-lock.json
  • ui/app/public/favicon.ico is excluded by !**/*.ico
📒 Files selected for processing (19)
  • Makefile
  • README.md
  • ui/app/.gitignore
  • ui/app/Makefile
  • ui/app/index.html
  • ui/app/lib/bootstrap-4.6.2-dist/css/bootstrap.min.css
  • ui/app/lib/font-awesome-4.7.0/css/font-awesome.css
  • ui/app/lib/font-awesome-4.7.0/css/font-awesome.min.css
  • ui/app/package.json
  • ui/app/script.js
  • ui/app/src/Main.elm
  • ui/app/src/Types.elm
  • ui/app/src/Updates.elm
  • ui/app/src/Views.elm
  • ui/app/src/assets/elm-datepicker.css
  • ui/app/src/main.js
  • ui/app/vite.config.mjs
  • ui/web.go
  • ui/web_test.go
💤 Files with no reviewable changes (5)
  • ui/app/src/Updates.elm
  • ui/app/src/Main.elm
  • ui/app/lib/font-awesome-4.7.0/css/font-awesome.min.css
  • ui/app/src/Types.elm
  • ui/app/lib/font-awesome-4.7.0/css/font-awesome.css

Copy link
Copy Markdown
Contributor

@sysadmind sysadmind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really know elm, but from a once over, it seems fine. I didn't try to run the build process, but I don't see anything that I find concerning.

endif

all: script.js test
all: src/Data build test
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this and the other modified make targets be PHONY?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, almost all targets in the file should be PHONY. I have a follow-up commit, where I fix this for all the targets. However, it is not strictly necessary for this feature, and the target wasn't PHONY there before.



set -e; \
$(DOCKER) run \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this container have --rm? Should it stick around? If it's going to stay around, I would expect it to have a more unique --name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trap will remove the docker container again, and we can't immediately remove the container, since we need to copy the files.

@TheMeier
Copy link
Copy Markdown
Contributor

I also did a rough review and manually tested some functionality. So far it looks good to me.

@SoloJacobs SoloJacobs changed the title feat(ui): Add static asset feat(ui): Add static asset caching Mar 27, 2026
Copy link
Copy Markdown
Contributor

@Spaceman1701 Spaceman1701 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't patch this into my checkout and run it, but I trust that you've run it @SoloJacobs.

@SoloJacobs SoloJacobs merged commit 1d6097c into prometheus:main Mar 30, 2026
8 checks passed
SoloJacobs added a commit to SoloJacobs/alertmanager that referenced this pull request Apr 6, 2026
* [CHANGE] `go get github.com/prometheus/alertmanager/ui` will now fail as compiled UI assets are no longer checked into the repository. Downstream builds that rely on these assets being present in the source tree must now build the UI from source. prometheus#5113
* [CHANGE] The '--enable-feature=auto-gomaxprocs' option is deprecated and will be removed in v0.33. This flag currently has no effect and can be safely removed from any startup scripts. prometheus#5090
* [CHANGE] Update internal function signatures across multiple packages. This affects any project that integrates `Alertmanager` code.
* [ENHANCEMENT] Add static asset caching. prometheus#5113
* [ENHANCEMENT] Reduce memory allocations through pre-sizing collections and batch allocation. prometheus#5020
* [ENHANCEMENT] Replace help with documentation in navigation bar. prometheus#4943
* [ENHANCEMENT] docs(ha): Update high availability documentation. prometheus#5136
* [ENHANCEMENT] docs: Add `auth_secret_file` for smtp in document. prometheus#5036
* [ENHANCEMENT] docs: Add description for global `telegram_bot_token`. prometheus#5114
* [ENHANCEMENT] docs: Add note about notifier timeouts. prometheus#5077
* [ENHANCEMENT] docs: Fix `force_implicit_tls` config field name. prometheus#5030
* [ENHANCEMENT] docs: Link community supported integrations. prometheus#4978
* [ENHANCEMENT] docs: Remove duplicate header. prometheus#5034
* [ENHANCEMENT] docs: Update mutual tls reference in high availability documentation. prometheus#5120
* [ENHANCEMENT] tracing: Use noop spans when tracing disabled. prometheus#5118
* [FEATURE] Add silence annotations. prometheus#4965
* [FEATURE] Add silence logging option. prometheus#4163
* [FEATURE] Add support for multiple matcher set silences. prometheus#4957
* [FEATURE] Add the reason for notifying in dedup stage. prometheus#4971
* [FEATURE] mattermost: Flatten attachments into top-level config. prometheus#5009
* [FEATURE] mattermost: Support global webhook url. prometheus#4998
* [FEATURE] slack: Add default color from template. prometheus#5014
* [FEATURE] slack: Allow receiver to edit existing messages. prometheus#5007
* [FEATURE] template: Add dict, map and append functions. prometheus#5093
* [FEATURE] webhook: Add full payload templating support for notifier. prometheus#5011
* [BUGFIX] config: Check for empty cluster tls client config. prometheus#5126
* [BUGFIX] config: Don't crash upon reading empty config for notifier. prometheus#4979
* [BUGFIX] config: Fix ipv6 address handling in hostport.string(). prometheus#5040
* [BUGFIX] mattermost: Omit empty text field in notifications. prometheus#4985
* [BUGFIX] telegram: Send fallback message when notification exceeds character limit. prometheus#5074
* [BUGFIX] ui: Fix escaping for matcher values with quotes. prometheus#4862
* [BUGFIX] ui: Handle special chars in silence regex-matchers. prometheus#4942
* [BUGFIX] ui: Support utf-8 label names in matchers. prometheus#5089

Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
@SoloJacobs SoloJacobs mentioned this pull request Apr 6, 2026
ultrotter pushed a commit that referenced this pull request Apr 7, 2026
* [CHANGE] `go get github.com/prometheus/alertmanager/ui` will now fail as compiled UI assets are no longer checked into the repository. Downstream builds that rely on these assets being present in the source tree must now build the UI from source. #5113
* [CHANGE] The '--enable-feature=auto-gomaxprocs' option is deprecated and will be removed in v0.33. This flag currently has no effect and can be safely removed from any startup scripts. #5090
* [CHANGE] Update internal function signatures across multiple packages. This affects any project that integrates `Alertmanager` code.
* [ENHANCEMENT] Add static asset caching. #5113
* [ENHANCEMENT] Reduce memory allocations through pre-sizing collections and batch allocation. #5020
* [ENHANCEMENT] Replace help with documentation in navigation bar. #4943
* [ENHANCEMENT] docs(ha): Update high availability documentation. #5136
* [ENHANCEMENT] docs: Add `auth_secret_file` for smtp in document. #5036
* [ENHANCEMENT] docs: Add description for global `telegram_bot_token`. #5114
* [ENHANCEMENT] docs: Add note about notifier timeouts. #5077
* [ENHANCEMENT] docs: Fix `force_implicit_tls` config field name. #5030
* [ENHANCEMENT] docs: Link community supported integrations. #4978
* [ENHANCEMENT] docs: Remove duplicate header. #5034
* [ENHANCEMENT] docs: Update mutual tls reference in high availability documentation. #5120
* [ENHANCEMENT] tracing: Use noop spans when tracing disabled. #5118
* [FEATURE] Add silence annotations. #4965
* [FEATURE] Add silence logging option. #4163
* [FEATURE] Add support for multiple matcher set silences. #4957
* [FEATURE] Add the reason for notifying in dedup stage. #4971
* [FEATURE] mattermost: Flatten attachments into top-level config. #5009
* [FEATURE] mattermost: Support global webhook url. #4998
* [FEATURE] slack: Add default color from template. #5014
* [FEATURE] slack: Allow receiver to edit existing messages. #5007
* [FEATURE] template: Add dict, map and append functions. #5093
* [FEATURE] webhook: Add full payload templating support for notifier. #5011
* [BUGFIX] config: Check for empty cluster tls client config. #5126
* [BUGFIX] config: Don't crash upon reading empty config for notifier. #4979
* [BUGFIX] config: Fix ipv6 address handling in hostport.string(). #5040
* [BUGFIX] mattermost: Omit empty text field in notifications. #4985
* [BUGFIX] telegram: Send fallback message when notification exceeds character limit. #5074
* [BUGFIX] ui: Fix escaping for matcher values with quotes. #4862
* [BUGFIX] ui: Handle special chars in silence regex-matchers. #4942
* [BUGFIX] ui: Support utf-8 label names in matchers. #5089

Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
@k0ste
Copy link
Copy Markdown

k0ste commented Apr 9, 2026

Seems this change missed ui-assets tarball release, like in Prometheus. Sometimes is hard to bring up npm only for build assets... Please provide tarball with release

@SoloJacobs
Copy link
Copy Markdown
Contributor Author

Hi @k0ste ,

thanks for the feedback. Could you provide a reference to the upstream project where this is needed? The build process between alertmanager and Prometheus differs.

Kind regards

@k0ste
Copy link
Copy Markdown

k0ste commented Apr 9, 2026

thanks for the feedback. Could you provide a reference to the upstream project where this is needed? The build process between alertmanager and Prometheus differs.

For example EPEL prometheus package


We also have custom build with reduced SD integrations, also but don't builtin assets to binary. Source SPEC

%global debug_package %{nil}
%define _build_id_links none
Summary: An open-source systems monitoring and alerting toolkit
Name: prometheus
Version: 3.11.0
%define _archversion 3.10.0-1
Release: 1%{?dist}
License: Apache-2.0
BuildRequires: golang >= 1.25 git systemd-rpm-macros
%define _uri github.com/%{name}
Url: https://%{_uri}/%{name}
Source0: https://codeload.%{_uri}/%{name}/tar.gz/refs/tags/v%{version}#/%{name}-%{version}.tar.gz
Source1: %{url}/releases/download/v%{version}/%{name}-web-ui-%{version}.tar.gz
Source2: https://gitlab.archlinux.org/archlinux/packaging/packages/%{name}/-/raw/%{_archversion}/%{name}.sysusers
Source3: https://gitlab.archlinux.org/archlinux/packaging/packages/%{name}/-/raw/%{_archversion}/%{name}.service
Source4: https://gitlab.archlinux.org/archlinux/packaging/packages/%{name}/-/raw/%{_archversion}/%{name}.conf

%description
Prometheus, a Cloud Native Computing Foundation project, is a systems and
service monitoring system. It collects metrics from configured targets at given
intervals, evaluates rule expressions, displays the results, and can trigger
alerts when specified conditions are observed

%prep
%setup -c -q
%setup -a 1 -qcTD
rm -rf "%{name}-%{version}/web/ui/static"
mv "static" "%{name}-%{version}/web/ui"

export GOPATH="%{_builddir}/gopath"
export GOBIN="${GOPATH}/bin"
mkdir -p "${GOPATH}/src/%{_uri}"
ln -snf "%{_builddir}/%{name}-%{version}/%{name}-%{version}" \
"${GOPATH}/src/%{_uri}/%{name}"

%build
export GOCACHE="${HOME}/pkgcache/go-cache"
export GOMODCACHE="${HOME}/pkgcache/go"
export GOTMPDIR="%{_builddir}"
export GOPATH="%{_builddir}/gopath"
export GOBIN="${GOPATH}/bin"
cd "${GOPATH}/src/%{_uri}/%{name}"
eval "$(go env | grep -e "GOHOSTOS" -e "GOHOSTARCH")"

pushd "web/ui"
go generate -x
popd

go generate -x -tags="plugins" "./plugins"

GOFLAGS="-linkmode external \
  -X %{_uri}/common/version.Version=%{version} \
  -X %{_uri}/common/version.Revision=%{release} \
  -X %{_uri}/common/version.Branch=tarball \
  -X %{_uri}/common/version.BuildUser=$(whoami)@mockbuild \
  -X %{_uri}/common/version.BuildDate=$(date +%%Y%%m%%d)"

# Build prometheus & promtool
# tags: https://github.com/prometheus/prometheus/blob/main/.promu.yml#L14
# WARNING: 'builtinassets' break the build
# 'remove_all_sd' - we don't need any SD, except file/HTTP (builtin by default)
for e in "%{name}" "promtool"
  do
    GOOS="${GOHOSTOS}" GOARCH="${GOHOSTARCH}" \
      go build -x \
      -tags="netgo,remove_all_sd" \
      -buildmode="pie" \
      -trimpath \
      -mod="readonly" \
      -modcacherw \
      -ldflags "${GOFLAGS}" "./cmd/${e}"
done

%check
cd "%{name}-%{version}"
eval "$(go env | grep -e "GOHOSTOS" -e "GOHOSTARCH")"
GOOS="${GOHOSTOS}" GOARCH="${GOHOSTARCH}" go test -x ./...

%install
install -Dm0644 "%{SOURCE2}" "%{buildroot}%{_sysusersdir}/%{name}.conf"
install -Dm0644 "%{SOURCE3}" -t "%{buildroot}%{_unitdir}"
install -Dm0644 "%{SOURCE4}" "%{buildroot}%{_sysconfdir}/conf.d/%{name}"

pushd "%{name}-%{version}"
install -Dm0755 -d "%{buildroot}%{_sharedstatedir}/%{name}"
install -Dm0755 "%{name}" -t "%{buildroot}%{_bindir}"
install -Dm0755 "promtool" -t "%{buildroot}%{_bindir}"
install -Dm0644 "documentation/examples/%{name}.yml" -t \
  "%{buildroot}%{_sysconfdir}/%{name}"

# Web
install -Dm0755 -d "%{buildroot}%{_datadir}/%{name}/web/ui"
cp --recursive "web/ui/static" "%{buildroot}%{_datadir}/%{name}/web/ui"
# Examples
install -Dm0644 "documentation/examples/%{name}"*".yml" -t \
  "%{buildroot}%{_datadir}/%{name}/examples"

%pre
%sysusers_create_package %{name} "%{SOURCE2}"

%post
%systemd_post %{name}.service

%preun
%systemd_preun %{name}.service

%postun
%systemd_postun %{name}.service

%files
%license %{name}-%{version}/LICENSE
%attr(0755,root,root) %{_bindir}/{%{name},promtool}
%dir %attr(0755,%{name},%{name}) %{_sharedstatedir}/%{name}
%defattr(0644,root,root,0755)
%{_datadir}/%{name}
%{_unitdir}/%{name}.service
%{_sysusersdir}/%{name}.conf
%config(noreplace) %{_sysconfdir}/conf.d/%{name}
%config(noreplace) %{_sysconfdir}/%{name}/%{name}.yml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants