ci: build under a per-run local tag, untag registry refs only, gate the image push on every test job
This commit is contained in:
1 parent
8ff67f5859
commit
4e108771f8
3 files changed
+67
-21
No files matched your search
+25
-11
@@ -7,7 +7,9 @@ name: ci
|
||||
# test-unit pytest (coverage gate from pyproject.toml: 90 percent)
|
||||
# test-integration pytest against a throwaway Gitea in Docker
|
||||
# test-mcp MCP smoke tests, including against the freshly built image
|
||||
# build-and-push build and scan the image; push it on push events (needs lint + test-unit)
|
||||
# build-and-push build and scan the image; push it on push events (needs lint, test-unit,
|
||||
# test-integration, test-mcp and security, so :dev and :latest are never
|
||||
# pushed while any of them is red)
|
||||
# docs-check docs drift check
|
||||
# security security test suite, pip-audit, ruff bandit rules
|
||||
#
|
||||
@@ -21,7 +23,10 @@ name: ci
|
||||
#
|
||||
# Docker hygiene on the shared runner: every resource this workflow creates has
|
||||
# a per-run name (aegis-ci-<run id>-...) and is removed by an `if: always()`
|
||||
# step that deletes exactly those names. Nothing here ever prunes.
|
||||
# step that deletes exactly those names. Registry tags (:sha-<12>, :dev, :latest, :main)
|
||||
# are shared with other users of the daemon: they are applied only immediately before the
|
||||
# push and only untagged afterwards, never used to remove containers. Nothing here ever
|
||||
# prunes.
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -153,6 +158,8 @@ jobs:
|
||||
env:
|
||||
AEGIS_INTEGRATION: "1"
|
||||
AEGIS_IT_NETWORK_MODE: container
|
||||
# A runner that cannot start must fail the job, not xfail the Actions scenario.
|
||||
AEGIS_IT_REQUIRE_RUNNER: "1"
|
||||
run: uv run pytest tests/integration -m integration --no-cov
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
@@ -204,8 +211,8 @@ jobs:
|
||||
run: bash scripts/ci/cleanup_job_resources.sh "${MCP_IMAGE}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 6. Build the image from the checked-out commit. On push events it is also
|
||||
# pushed:
|
||||
# 6. Build the image from the checked-out commit under a per-run local tag
|
||||
# (aegis-ci-<run id>-build:<sha>). On push events it is also tagged and pushed:
|
||||
# :sha-<12> every branch (immutable, traceable to the commit; lets any
|
||||
# feature branch image be pulled and tested)
|
||||
# :dev additionally on dev
|
||||
@@ -214,7 +221,7 @@ jobs:
|
||||
# outputs and the job summary.
|
||||
# ---------------------------------------------------------------------------
|
||||
build-and-push:
|
||||
needs: [lint, test-unit]
|
||||
needs: [lint, test-unit, test-integration, test-mcp, security]
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
@@ -233,6 +240,8 @@ jobs:
|
||||
run: |
|
||||
IMAGE="git.hiddenden.cafe/${GITHUB_REPOSITORY,,}"
|
||||
SHA_TAG="${IMAGE}:sha-${GITHUB_SHA::12}"
|
||||
# Local build tag: unique per run, never a registry tag.
|
||||
BUILD_TAG="aegis-ci-${GITHUB_RUN_ID}-build:${GITHUB_SHA}"
|
||||
EXTRA_TAGS=""
|
||||
if [ "${GITHUB_EVENT_NAME}" = "push" ]; then
|
||||
if [ "${GITHUB_REF_NAME}" = "main" ]; then
|
||||
@@ -244,6 +253,7 @@ jobs:
|
||||
{
|
||||
echo "image=${IMAGE}"
|
||||
echo "sha_tag=${SHA_TAG}"
|
||||
echo "build_tag=${BUILD_TAG}"
|
||||
echo "extra_tags=${EXTRA_TAGS}"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
@@ -253,11 +263,11 @@ jobs:
|
||||
docker build -f docker/Dockerfile \
|
||||
--label "org.opencontainers.image.revision=${GITHUB_SHA}" \
|
||||
--label "org.opencontainers.image.source=https://git.hiddenden.cafe/${GITHUB_REPOSITORY}" \
|
||||
-t "${{ steps.meta.outputs.sha_tag }}" .
|
||||
-t "${{ steps.meta.outputs.build_tag }}" .
|
||||
|
||||
- name: Smoke-test image
|
||||
shell: bash
|
||||
run: docker run --rm "${{ steps.meta.outputs.sha_tag }}" version
|
||||
run: docker run --rm "${{ steps.meta.outputs.build_tag }}" version
|
||||
|
||||
# Vulnerability scan of the image that is about to be pushed: pinned Trivy
|
||||
# (sha256 verified), fails on fixable HIGH and CRITICAL findings. Waivers live
|
||||
@@ -271,7 +281,7 @@ jobs:
|
||||
|
||||
- name: Scan image
|
||||
shell: bash
|
||||
run: bash scripts/ci/scan_image.sh "${{ steps.meta.outputs.sha_tag }}"
|
||||
run: bash scripts/ci/scan_image.sh "${{ steps.meta.outputs.build_tag }}"
|
||||
|
||||
# No third-party action sees the registry token: the CLI reads it from stdin. The
|
||||
# credentials go to a per-job config directory (DOCKER_CONFIG), never into the shared
|
||||
@@ -290,12 +300,14 @@ jobs:
|
||||
printf '%s' "${REGISTRY_TOKEN}" | DOCKER_CONFIG="${config_dir}" \
|
||||
docker login git.hiddenden.cafe --username "${REGISTRY_USER}" --password-stdin
|
||||
|
||||
# The registry tags are applied here, right before the push, and removed again by the
|
||||
# cleanup step (untag only).
|
||||
- name: Tag and push
|
||||
if: github.event_name == 'push'
|
||||
shell: bash
|
||||
run: |
|
||||
for tag in ${{ steps.meta.outputs.extra_tags }}; do
|
||||
docker tag "${{ steps.meta.outputs.sha_tag }}" "${tag}"
|
||||
for tag in ${{ steps.meta.outputs.sha_tag }} ${{ steps.meta.outputs.extra_tags }}; do
|
||||
docker tag "${{ steps.meta.outputs.build_tag }}" "${tag}"
|
||||
done
|
||||
for tag in ${{ steps.meta.outputs.sha_tag }} ${{ steps.meta.outputs.extra_tags }}; do
|
||||
docker push "${tag}"
|
||||
@@ -331,8 +343,10 @@ jobs:
|
||||
if [ -n "${DOCKER_CONFIG:-}" ]; then
|
||||
rm -rf "${DOCKER_CONFIG}"
|
||||
fi
|
||||
# Registry tags first (untag only), then the per-run build tag.
|
||||
bash scripts/ci/cleanup_job_resources.sh \
|
||||
"${{ steps.meta.outputs.sha_tag }}" ${{ steps.meta.outputs.extra_tags }}
|
||||
"${{ steps.meta.outputs.sha_tag }}" ${{ steps.meta.outputs.extra_tags }} \
|
||||
"${{ steps.meta.outputs.build_tag }}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 7. Docs drift check
|
||||
|
||||
Reference in new issue
Block a user