name: Publish Packwiz site on: push: branches: - main tags: - "forever-v*" # A branch push and release tag can happen close together. Serializing them # prevents two jobs from racing to update the GitOps deployment manifest. concurrency: group: mcpacks-publish cancel-in-progress: false env: REGISTRY: tea.ahmza.com IMAGE_NAME: ahmza.com/mcpacks-site jobs: publish: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Check out all pack history uses: actions/checkout@v4 with: fetch-depth: 0 - name: Fetch current main and release tags # A tag-triggered checkout points HEAD at that tag. Fetching main # explicitly ensures /dev still contains today's development branch. run: git fetch origin main:refs/remotes/origin/main --tags --force - name: Set up Go for Packwiz uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Install pinned Packwiz # Packwiz has no stable binary release channel. Pinning the source # revision makes image builds reproducible instead of following latest. run: go install github.com/packwiz/packwiz@dfd8b68a4796c763e25bad50265ea1f1233e24f1 - name: Assemble static Packwiz site env: EVENT_REF: ${{ gitea.ref }} EVENT_SHA: ${{ gitea.sha }} run: | chmod +x scripts/build-site.sh # A branch job must publish exactly the commit that triggered it, # even if a newer main commit arrives while this job is queued. A # tag job uses current main for /dev while exporting the tag itself # to /releases in scripts/build-site.sh. case "$EVENT_REF" in refs/tags/*) dev_ref=origin/main ;; *) dev_ref=$EVENT_SHA ;; esac PACKWIZ_BIN="$(go env GOPATH)/bin/packwiz" \ ./scripts/build-site.sh "$dev_ref" test -s .build/site/forever/dev/pack.toml grep -q '^hash = "[0-9a-f]\{64\}"$' \ .build/site/forever/dev/pack.toml # Building distribution metadata must not alter tracked source packs. git diff --exit-code -- forever - name: Verify tagged release output if: startsWith(gitea.ref, 'refs/tags/') env: RELEASE_TAG: ${{ gitea.ref_name }} run: | version=${RELEASE_TAG#forever-} test -s ".build/site/forever/releases/$version/pack.toml" test -s .build/site/forever/stable/pack.toml - name: Log in to Gitea Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ci-bot password: ${{ secrets.REGISTRY_TOKEN }} # The SWS runtime image already publishes amd64 and arm64 variants and # this Dockerfile has no target-architecture RUN commands, so Buildx can # create both variants without slow QEMU emulation. - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push immutable site image id: build uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 push: true build-args: | VCS_REF=${{ gitea.sha }} # latest bootstraps the first deployment and is convenient for # inspection. Kubernetes runs the immutable manifest digest emitted # by this step, never this mutable tag. tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max - name: Check out cluster GitOps repository uses: actions/checkout@v4 with: repository: ahmza.com/k8s-starter-pack ref: main token: ${{ secrets.GITOPS_TOKEN }} path: _gitops - name: Record the deployed image in Git env: # A digest identifies the actual multi-architecture image contents. # This changes for a release build even when its tag points at the # same Git commit previously built by the main-branch workflow. IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }} run: | python3 - "$IMAGE" <<'PY' from pathlib import Path import sys manifest = Path("_gitops/apps/mcpacks/deployment.yaml") image = sys.argv[1] prefix = " image: " repository = "tea.ahmza.com/ahmza.com/mcpacks-site" lines = manifest.read_text().splitlines() matches = [ i for i, line in enumerate(lines) if line.startswith(prefix + repository) ] if len(matches) != 1: raise SystemExit(f"expected one mcpacks image line, found {len(matches)}") lines[matches[0]] = f"{prefix}{image}" manifest.write_text("\n".join(lines) + "\n") PY cd _gitops if git diff --quiet -- apps/mcpacks/deployment.yaml; then echo "GitOps manifest already references $IMAGE" exit 0 fi git config user.name "gitea-actions[bot]" git config user.email "gitea-actions[bot]@tea.ahmza.com" git add apps/mcpacks/deployment.yaml git commit -m "Deploy mcpacks ${GITEA_SHA}" git push origin HEAD:main