diff options
| author | tranch <tranch.xiao@gmail.com> | 2026-07-09 18:21:37 +0800 |
|---|---|---|
| committer | tranch <tranch.xiao@gmail.com> | 2026-07-09 18:21:37 +0800 |
| commit | 39d438730aa65e0e3d5604894d4c41b903e4cae4 (patch) | |
| tree | ed78f8c3489704abb3c0de49f706587ff4efccd9 /.github/workflows/promote-acr.yml | |
| parent | 85d19ac59f67d0f6ee5beaaa8dbc222954ec6434 (diff) | |
| download | AeroCore-OS-39d438730aa65e0e3d5604894d4c41b903e4cae4.tar.gz AeroCore-OS-39d438730aa65e0e3d5604894d4c41b903e4cae4.zip | |
Promote ACR images manually
Remove push-triggered builds and split ACR publishing out of the build workflow.
Add a manual promote-acr workflow that copies an existing GHCR tag to ACR, supports explicit target tags, validates the required ACR configuration, and signs the promoted ACR digest.
Verification: parsed both workflow YAML files and checked embedded run blocks with bash -n.
Diffstat (limited to '.github/workflows/promote-acr.yml')
| -rw-r--r-- | .github/workflows/promote-acr.yml | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/.github/workflows/promote-acr.yml b/.github/workflows/promote-acr.yml new file mode 100644 index 0000000..99a67f8 --- /dev/null +++ b/.github/workflows/promote-acr.yml @@ -0,0 +1,147 @@ +--- +name: Promote image to ACR + +on: + workflow_dispatch: + inputs: + source_tag: + description: "Existing GHCR tag to promote" + required: true + type: string + target_tags: + description: "Space-separated ACR tags to publish; defaults to source_tag" + required: false + type: string + image_name: + description: "Image name override; defaults to image-template.env" + required: false + type: string + +env: + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" + +concurrency: + group: ${{ github.workflow }}-${{ inputs.image_name || 'default' }}-${{ inputs.source_tag }} + cancel-in-progress: false + +jobs: + promote_acr: + name: Promote GHCR image to ACR + runs-on: ubuntu-24.04 + + permissions: + contents: read + packages: read + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 #v4.0.0 + + - name: Install skopeo + run: | + sudo apt-get update + sudo apt-get install -y skopeo + + - name: Prepare image variables + env: + IMAGE_NAME_INPUT: ${{ inputs.image_name }} + SOURCE_TAG: ${{ inputs.source_tag }} + TARGET_TAGS_INPUT: ${{ inputs.target_tags }} + run: | + set -euo pipefail + + image_name="${IMAGE_NAME_INPUT:-$(just image_name)}" + target_tags="${TARGET_TAGS_INPUT:-$SOURCE_TAG}" + + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> "$GITHUB_ENV" + echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" + echo "SOURCE_TAG=${SOURCE_TAG}" >> "$GITHUB_ENV" + echo "TARGET_TAGS=${target_tags}" >> "$GITHUB_ENV" + + - name: Validate ACR configuration + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + ACR_USERNAME: ${{ secrets.ACR_USERNAME }} + ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + run: | + set -euo pipefail + + : "${ACR_REGISTRY:?Repository variable ACR_REGISTRY is required.}" + : "${ACR_NAMESPACE:?Repository variable ACR_NAMESPACE is required.}" + : "${ACR_USERNAME:?Repository secret ACR_USERNAME is required.}" + : "${ACR_PASSWORD:?Repository secret ACR_PASSWORD is required.}" + : "${COSIGN_PRIVATE_KEY:?Repository secret SIGNING_SECRET is required.}" + + - name: Login to GitHub Container Registry + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "$GITHUB_TOKEN" | sudo -E podman login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Login to ACR + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_USERNAME: ${{ secrets.ACR_USERNAME }} + ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} + run: | + set -euo pipefail + echo "$ACR_PASSWORD" | sudo -E podman login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin + echo "$ACR_PASSWORD" | docker login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin + + - name: Promote image + id: promote + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + run: | + set -euo pipefail + + source_image="docker://${IMAGE_REGISTRY}/${IMAGE_NAME}:${SOURCE_TAG}" + first_target="" + + { + echo "# Promote to ACR result" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + for tag in ${TARGET_TAGS}; do + dest_image="${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}:${tag}" + sudo -E skopeo copy "$source_image" "docker://$dest_image" + echo "$dest_image" >> "$GITHUB_STEP_SUMMARY" + if [ -z "$first_target" ]; then + first_target="$dest_image" + fi + done + + echo '```' >> "$GITHUB_STEP_SUMMARY" + + digest=$(sudo -E skopeo inspect --format '{{.Digest}}' "docker://$first_target") + if [ -z "$digest" ]; then + echo "Failed to resolve digest for $first_target" >&2 + exit 1 + fi + + echo "digest=${digest}" >> "$GITHUB_OUTPUT" + + - name: Install Cosign + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 + with: + cosign-release: 'v2.6.3' + + - name: Sign ACR image + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + COSIGN_EXPERIMENTAL: false + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + DIGEST: ${{ steps.promote.outputs.digest }} + run: | + set -euo pipefail + + cosign sign -y --key env://COSIGN_PRIVATE_KEY "${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}@${DIGEST}" |
