diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5eaf83986..f7311cd47 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -2,6 +2,10 @@ name: Docker on: workflow_dispatch: + inputs: + version: + description: "Version to stamp into the image contents and exact image tag" + required: false release: types: [published] @@ -41,6 +45,29 @@ jobs: steps: - uses: actions/checkout@v6 + - name: Determine image version + id: version + env: + MANUAL_VERSION: ${{ github.event.inputs.version }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + run: | + version="${MANUAL_VERSION#v}" + if [ -z "$version" ] && [ -n "$RELEASE_TAG" ]; then + version="${RELEASE_TAG#v}" + fi + printf 'version=%s\n' "$version" >> "$GITHUB_OUTPUT" + + - name: Set up Python + if: steps.version.outputs.version != '' + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Sync versioned files for image build + if: steps.version.outputs.version != '' + run: | + python scripts/version-sync.py --version ${{ steps.version.outputs.version }} + - name: Set up QEMU uses: docker/setup-qemu-action@v4 @@ -62,6 +89,7 @@ jobs: tags: | type=ref,event=branch,suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }} type=ref,event=pr,suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }} + type=raw,value=${{ steps.version.outputs.version }},enable=${{ steps.version.outputs.version != '' }},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }} type=semver,pattern={{version}},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }} type=semver,pattern={{major}}.{{minor}},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }} type=semver,pattern={{major}},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }} diff --git a/docs/content/docs/releases.mdx b/docs/content/docs/releases.mdx index 44685e31b..6d43b8e3a 100644 --- a/docs/content/docs/releases.mdx +++ b/docs/content/docs/releases.mdx @@ -7,6 +7,8 @@ description: Automated release pipeline with semantic versioning, multi-package Headroom uses a unified GitHub Actions workflow (`.github/workflows/release.yml`) that automatically publishes all three packages, generates changelogs from conventional commits, and creates GitHub Releases. +Publishing a GitHub Release also triggers `.github/workflows/docker.yml`, which builds GHCR images tagged with the same semantic version and syncs the image contents to that exact release version before build. + ## Packages & Registries | Package | Type | Registry | Environment Variable | @@ -15,6 +17,7 @@ Headroom uses a unified GitHub Actions workflow (`.github/workflows/release.yml` | `headroom-ai` | TypeScript SDK | npmjs.org | `NPM_SDK_PACKAGE` | | `headroom-openclaw` | TypeScript plugin | npmjs.org | `NPM_OPENCLAW_PACKAGE` | | `headroom-openclaw` | TypeScript plugin | GitHub Package Registry | — | +| `ghcr.io/chopratejas/headroom` | Docker image | GitHub Container Registry | — | ## Version Strategy diff --git a/wiki/docker-install.md b/wiki/docker-install.md index 9093c90c5..634fcc9b4 100644 --- a/wiki/docker-install.md +++ b/wiki/docker-install.md @@ -41,6 +41,8 @@ The wrapper keeps Headroom inside Docker and mounts host state back into the con Port `8787` stays the default, so `http://localhost:8787` works the same way as a native install. +Published releases also push versioned GHCR tags such as `ghcr.io/chopratejas/headroom:0.5.26`, and those images are built with the same synced package version used for the matching PyPI and npm release. + ## How the wrapper behaves ### Native Headroom commands