Skip to content

Retag stable lcm-bricks latest → M<major>-bom1 #26

Retag stable lcm-bricks latest → M<major>-bom1

Retag stable lcm-bricks latest → M<major>-bom1 #26

name: "LCM: Retag stable image to major version"
run-name: "Retag stable lcm-bricks ${{ inputs.tag }} → M<major>-${{ inputs.cluster }}"
on:
workflow_dispatch:
inputs:
tag:
description: 'Stable image tag to retag (e.g. 3.7.106), or "latest" to resolve the newest promoted version'
required: true
default: 'latest'
type: string
cluster:
description: 'Target cluster to retag image to it'
required: true
type: choice
options:
- "na1"
- "ca2"
- "perf1"
- "bom1"
- "syd1"
- "na3"
- "eu1"
- "fra1"
- "all-clusters"
dry-run:
description: 'Dry-run only — print crane commands without executing'
required: true
default: true
type: boolean
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
retag-stable:
name: Retag stable/${{ inputs.tag }} to major version
runs-on:
group: infra1-runners-arc
labels: runners-small
permissions:
id-token: write
contents: read
env:
INFRA_REPO_URL: ${{ secrets.ECR_URL }}
images: "lcm-bricks lcm-bricks-nextversion"
clusters: "na1 ca2 perf1 bom1 syd1 na3 eu1 fra1"
steps:
- name: Get required Vault secrets
uses: hashicorp/vault-action@v3
with:
url: ${{ secrets.VAULT_ADDRESS }}
method: jwt
path: jwt/github
role: ecr-push
secrets: |
secret/data/v3/int/ecr/infra1-user-ecr-rw aws_ecr_access_key | AWS_ACCESS_KEY ;
secret/data/v3/int/ecr/infra1-user-ecr-rw aws_ecr_secret_key | AWS_SECRET_KEY ;
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ env.AWS_SECRET_KEY }}
aws-region: us-east-1
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: 'true'
- name: Retag images
id: retag
env:
TAG: ${{ inputs.tag }}
DRY_RUN: ${{ inputs.dry-run }}
CLUSTER: ${{ inputs.cluster }}
run: |
set -euo pipefail
images=( ${{ env.images }} )
clusters=( ${{ env.clusters }} )
target_cluster="${CLUSTER}"
if [[ "${target_cluster}" != "all-clusters" && " ${clusters[*]} " != *" ${target_cluster} "* ]]; then
echo "::error::Unknown cluster '${target_cluster}'. Configured clusters: ${clusters[*]}"
exit 1
fi
# the image carries its own version (LABEL bricks_version, fed by BRICKS_VERSION
# at build time), so 'latest' resolves without parsing mutable tag names
resolve_version() {
local ref=$1 version
version=$(crane config "${ref}" | jq -r '.config.Labels.bricks_version // empty')
if [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
# stderr: this runs inside $(...), stdout is reserved for the version
echo "::error::cannot resolve a version from ${ref} (bricks_version label = '${version:-<missing>}')" >&2
return 1
fi
printf '%s' "${version}"
}
crane_tag() {
local src=$1 tag=$2
if [ "${DRY_RUN}" == 'true' ]; then
echo "[dry-run] crane tag ${src} ${tag}"
else
crane tag "${src}" "${tag}"
echo "Tagged ${src} → ${tag}"
fi
}
resolved_summary=""
for image in "${images[@]}"; do
version="${TAG}"
# retag from the concrete version tag: traceable, and immune to latest
# moving underneath the run. Only checked when resolving latest — an
# explicit older tag (rollback) is expected to differ from latest.
if [[ "${TAG}" == 'latest' ]]; then
version=$(resolve_version "${INFRA_REPO_URL}/stable/${image}:latest")
echo "Resolved stable/${image}:latest → ${version}"
if [[ "$(crane digest "${INFRA_REPO_URL}/stable/${image}:${version}")" \
!= "$(crane digest "${INFRA_REPO_URL}/stable/${image}:latest")" ]]; then
echo "::error::stable/${image}:latest and :${version} are different digests — refusing to retag"
exit 1
fi
fi
major="${version%%.*}"
src="${INFRA_REPO_URL}/stable/${image}:${version}"
if [[ "${target_cluster}" == "all-clusters" ]]; then
for cluster in "${clusters[@]}"; do
crane_tag "${src}" "M${major}-${cluster}"
done
else
crane_tag "${src}" "M${major}-${target_cluster}"
fi
resolved_summary+="${image}=${version} "
done
echo "resolved_summary=${resolved_summary% }" >> "$GITHUB_OUTPUT"
- name: Summary
env:
TAG: ${{ inputs.tag }}
CLUSTER: ${{ inputs.cluster }}
RESOLVED: ${{ steps.retag.outputs.resolved_summary }}
run: |
set -euo pipefail
clusters=( ${{ env.clusters }} )
if [[ "${CLUSTER}" == 'all-clusters' ]]; then
targets="${clusters[*]}"
else
targets="${CLUSTER}"
fi
{
echo "## LCM stable retag"
echo ""
echo "| | |"
echo "|---|---|"
echo "| **Requested tag** | \`${TAG}\` |"
echo "| **Resolved version(s)** | \`${RESOLVED}\` |"
echo "| **Major tag pattern** | \`M<major>-<cluster>\` |"
echo "| **Retagged cluster(s)** | \`${targets}\` |"
echo "| **Dry-run** | \`${{ inputs.dry-run }}\` |"
} >> "$GITHUB_STEP_SUMMARY"