Files
trex-core/.github/workflows/publish-image.yml
T

145 lines
4.4 KiB
YAML

name: Publish verified container image
on:
push:
tags:
- "v*"
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Reject non-version publication events
env:
PUBLICATION_EVENT: ${{ github.event_name }}
PUBLICATION_REF: ${{ github.ref }}
run: |
if [[ "${PUBLICATION_EVENT}" != "push" \
|| ! "${PUBLICATION_REF}" =~ ^refs/tags/v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
echo "publication requires a strict vX.Y.Z tag push" >&2
exit 1
fi
- name: Check out exact source commit
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
fetch-depth: 0
- name: Reverify exact checked out commit
run: python scripts/image_release.py verify-checkout --commit "${GITHUB_SHA}"
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install repository checks
run: |
python -m pip install "uv==0.11.14"
uv sync --extra dev --locked
- name: Run repository lint
run: uv run ruff check .
- name: Run repository tests
run: uv run pytest
- name: Create excluded synthetic canary
run: |
python - <<'PY'
from pathlib import Path
Path(".env.ci-canary").write_text("TREX_SECRET_CANARY_DO_NOT_SHIP\n", encoding="ascii")
PY
- name: Build source image once
run: |
docker build \
--provenance=false \
--build-arg "SOURCE_COMMIT=${GITHUB_SHA}" \
--tag "trex-core-ci:${GITHUB_SHA}" \
.
- name: Smoke built image
run: python scripts/image_release.py smoke --image "trex-core-ci:${GITHUB_SHA}"
- name: Record tested image ID
run: |
python scripts/image_release.py record-image-id \
--image "trex-core-ci:${GITHUB_SHA}" \
--output trex-core-image.id
- name: Export tested image
run: docker save --output trex-core-image.tar "trex-core-ci:${GITHUB_SHA}"
- name: Scan all canary surfaces
run: |
set +e
python scripts/image_release.py scan \
--image "trex-core-ci:${GITHUB_SHA}" \
--archive trex-core-image.tar \
>canary-scan.stdout 2>canary-scan.stderr
scan_status=$?
set -e
python scripts/image_release.py assert-clean-output \
canary-scan.stdout canary-scan.stderr
exit "${scan_status}"
- name: Record tested archive checksum
run: |
python scripts/image_release.py checksum \
--archive trex-core-image.tar \
--output trex-core-image.tar.sha256
- name: Upload immutable tested image artifact
uses: actions/upload-artifact@v4
with:
name: tested-image-${{ github.run_id }}-${{ github.run_attempt }}
if-no-files-found: error
overwrite: false
retention-days: 7
path: |
trex-core-image.tar
trex-core-image.tar.sha256
trex-core-image.id
scripts/image_release.py
publish:
needs: verify
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image: ${{ steps.publish.outputs.image }}
digest: ${{ steps.publish.outputs.digest }}
source_commit: ${{ steps.publish.outputs.source_commit }}
version_tag: ${{ steps.publish.outputs.version_tag }}
steps:
- name: Download tested image artifact
uses: actions/download-artifact@v4
with:
name: tested-image-${{ github.run_id }}-${{ github.run_attempt }}
path: tested-image
- name: Verify, load, and publish without rebuilding
id: publish
env:
GITHUB_ACTOR: ${{ github.actor }}
REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python tested-image/scripts/image_release.py publish \
--archive tested-image/trex-core-image.tar \
--checksum tested-image/trex-core-image.tar.sha256 \
--image-id tested-image/trex-core-image.id \
--local-image "trex-core-ci:${GITHUB_SHA}" \
--commit "${GITHUB_SHA}" \
--event-name "${GITHUB_EVENT_NAME}" \
--ref "${GITHUB_REF}"