Skip to content

ci: build, release and clean up images with the shared org workflows - #381

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

Part of Aam-Digital/internal#392: the CI building blocks move into reusable workflows in the org .github repo, so this repo keeps only what is specific to it.

Aam-Digital/.github#1 (shared workflows and Renovate presets) is merged and tagged v1; the shared workflows are called at @v1.

Changes

  • Images: the shared docker-image.yml replaces the local _build.yml.
    • Release image (on release: published): tags <version> plus stable and latest, which are set from the release's prerelease flag. Multi-platform (linux/amd64, linux/arm64) as since ci: build multi-platform image (amd64 + arm64) #380.
    • The labels stay the same, including org.opencontainers.image.version=<version> and the description. Each platform is built on a native runner (arm64 on ubuntu-24.04-arm, no QEMU). package.json's version is still set to the release version before the build.
    • PR image: only pr-<n>, linux/amd64 only. Its version label is now pr-<n> (was 0.0.0-pr.<n>), like the PR images of the other repos; package.json keeps 0.0.0-pr.<n>, because npm only accepts semver. PRs from forks only check that the image builds.
    • 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).
  • PR image cleanup (new, pr-closed.yml): the shared image-cleanup.yml deletes pr-<n> when the PR is closed. It first cancels a PR image build that is still running. Until now, nothing deleted PR images in this repo.
  • Edge builds (new, on-push.yml): every master push, after Lint, Test and E2E Tests, is built as X.Y.Z-edge.N (the last release with the patch number bumped, plus the commits since; shared edge-version.yml), tagged edge too while it is the newest commit. No git tag, no GitHub release. After each full release, on-release.yml prunes the edge images of the finished cycle (image-cleanup.yml with tags: "*-edge.*").
  • Releases: the shared release.yml (type: release, auto mode) replaces the local npx semantic-release job.
    • It still uses the GH_TOKEN PAT, so the release triggers the image build.
    • .releaserc.json (plugins, tagFormat) is unchanged; the shared workflow only sets branches to the default branch.
    • It still runs after Lint, Test and E2E Tests, now on master pushes only. The shared workflow puts every release run of the repo in one concurrency group, so a no-op release job of a branch push could otherwise replace a master release that is waiting in that group.
  • Node: .nvmrc pins the exact version 24.22.0 (was 24). The four hard-coded node-version: 24.22.0 in the workflows become node-version-file: .nvmrc. No packageManager field: nothing pins npm today. CI and the image use the npm that comes with Node.
  • Renovate: extends the shared presets (default, node, docker). It adds the nvm manager for .nvmrc. .nvmrc and FROM node: update together in one node group, and action majors are in the github-actions group.
  • New checks: pr-title / Validate PR title (shared pr-title-lint.yml, on pull_request_target) and actionlint / actionlint.
  • Top-level permissions: {} in the caller workflows (fixes qlty's checkov CKV2_GHA_1 finding). Each calling job grants only what its shared workflow needs.

Check names

before after
Lint, Test, E2E Tests unchanged
build / Build and publish replication-backend image build / build (linux/amd64), build / merge (PR); on releases also build / build (linux/arm64)
Create Release Create Release / release on master; Create Release (skipped) on other branches
– cleanup-image / cleanup (on close)
– pr-title / Validate PR title (new, see below)
– actionlint / actionlint (new)

master has classic branch protection without required checks, so nothing blocks on the renamed checks. Moving to a ruleset with required checks is a separate step (internal#392).

Testing

  • actionlint (with shellcheck) and prettier on all workflow files: clean. qlty check (checkov) on the workflows: clean.
  • renovate-config-validator --strict: valid. It cannot resolve the remote presets; the first Renovate run after .github#1 has to confirm them.
  • Before the job was limited to master, Create Release / release ran on this branch (b7d4b18). It only logged Releases are only created from the default branch 'master' and created nothing.
  • PR image of this PR compared with the current images: see the comment below. (Its cleanup-replaced part is outdated: that step was replaced by the PR-close sweep.)
  • Not testable before merge:
    • an actual release and the release image build;
    • pr-closed.yml (runs when this PR is closed);
    • pr-title-lint.yml (pull_request_target runs the base branch's workflow file, so it only shows up on the next PR).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added automated checks for workflow syntax and pull request title formatting.
    • Added automated cleanup of preview container images when pull requests close.
    • Added support for publishing preview, edge, release, and prerelease container images.
  • Improvements

    • Standardized Node.js version usage across automated checks.
    • Improved release image tagging, including stable tags for production releases.
    • Updated pull request builds to use versioned preview image tags.

sleidig and others added 2 commits October 13, 2026 20:17
Swap the local _build.yml for Aam-Digital/.github's docker-image.yml and
delete pr-<n> images when a PR is closed (pr-image-cleanup.yml).
PR images are amd64 only; release images stay amd64 + arm64 and get
stable/latest from the release's prerelease flag.

Refs Aam-Digital/internal#392

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

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: Aam-Digital/replication-backend/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bbcd0474-f119-4706-9056-b5554d63b631
📥 Commits

Reviewing files that changed from the base of the PR and between 801a5dc and 7aa536d.

📒 Files selected for processing: 9
  • .github/workflows/_build.yml
  • .github/workflows/actionlint.yml
  • .github/workflows/on-push.yml
  • .github/workflows/on-release.yml
  • .github/workflows/pr-closed.yml
  • .github/workflows/pr-release.yml
  • .github/workflows/pr-title-lint.yml
  • .nvmrc
  • renovate.json
💤 Files with no reviewable changes: 1
  • .github/workflows/_build.yml

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

The pull request updates CI checks and Node.js configuration. It replaces local container build and release steps with shared workflows, adds image cleanup for closed pull requests and stable releases, and changes Renovate settings.

Changes: Repository automation

Layer / File(s) Summary
Validation and toolchain configuration
.nvmrc, .github/workflows/on-push.yml, .github/workflows/actionlint.yml, .github/workflows/pr-title-lint.yml, renovate.json
The Node.js version is set to 24.22.0 and used by push checks. New actionlint and PR title lint workflows are added. Renovate now uses shared presets, enables the nvm manager, and adds an additional reviewer.
Pull request image lifecycle
.github/workflows/pr-release.yml, .github/workflows/pr-closed.yml
PR image builds use the shared Docker workflow, prepare a PR-specific package version, and push only for same-repository pull requests. A new workflow invokes image cleanup when a same-repository pull request closes.
Edge and release image lifecycle
.github/workflows/_build.yml, .github/workflows/on-push.yml, .github/workflows/on-release.yml
The local image build workflow is removed. Push and release workflows delegate release and image building to shared workflows. Edge builds publish version-derived tags; published releases use conditional stable tags, and non-prerelease releases trigger edge-image cleanup.

Priority: ⚪ Pending latest changes

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Suggested reviewers: tomwwinter, abhinegi2

Merge Risk: 🔵 Low · up to 7aa53

The workflows are mergeable with owner awareness: a release may leave one edge image behind for later cleanup, but the reviewed publishing paths otherwise match their intended tags.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: replacing repository-specific CI with shared organization workflows for image builds, releases, and cleanup.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (8 skipped: 8 unsupported.)

✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • 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.

Comment thread .github/workflows/pr-closed.yml Resolved
sleidig and others added 3 commits October 13, 2026 20:24
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread .github/workflows/pr-closed.yml Resolved
@sleidig

sleidig commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

Verification of the shared workflows on this PR

1. Multi-platform path (temporary commit 40ef59e: platforms: linux/amd64,linux/arm64)

  • build / build passed: QEMU was set up and the cache scope was replication-backend.
  • pr-381 was an OCI index with linux/amd64, linux/arm64 and 2 attestation manifests.
  • The labels match those of pr-380, which came from the old _build.yml:
    • version = 0.0.0-pr.381
    • the custom description was kept
    • source, revision, title, url, licenses, created
  • The npm version prepare step printed v0.0.0-pr.381.
  • The pr-image-cleanup.yml dry run:
    • Read all 608 versions of the package.
    • Planned to delete exactly the index plus its amd64, arm64 and 2 attestation manifests (5 versions).
    • Planned nothing else; untagged versions of other images were left alone.

2. Real cleanup (temporary commit d82559d: cleanup job before the build)

  • The job's GITHUB_TOKEN deleted the 5 versions above, so no PAT is needed for this package.
  • After that, the build pushed the amd64-only image.

3. Final state (temporary jobs reverted): pr-381 is

  • an OCI index with linux/amd64 + 1 attestation manifest,
  • with the same labels,
  • QEMU skipped.

Leftovers: the test pushes left two superseded pr-381 images as untagged versions:

  • 1380836392 + 1380836357, 1380836338
  • 1380845287 + 1380845254, 1380845230

Every push to a PR orphans the previous pr-<n> image like this, in every repo. pr-image-cleanup.yml deliberately deletes only the image that is still tagged. These versions can go with the one-time backlog cleanup.

🤖 Generated with Claude Code

…vate preset and lint callers

- Releases: the local semantic-release job is replaced by the shared release.yml
  (type: release on every push; it only releases on master). .releaserc.json is unchanged.
- .nvmrc pins the exact Node version 24.21.0; all workflows read it via node-version-file
  instead of four hard-coded versions.
- renovate.json extends the shared org presets (default, node, docker).
- New callers of the shared pr-title-lint and actionlint workflows.
- Top-level `permissions: {}` in the caller workflows (checkov CKV2_GHA_1);
  each calling job grants what the shared workflow needs.

Part of Aam-Digital/internal#392

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sleidig sleidig changed the title ci: use shared org workflows for image build and PR image cleanup ci: build, release and clean up images with the shared org workflows Oct 13, 2026
@sleidig

sleidig commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

Image check (registry manifests and config labels)

before: latest / stable (release 1.15.4, built before #380) before: pr-381 (ea42b96, previous push) after: pr-381 (f2cfe83, this push)
platforms linux/amd64 (single manifest) linux/amd64 + attestation linux/amd64 + attestation
org.opencontainers.image.version 1.15.4 0.0.0-pr.381 0.0.0-pr.381
org.opencontainers.image.description A proxy that implements the CouchDB replication protocol same same
title / source / url / licenses / revision set set set (revision = PR merge commit)

The labels are unchanged. Releases build linux/amd64 + linux/arm64 since #380, with tags <version>, stable and latest. The release path cannot run before merge.

cleanup-replaced: this push replaced the previous pr-381 image. The step "Delete replaced images" logged:

deleted image sha256:ea42b96b… (package version 1380858585)
deleted child manifest sha256:8acf77ab… (package version 1380858548)
deleted child manifest sha256:02f6c99c… (package version 1380858513)

The packages API returns 404 for all three versions now. So the job token can delete versions of this package.

Release job on a branch: Create Release / release ran and only logged Releases are only created from the default branch 'master', not from 'refs/heads/ci/shared-workflows'.

🤖 Generated with Claude Code

@sleidig
sleidig marked this pull request as ready for review October 13, 2026 20:46
sleidig and others added 7 commits October 13, 2026 22:53
The shared release workflow queues its runs in one concurrency group per repository, so a no-op
release job of a branch push could replace a master release that waits in that group.

Part of Aam-Digital/internal#392

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>
…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>
# Conflicts:
#	.github/workflows/on-push.yml
package.json keeps `0.0.0-pr.<n>` (npm only accepts semver); only the label override is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 merged commit 631b12a into master Oct 20, 2026
15 checks passed
@sleidig
sleidig deleted the ci/shared-workflows branch October 20, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant