feat: harden egress quality guard and recovery #431
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: GHCR Image | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "v*.*.*" | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| concurrency: | |
| group: ghcr-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| verify: | |
| name: Verify | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: backend/go.mod | |
| cache-dependency-path: backend/go.sum | |
| - name: Test backend | |
| working-directory: backend | |
| run: go test ./... | |
| - name: Vet backend | |
| working-directory: backend | |
| run: go vet ./... | |
| - name: Verify Swagger document | |
| run: | | |
| make swagger | |
| git diff --exit-code -- backend/docs/docs.go backend/docs/swagger.json backend/docs/swagger.yaml | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 11.5.2 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| cache-dependency-path: frontend/pnpm-lock.yaml | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| run: pnpm install --frozen-lockfile | |
| - name: Lint frontend | |
| working-directory: frontend | |
| run: pnpm lint | |
| - name: Build frontend | |
| working-directory: frontend | |
| run: pnpm build | |
| check_ghcr_image: | |
| name: Build image (${{ matrix.arch }}) | |
| if: github.event_name != 'push' | |
| needs: verify | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| platform: linux/amd64 | |
| runner: ubuntu-24.04 | |
| - arch: arm64 | |
| platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: ${{ matrix.platform }} | |
| push: false | |
| cache-from: type=gha,scope=${{ matrix.arch }} | |
| provenance: false | |
| sbom: false | |
| build_ghcr_image: | |
| name: Publish image (${{ matrix.arch }}) | |
| if: github.event_name == 'push' | |
| needs: verify | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| platform: linux/amd64 | |
| runner: ubuntu-24.04 | |
| - arch: arm64 | |
| platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Normalize image name | |
| id: image | |
| shell: bash | |
| run: | | |
| image_name=$(printf '%s' "$GITHUB_REPOSITORY" | tr '[:upper:]' '[:lower:]') | |
| echo "name=ghcr.io/$image_name" >> "$GITHUB_OUTPUT" | |
| - name: Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ steps.image.outputs.name }} | |
| tags: | | |
| type=ref,event=branch,suffix=-${{ matrix.arch }} | |
| type=ref,event=tag,suffix=-${{ matrix.arch }} | |
| type=raw,value=latest-${{ matrix.arch }},enable=${{ github.ref == 'refs/heads/main' }} | |
| - name: Login to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and publish | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: ${{ matrix.platform }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha,scope=${{ matrix.arch }} | |
| cache-to: type=gha,scope=${{ matrix.arch }},mode=max | |
| provenance: mode=max | |
| sbom: true | |
| merge: | |
| name: Merge image | |
| if: github.event_name == 'push' | |
| needs: | |
| - build_ghcr_image | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Set up Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Normalize image name | |
| id: image | |
| shell: bash | |
| run: | | |
| image_name=$(printf '%s' "$GITHUB_REPOSITORY" | tr '[:upper:]' '[:lower:]') | |
| echo "name=ghcr.io/$image_name" >> "$GITHUB_OUTPUT" | |
| - name: Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ steps.image.outputs.name }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=tag | |
| type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} | |
| - name: Login to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create manifest list | |
| shell: bash | |
| run: | | |
| jq -cr '.tags[]' <<< "$DOCKER_METADATA_OUTPUT_JSON" | while read -r tag; do | |
| docker buildx imagetools create \ | |
| -t "$tag" \ | |
| "${tag}-amd64" \ | |
| "${tag}-arm64" | |
| done | |
| - name: Inspect image | |
| run: docker buildx imagetools inspect "${{ steps.image.outputs.name }}:${{ steps.meta.outputs.version }}" |