diff --git a/.gitea/workflows/publish-images.yml b/.gitea/workflows/publish-images.yml index b3cdc75..acdddad 100644 --- a/.gitea/workflows/publish-images.yml +++ b/.gitea/workflows/publish-images.yml @@ -1,26 +1,22 @@ --- -name: publish images +name: publish controller image on: push: branches: [main] paths: - '.gitea/workflows/publish-images.yml' - - 'config/**' - - 'container/**' + - 'container/controller.Dockerfile' - 'cmd/**' - 'internal/**' - - 'scripts/**' - - 'src/**' + - 'scripts/publish-image' - 'go.mod' - 'go.sum' - - 'pyproject.toml' - - 'README.md' workflow_dispatch: jobs: - publish-images: - name: publish-images + publish-controller: + name: publish-controller runs-on: [self-hosted, vm] timeout-minutes: 45 permissions: @@ -28,115 +24,13 @@ jobs: env: PUSH_REGISTRY: zot-push.ad.ddupan.top PULL_REGISTRY: zot.ad.ddupan.top - CONTROLLER_REPOSITORY: panxiao81/gitea-dynamic-runner-controller - RUNNER_REPOSITORY: panxiao81/gitea-dynamic-runner-runner + IMAGE_NAME: controller + IMAGE_REPOSITORY: panxiao81/gitea-dynamic-runner-controller + IMAGE_DOCKERFILE: container/controller.Dockerfile SPIRE_AGENT_SOCKET: /run/spire/agent-sockets/spire-agent.sock steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Test source - shell: bash - run: | - set -euo pipefail - go test ./... - go vet ./... - python3 -m venv /tmp/test-venv - source /tmp/test-venv/bin/activate - python3 -m pip install -e '.[test]' - pytest -q - python3 -m compileall -q src tests - sudo apt-get update - sudo apt-get install --yes --no-install-recommends shellcheck - shellcheck scripts/* - - name: Build and publish shell: bash - run: | - set -euo pipefail - set +x - - # Bootstrap the image that first introduces automatic Docker setup. - # Once deployed, the job-started hook makes this an idempotent no-op. - sudo scripts/setup-job-docker - - : "${GITHUB_SHA:?GITHUB_SHA is required}" - image_tag="sha-${GITHUB_SHA}" - docker_config=$(mktemp -d) - jwt_file=$(mktemp) - cleanup() { - docker buildx rm ci-builder >/dev/null 2>&1 || true - rm -rf -- "$docker_config" "$jwt_file" - } - trap cleanup EXIT - export DOCKER_CONFIG="$docker_config" - - /opt/spire/bin/spire-agent api fetch jwt \ - -audience zot \ - -socketPath "$SPIRE_AGENT_SOCKET" \ - -output json >"$jwt_file" - # shellcheck disable=SC2016 - jq -er '.[0].svids[0].svid' "$jwt_file" | \ - docker login "$PUSH_REGISTRY" --username zot --password-stdin - - docker buildx create \ - --name ci-builder \ - --driver docker-container \ - --use - - publish() { - local repository=$1 - local dockerfile=$2 - local metadata=$3 - docker buildx build \ - --builder ci-builder \ - --platform linux/amd64 \ - --file "$dockerfile" \ - --tag "${PUSH_REGISTRY}/${repository}:${image_tag}" \ - --tag "${PUSH_REGISTRY}/${repository}:main" \ - --provenance=mode=max \ - --sbom=true \ - --metadata-file "$metadata" \ - --push \ - . - } - - publish \ - "$CONTROLLER_REPOSITORY" \ - container/controller.Dockerfile \ - controller-metadata.json - publish \ - "$RUNNER_REPOSITORY" \ - container/runner.Dockerfile \ - runner-metadata.json - - controller_digest=$( - # shellcheck disable=SC2016 - jq -er '."containerimage.digest"' controller-metadata.json - ) - runner_digest=$( - # shellcheck disable=SC2016 - jq -er '."containerimage.digest"' runner-metadata.json - ) - controller_ref="${PULL_REGISTRY}/${CONTROLLER_REPOSITORY}@${controller_digest}" - runner_ref="${PULL_REGISTRY}/${RUNNER_REPOSITORY}@${runner_digest}" - - printf 'controller=%s\nrunner=%s\n' "$controller_ref" "$runner_ref" - if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then - { - printf '## Published images\n\n' - # shellcheck disable=SC2016 - printf -- '- Controller: `%s`\n' "$controller_ref" - # shellcheck disable=SC2016 - printf -- '- Runner: `%s`\n' "$runner_ref" - # shellcheck disable=SC2016 - printf -- '- Source: `%s`\n' "$GITHUB_SHA" - } >>"$GITHUB_STEP_SUMMARY" - fi + run: scripts/publish-image diff --git a/.gitea/workflows/publish-runner-image.yml b/.gitea/workflows/publish-runner-image.yml new file mode 100644 index 0000000..3f0657e --- /dev/null +++ b/.gitea/workflows/publish-runner-image.yml @@ -0,0 +1,26 @@ +--- +name: publish runner image + +on: + workflow_dispatch: + +jobs: + publish-runner: + name: publish-runner + runs-on: [self-hosted, vm] + timeout-minutes: 45 + permissions: + contents: read + env: + PUSH_REGISTRY: zot-push.ad.ddupan.top + PULL_REGISTRY: zot.ad.ddupan.top + IMAGE_NAME: runner + IMAGE_REPOSITORY: panxiao81/gitea-dynamic-runner-runner + IMAGE_DOCKERFILE: container/runner.Dockerfile + SPIRE_AGENT_SOCKET: /run/spire/agent-sockets/spire-agent.sock + steps: + - uses: actions/checkout@v4 + + - name: Build and publish + shell: bash + run: scripts/publish-image diff --git a/scripts/publish-image b/scripts/publish-image new file mode 100755 index 0000000..14082d5 --- /dev/null +++ b/scripts/publish-image @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -euo pipefail +set +x + +: "${GITHUB_SHA:?GITHUB_SHA is required}" +: "${IMAGE_NAME:?IMAGE_NAME is required}" +: "${IMAGE_REPOSITORY:?IMAGE_REPOSITORY is required}" +: "${IMAGE_DOCKERFILE:?IMAGE_DOCKERFILE is required}" +: "${PUSH_REGISTRY:?PUSH_REGISTRY is required}" +: "${PULL_REGISTRY:?PULL_REGISTRY is required}" +: "${SPIRE_AGENT_SOCKET:?SPIRE_AGENT_SOCKET is required}" + +# Bootstrap the image that first introduces automatic Docker setup. Once that +# runner is deployed, the job-started hook makes this an idempotent no-op. +sudo scripts/setup-job-docker + +image_tag="sha-${GITHUB_SHA}" +metadata="${IMAGE_NAME}-metadata.json" +docker_config=$(mktemp -d) +jwt_file=$(mktemp) +cleanup() { + docker buildx rm ci-builder >/dev/null 2>&1 || true + rm -rf -- "$docker_config" "$jwt_file" +} +trap cleanup EXIT +export DOCKER_CONFIG="$docker_config" + +/opt/spire/bin/spire-agent api fetch jwt \ + -audience zot \ + -socketPath "$SPIRE_AGENT_SOCKET" \ + -output json >"$jwt_file" +# shellcheck disable=SC2016 +jq -er '.[0].svids[0].svid' "$jwt_file" | \ + docker login "$PUSH_REGISTRY" --username zot --password-stdin + +docker buildx create \ + --name ci-builder \ + --driver docker-container \ + --use + +docker buildx build \ + --builder ci-builder \ + --platform linux/amd64 \ + --file "$IMAGE_DOCKERFILE" \ + --tag "${PUSH_REGISTRY}/${IMAGE_REPOSITORY}:${image_tag}" \ + --tag "${PUSH_REGISTRY}/${IMAGE_REPOSITORY}:main" \ + --provenance=mode=max \ + --sbom=true \ + --metadata-file "$metadata" \ + --push \ + . + +image_digest=$( + # shellcheck disable=SC2016 + jq -er '."containerimage.digest"' "$metadata" +) +image_ref="${PULL_REGISTRY}/${IMAGE_REPOSITORY}@${image_digest}" + +printf '%s=%s\n' "$IMAGE_NAME" "$image_ref" +if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then + { + printf '## Published image\n\n' + # shellcheck disable=SC2016 + printf -- '- %s: `%s`\n' "$IMAGE_NAME" "$image_ref" + # shellcheck disable=SC2016 + printf -- '- Source: `%s`\n' "$GITHUB_SHA" + } >>"$GITHUB_STEP_SUMMARY" +fi