mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 17:45:53 +01:00
ci(docker): add workflow_dispatch to build a SHA-tagged preview image
`docker.yml` only triggered on `push` to `master` and on `v*` tags, so
there was no way to build an image from an unmerged branch. Previewing a
change end to end before merging therefore had no image to deploy, and
because the concurrency group is `docker-${github.ref}` a *pending*
master run can still be superseded by the next push — so an arbitrary
master SHA is not guaranteed to have an image either.
Add a `workflow_dispatch` trigger with an optional `ref` input:
- The manual run checks out `inputs.ref` (falling back to `github.sha`),
resolves the exact commit, and publishes a `sha-<short>` image tag for
that commit. The `latest` and `v*`/semver tags stay gated to the push
and tag events, so a dispatch never publishes a release tag.
- `type=sha` is kept exactly as-is for push/tag events; the dispatch tag
is emitted as a raw `sha-<short>` of the resolved commit so it is
correct even when the built ref differs from `github.sha`.
- The commit stamped into the image (`PAPERCLIP_BUILD_COMMIT`) is taken
from the same resolved commit; on push/tag it equals `github.sha`, so
those builds are unchanged.
This is intentionally not the release workflow, which publishes a stable
`v*` tag — a much bigger act than building a review image. The resulting
`sha-<short>` tag is consumed as an ordinary app ref by the fleet deploy
tooling, so nothing downstream changes.
Tested: `actionlint` clean on the workflow; YAML parses; verified the
diff leaves the push/tag paths byte-for-byte behaviourally identical
(`ref` and `PAPERCLIP_BUILD_COMMIT` both resolve to `github.sha`, and
`type=sha` is unchanged when `github.event_name != 'workflow_dispatch'`).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
19be4cf927
commit
02c6fa1c6c
1 file changed
+63
-4
@@ -6,6 +6,19 @@ on:
|
||||
- "master"
|
||||
tags:
|
||||
- "v*"
|
||||
# Manual builds so an unmerged ref can be previewed before it lands. This
|
||||
# publishes a SHA-tagged image and no `latest`/`v*` (release) tag — it is a
|
||||
# review image, not a release — and the deploy tooling accepts the resulting
|
||||
# `sha-<short>` tag as an ordinary app ref, so nothing downstream changes.
|
||||
# Deliberately not the release workflow: that one publishes a stable `v*`
|
||||
# release, a far bigger act than building a preview image.
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: "Branch, tag, or commit SHA to build. Defaults to the ref this run was dispatched on."
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -26,10 +39,29 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
# push/tag builds resolve to github.sha — the checkout default, so
|
||||
# their behaviour is unchanged. A manual run may override it with the
|
||||
# `ref` input to build an unmerged branch, tag, or commit.
|
||||
ref: ${{ inputs.ref || github.sha }}
|
||||
# Full history and tags so `git describe` below can compute the
|
||||
# release version to stamp into the image.
|
||||
fetch-depth: 0
|
||||
|
||||
# Pin every downstream reference to the exact commit that was checked
|
||||
# out. On push/tag builds this equals github.sha; on a manual run it is
|
||||
# the head of the `ref` input, which can differ from github.sha (the ref
|
||||
# the dispatch ran on). The SHA image tag and the commit stamped into the
|
||||
# image are both derived from this, so a manual build always tags the
|
||||
# commit it actually built.
|
||||
- name: Resolve build ref
|
||||
id: resolve-ref
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sha="$(git rev-parse HEAD)"
|
||||
echo "sha=${sha}" >> "$GITHUB_OUTPUT"
|
||||
echo "short_sha=$(git rev-parse --short=7 HEAD)" >> "$GITHUB_OUTPUT"
|
||||
echo "Building ${GITHUB_REF} at ${sha}"
|
||||
|
||||
# `.git` is dockerignored, so a running image cannot derive its own
|
||||
# version and otherwise reports the source package.json placeholder in
|
||||
# analytics and the debug panel. Compute it here from the pristine
|
||||
@@ -140,7 +172,11 @@ jobs:
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=sha
|
||||
# push/tag builds keep the stock sha tag (sha-<short> of github.sha).
|
||||
# A manual run may build a ref other than github.sha, so it tags the
|
||||
# resolved commit instead — same sha-<short> format, correct commit.
|
||||
type=sha,enable=${{ github.event_name != 'workflow_dispatch' }}
|
||||
type=raw,value=sha-${{ steps.resolve-ref.outputs.short_sha }},enable=${{ github.event_name == 'workflow_dispatch' }}
|
||||
labels: |
|
||||
io.github.paperclipai.schema.last-migration=${{ steps.schema.outputs.last }}
|
||||
io.github.paperclipai.schema.migration-count=${{ steps.schema.outputs.count }}
|
||||
@@ -155,7 +191,7 @@ jobs:
|
||||
target: production
|
||||
build-args: |
|
||||
PAPERCLIP_BUILD_VERSION=${{ steps.build-version.outputs.version }}
|
||||
PAPERCLIP_BUILD_COMMIT=${{ github.sha }}
|
||||
PAPERCLIP_BUILD_COMMIT=${{ steps.resolve-ref.outputs.sha }}
|
||||
CLI_TOOLS_CACHE_EPOCH=${{ steps.tools-epoch.outputs.epoch }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@@ -183,10 +219,29 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
# push/tag builds resolve to github.sha — the checkout default, so
|
||||
# their behaviour is unchanged. A manual run may override it with the
|
||||
# `ref` input to build an unmerged branch, tag, or commit.
|
||||
ref: ${{ inputs.ref || github.sha }}
|
||||
# Full history and tags so `git describe` below can compute the
|
||||
# release version to stamp into the image.
|
||||
fetch-depth: 0
|
||||
|
||||
# Pin every downstream reference to the exact commit that was checked
|
||||
# out. On push/tag builds this equals github.sha; on a manual run it is
|
||||
# the head of the `ref` input, which can differ from github.sha (the ref
|
||||
# the dispatch ran on). The SHA image tag and the commit stamped into the
|
||||
# image are both derived from this, so a manual build always tags the
|
||||
# commit it actually built.
|
||||
- name: Resolve build ref
|
||||
id: resolve-ref
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sha="$(git rev-parse HEAD)"
|
||||
echo "sha=${sha}" >> "$GITHUB_OUTPUT"
|
||||
echo "short_sha=$(git rev-parse --short=7 HEAD)" >> "$GITHUB_OUTPUT"
|
||||
echo "Building ${GITHUB_REF} at ${sha}"
|
||||
|
||||
# `.git` is dockerignored, so a running image cannot derive its own
|
||||
# version and otherwise reports the source package.json placeholder in
|
||||
# analytics and the debug panel. Compute it here from the pristine
|
||||
@@ -301,7 +356,11 @@ jobs:
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=sha
|
||||
# push/tag builds keep the stock sha tag (sha-<short> of github.sha).
|
||||
# A manual run may build a ref other than github.sha, so it tags the
|
||||
# resolved commit instead — same sha-<short> format, correct commit.
|
||||
type=sha,enable=${{ github.event_name != 'workflow_dispatch' }}
|
||||
type=raw,value=sha-${{ steps.resolve-ref.outputs.short_sha }},enable=${{ github.event_name == 'workflow_dispatch' }}
|
||||
labels: |
|
||||
io.github.paperclipai.schema.last-migration=${{ steps.schema.outputs.last }}
|
||||
io.github.paperclipai.schema.migration-count=${{ steps.schema.outputs.count }}
|
||||
@@ -316,7 +375,7 @@ jobs:
|
||||
build-args: |
|
||||
CLOUD_BUNDLED_PLUGINS=daytona
|
||||
PAPERCLIP_BUILD_VERSION=${{ steps.build-version.outputs.version }}
|
||||
PAPERCLIP_BUILD_COMMIT=${{ github.sha }}
|
||||
PAPERCLIP_BUILD_COMMIT=${{ steps.resolve-ref.outputs.sha }}
|
||||
CLI_TOOLS_CACHE_EPOCH=${{ steps.tools-epoch.outputs.epoch }}
|
||||
# amd64 only, unlike the self-hosted image above: the cloud variant
|
||||
# is consumed exclusively by managed-deployment hosts, which run
|
||||
|
||||
Reference in new issue
Block a user