Skip to content

ci: use the shared Aam-Digital CI workflows - #4507

Merged
sleidig merged 13 commits into
masterfrom
ci/shared-workflows
Oct 20, 2026
Merged

sleidig merged 13 commits into
masterfrom
ci/shared-workflows

Conversation

@sleidig

@sleidig sleidig commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Moves ndb-core's CI onto the shared reusable workflows in Aam-Digital/.github (Aam-Digital/.github#1). Aam-Digital/.github#1 is merged and tagged v1; every uses: of a shared workflow points at @v1.

Changes

  • Image build: _build.yaml keeps the web app job. The image is built by the shared docker-image.yml (aamdigital/ndb-server on Docker Hub and ghcr.io/aam-digital/ndb-core, OCI labels, GHA cache, SOURCE_DATE_EPOCH=0 passed as build-arg).
    • PR images: tag pr-<n> only, linux/amd64 only (previously amd64 + arm64). The version label is pr-<n> (set by the shared workflow from the first tag), so _build.yaml has no labels input any more.
    • Every platform is built on a native runner (arm64 on ubuntu-24.04-arm, no QEMU), then merged into one multi-platform image per registry.
    • Images replaced by a later push are no longer deleted by the build: they stay untagged until the shared image-cleanup.yml (on PR close and after releases) deletes untagged images older than 2 days (feat: shared CI workflows, release automation, Renovate presets and org defaults .github#1).
    • Fork PRs now build the image without pushing, instead of skipping the job. The required check therefore also reports for forks.
  • Edge builds (on-master-push.yml, replaces the -master.N prereleases): every master push, after qa and qa-e2e, is built as X.Y.Z-edge.N = the last release with the patch number bumped, plus the commits since (e.g. 3.93.1-edge.39; shared edge-version.yml). There is no git tag and no GitHub release for it, so no GH_TOKEN on master pushes.
    • Image: <version>, plus edge and master (transition, see below) while it is the newest master commit. A newer push cancels an older edge build (concurrency), so edge never moves back.
    • Translations: i18n-publish-translations.yml is now also callable (workflow_call) and publishes locale/<edge version> without touching locale/latest, so new texts can be checked on edge before a release. The existing cleanup at the next full release removes these folders. Its version step now reads inputs.version first: under workflow_call, github.event_name is push.
  • Releases: shared release.yml, manual mode: create-release.yml → full release (the local prerelease cleanup job is gone).
    • The semantic-release plugins stay in .releaserc; the extra plugins and the Slack webhook are passed as before.
    • .releaserc: removed branches. The shared workflow always passes its own branches, so this block (including the stale official-release branch) was dead config.
  • Release images: tag-published.yml → release-published.yml, triggered on release: published instead of tag pushes.
    • stable / latest are set from the release's prerelease flag, not from a - in the tag name.
    • After a full release, the shared image-cleanup.yml (tags: "*-edge.*,*-master.*") deletes the old edge images from ghcr.io, then the untagged images older than 2 days. Images still tagged edge, master, stable or latest are kept. Docker Hub is not covered.
    • The Sentry sourcemap and release steps now key off the prerelease flag. i18n-publish-translations.yml already ran on release: published and is unchanged.
  • PR closed:
    • The shared image-cleanup.yml runs first. It cancels any running pull-request-updated.yml build of the PR, waits for it, then deletes pr-<n> from ghcr.io with all pages read and the manifests handled.
    • Then a local job removes the SSH deployment, deletes the Docker Hub tag (with the fixed /v2/auth/token login from fix(ci): reliably delete PR images when a PR is closed #4505), and deletes the GHA caches. It runs even if the image cleanup failed.
  • Node.js: .nvmrc (24.22.0) and "packageManager": "npm@12.2.0" replace _node-toolchain.yml. All jobs use setup-node with node-version-file: .nvmrc and install the npm from packageManager.
  • Lint: pr-title-lint.yml and the new actionlint.yml call the shared workflows. The actionlint step in qa / code-quality is removed; the job stays.
  • Renovate: extends the shared presets (default, node, docker). The custom regex manager for _node-toolchain.yml is no longer needed, and nvm is added to enabledManagers. Final Review labels, ignoreDeps and the additional reviewer are kept.
  • Community files: removed SECURITY.md, which now comes from the org defaults. ndb-core keeps its own .github/ISSUE_TEMPLATE/ (updated in chore: update agent instructions and process templates #4529, used by the feature-use-cases skill), CONTRIBUTING.md and the PR template.
  • Docs: build/README.md, CONTRIBUTING.md, README.md (Node version).

⚠️ Required status checks (ruleset master)

Observed on this PR (exact names):

old new
build / build-image (required) build / build-image / build (linux/amd64)
build / toolchain, qa / toolchain, qa-e2e / toolchain removed (no longer a job)
(new) build / build-image / merge (skipped for fork PRs, so never make it required)

Expected after merge (not observable on a PR: pull_request_target runs the base branch's workflow, so this PR still shows the old Validate PR title):

old new
Validate PR title (not required) pr-title / Validate PR title
actionlint step inside qa / code-quality separate check actionlint / actionlint

Unchanged and required: qa / test-unit, qa / code-quality, qa-e2e / test-e2e, deploy, CodeRabbit.
Suggested ruleset: replace build / build-image with build / build-image / build (linux/amd64), and add actionlint / actionlint (linting is no longer part of the required qa / code-quality) and pr-title / Validate PR title.
Switch the ruleset right when this merges, then update open PRs: PRs that branched from the old master keep reporting build / build-image and would block on the new name.

Edge transition (from #4506)

  1. With this merged, every master push builds X.Y.Z-edge.N. Its image is tagged <version>, edge and master.
    The 22 existing -master.N GitHub prereleases and their tags are deleted once by hand (one-time command in internal#392); nothing creates new ones.
  2. Switch the preview instance from :master to :edge (infra repo).
  3. Follow-up PR: drop the master tag here (edge,master → edge in on-master-push.yml). The shared workflows keep matching *-master.* for the cleanup.

Semver ordering: 3.93.1-edge.N sorts below the old 3.94.0-master.N. semantic-release is not affected, because a release branch ignores prerelease tags. Anything that picks images by highest semver instead of a fixed tag would prefer the old -master.N images until they are deleted at the next full release.

Behaviour changes to be aware of

  • Every push to master builds an edge image (and publishes its translations, redeploys the preview), including chore/docs pushes and pushes right after a release. Before, prereleases were only made for releasable commits. Wanted: Renovate's chore(deps) merges reach the preview instance before the next full release.
  • Docker Hub edge tags are not pruned (the shared image-cleanup.yml covers ghcr.io only), and there is now one per master push.
  • The release jobs only run on the default branch.

Testing

  • actionlint 1.7.12 with shellcheck 0.11.0: clean. It was also run against local copies of the shared workflows, so the inputs, secrets and permissions of every call are checked.
  • renovate-config-validator --strict (Renovate 44): valid. The local validator does not resolve the local>Aam-Digital/.github//… presets. They resolve only once feat: shared CI workflows, release automation, Renovate presets and org defaults .github#1 is on its default branch.
  • This PR's own CI exercises the PR image build; the image check is in the comment below. (The cleanup-replaced result there is outdated: that step was replaced by the PR-close sweep.)
  • Not testable before merge: everything on pull_request_target (PR title lint, PR close cleanup; they run the base branch's version), the edge build on master push (version, tags, edge translations), create-release.yml, release-published.yml (image tags, prune, Sentry) and i18n publishing. Check the first master push and the first full release after merging.

PR Checklist

Before you request a manual PR review from someone, please go through all of this list:

  • manually tested (all) required functionality yourself and added comment with clear steps for manual testing
  • reviewed the "Files changed" section of the PR briefly
  • added label "Final Review" to trigger UI regression testing (Argos visual review)
  • triggered CodeRabbit AI review by commenting "@coderabbitai review" (e2e tests run automatically on every push)
  • marked each code review comment as resolved (or commented on it with a question, if unsure)

--> then mark the PR "Ready for Review"


🤖 Generated with Claude Code

sleidig and others added 3 commits October 13, 2026 22:42
- image build: _build.yaml keeps the web app build and calls the shared
  docker-image workflow (Docker Hub + ghcr.io). PR images are linux/amd64
  only and the image of a previous push is deleted when it is replaced.
- releases: shared release workflow in manual mode. Master pushes create
  X.Y.Z-edge.N prereleases (formerly -master.N), create-release.yml the
  full release. Images are built on `release: published`, tagged
  `stable`/`latest` from the release's prerelease flag; prereleases get
  `edge` and, during the transition, `master`. Old prerelease images are
  pruned from ghcr.io after a full release.
- PR close: shared pr-image-cleanup (cancels running PR builds first),
  then deployment removal, Docker Hub tag and cache deletion.
- Node.js version from .nvmrc, npm version from packageManager
  (replaces _node-toolchain.yml).
- PR title lint and actionlint via the shared workflows.

Part of Aam-Digital/internal#392

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Node.js version is now read from .nvmrc (nvm manager), so the custom
regex manager for _node-toolchain.yml is no longer needed.

Part of Aam-Digital/internal#392

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
They are now provided for all repositories by Aam-Digital/.github.
CONTRIBUTING.md and the PR template stay, as they are specific to this
repository.

Part of Aam-Digital/internal#392

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: Aam-Digital/ndb-core/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f717579b-c644-497d-95cd-c080c1518363

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

Copy link
Copy Markdown
Contributor

Deployed to https://pr-4507.aam-digital.net/

# skipped for prereleases (e.g. -edge.n)
if: ${{ !github.event.release.prerelease }}
run: |
npm install -g @sentry/cli
# skipped for prereleases (e.g. -edge.n)
if: ${{ !github.event.release.prerelease }}
run: |
npm install -g @sentry/cli
# skipped for prereleases (e.g. -edge.n)
if: ${{ !github.event.release.prerelease }}
run: |
npm install -g @sentry/cli
# skipped for prereleases (e.g. -edge.n)
if: ${{ !github.event.release.prerelease }}
run: |
npm install -g @sentry/cli

env:
GH_TOKEN: ${{ github.token }}
actions: write # required for cancelling PR builds and deleting GitHub Actions caches
env:
GH_TOKEN: ${{ github.token }}
actions: write # required for cancelling PR builds and deleting GitHub Actions caches
packages: write # required for deleting GHCR images

permissions:
contents: read
packages: write # required for pushing to ghcr.io
The build name is passed to _build.yaml as an input.

Part of Aam-Digital/internal#392

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sleidig

sleidig commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

PR image check (registry API)

1st push (d01d…/6bc38bc): ghcr.io/aam-digital/ndb-core:pr-4507

  • index sha256:96fb4547…, with only an linux/amd64 manifest (sha256:c38aaca5…) and its attestation (sha256:fcb530e1…)
  • only tag on the package version: pr-4507
  • config created: 1970-01-01T00:00:00Z (SOURCE_DATE_EPOCH=0 still applies)
  • labels: org.opencontainers.image.version=pr-4507, plus source, revision, title, description, licenses, url, created
  • Docker Hub aamdigital/ndb-server:pr-4507: amd64 only, same platform manifest digest

2nd push (db8d03f): new index sha256:90b86aa1…. The "Delete replaced images" step logged:

deleted image sha256:96fb4547… (package version 1381493772)
deleted child manifest sha256:c38aaca5… (package version 1381493711)
deleted child manifest sha256:fcb530e1… (package version 1381493747)

All three package versions now return 404 from the packages API.

Check names as reported: build / build-image / build (pass), plus build / build-image / build-native (${{ matrix.platform }}) and build / build-image / merge (skipped, from the shared workflow's native-runner mode).

sleidig and others added 9 commits October 14, 2026 07:53
Part of Aam-Digital/internal#392

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The shared docker-image workflow no longer deletes replaced images itself; pr-image-cleanup now deletes
untagged images older than 2 days (Aam-Digital/.github#1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moved here from the shared preset's README (Aam-Digital/.github#1), since it only concerns this repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…prereleases

Uses the shared edge-version workflow (Aam-Digital/.github#1): version <last release, patch + 1>-edge.<commits
since>, tagged `edge` too while it is the newest commit. Edge images of a finished cycle are pruned after
the next full release. The shared release workflow no longer takes `type`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`secrets: inherit` is flagged by zizmor (blocking in qlty check). _build.yaml and
i18n-publish-translations.yml now declare the secrets they read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…HA_7

The workflow_dispatch input only selects which version's translations are re-published; it is
validated and affects no build output. qlty reported it because the file changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ombined image-cleanup.yml)

- image-prune.yml and pr-image-cleanup.yml are now one image-cleanup.yml (`tags` instead of `tag-patterns`; callers
  grant `actions: write` too).
- docker-image.yml builds every platform on a native runner: check names are now `<job> / build (<platform>)` and
  `<job> / merge`, and the `native-runners` input is gone.
- The `org.opencontainers.image.version` label of PR images is set by the shared workflow from the first tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps ndb-core's own issue templates (updated on master in #4529) instead of the org defaults, and carries master's
Node.js 24.22.0 update over into .nvmrc.
Aam-Digital/.github#1 is merged and tagged `v1`; its branch is deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sleidig
sleidig marked this pull request as ready for review October 20, 2026 09:52
@sleidig
sleidig merged commit 841bec9 into master Oct 20, 2026
18 checks passed
@sleidig
sleidig deleted the ci/shared-workflows branch October 20, 2026 09:53
sleidig added a commit that referenced this pull request Oct 20, 2026
…tdated CI flow diagram

- The jobs sentry-upload-sourcemaps and sentry-release become one job `sentry-release`. It installs the @sentry/cli
  version from package-lock.json (the one the build injects the debug IDs with) with --ignore-scripts, instead of the
  latest version with install scripts (SonarCloud findings from #4507), then creates the release and uploads the
  sourcemaps.
- Full releases only, by a job-level `if`: a step-level `if` reported a green job for an upload that never ran,
  which hid failing uploads before.
- .github/ci-cd-flow.drawio.png showed the CI flow before the shared workflows and is not referenced anywhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sleidig

sleidig commented Oct 23, 2026

Copy link
Copy Markdown
Member Author

🎉 This PR is included in version 4.0.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@sleidig sleidig added the released managed by CI (semantic-release) label Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released managed by CI (semantic-release)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants