Repository navigation
upstream: fix: Prevent 500 on invalid query input for robot accounts (goharbor/harbor#23670) #1099
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: PR Preview Images | |
| on: | |
| pull_request: | |
| branches: [main, "release-[0-9]*.[0-9]*"] | |
| # Allowlist: only build preview images when an input that actually reaches | |
| # one of the images changes. Each entry below is consumed by a dockerfile | |
| # COPY/build-arg or by the task build steps (gen-apis / build:binary). | |
| # Anything not listed (docs, tests, 8gcr-ee patches, lint config, dev | |
| # taskfiles, other workflows) cannot change an image, so it is skipped. | |
| paths: | |
| - "src/**" # Go components + portal sources | |
| - "api/v2.0/swagger.yaml" # gen-apis (core) + portal API client | |
| - "tools/swagger/templates/**" # gen-apis output templates | |
| - "make/migrations/**" # baked into harbor-core | |
| - "icons/**" # baked into harbor-core | |
| - "config/portal/**" # portal nginx.conf | |
| - "LICENSE" # baked into harbor-portal | |
| - "VERSION" # ReleaseVersion ldflag baked into the Go binaries | |
| - "dockerfile/**" # every image | |
| - "versions.env" # build-args + registry/trivy/distribution pins | |
| - "Taskfile.yml" # build orchestration root | |
| - "taskfile/build.yml" # gen-apis + build:binary recipes | |
| - ".github/workflows/pr-ci.yml" # this workflow | |
| - ".github/actions/setup-go-cached/**" # Go build env used by the build jobs | |
| - ".github/actions/setup-task/**" # Task install action used by the build jobs | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: pr-preview-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| REGISTRY_ADDRESS: ${{ vars.REGISTRY_ADDRESS || '8gears.container-registry.com' }} | |
| PR_REGISTRY_PROJECT: ${{ vars.PR_REGISTRY_PROJECT }} | |
| PREVIEW_TAG: pr-${{ github.event.pull_request.number }} | |
| jobs: | |
| build: | |
| name: "${{ matrix.component }} (${{ matrix.platform }})" | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'renovate[bot]' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| component: [core, jobservice, registryctl, exporter, portal, registry, trivy-adapter] | |
| platform: | |
| - linux/amd64 | |
| - linux/arm64 | |
| runs-on: ${{ vars.RUNNER || 'ubuntu-latest' }} | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Prepare | |
| id: prepare | |
| run: | | |
| platform=${{ matrix.platform }} | |
| echo "PLATFORM_PAIR=${platform//\//-}" >> "$GITHUB_ENV" | |
| if [ "${{ matrix.component }}" = "trivy-adapter" ]; then | |
| echo "image_name=trivy-adapter" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "image_name=harbor-${{ matrix.component }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| # Surface pod env var for GitHub Actions expressions | |
| if [ -n "$BUILDX_HOST" ]; then | |
| echo "BUILDX_HOST=$BUILDX_HOST" >> "$GITHUB_ENV" | |
| fi | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Load versions | |
| run: grep -E '^[A-Z_]+=' versions.env >> "$GITHUB_ENV" | |
| - name: Setup Go | |
| uses: ./.github/actions/setup-go-cached | |
| with: | |
| go-version-file: src/go.mod | |
| go-sum-path: src/go.sum | |
| - name: Install Task | |
| uses: ./.github/actions/setup-task | |
| with: | |
| version: 3.49.1 | |
| - name: Generate API code | |
| if: ${{ contains(fromJSON('["core","jobservice","registryctl","exporter","registry","trivy-adapter"]'), matrix.component) }} | |
| run: task build:gen-apis | |
| - name: Compile Go binary | |
| if: ${{ contains(fromJSON('["core","jobservice","registryctl","exporter","registry","trivy-adapter"]'), matrix.component) }} | |
| env: | |
| COMPONENT: ${{ matrix.component }} | |
| PLATFORM_PAIR: ${{ env.PLATFORM_PAIR }} | |
| run: task build:binary:${COMPONENT}:${PLATFORM_PAIR} GIT_COMMIT="${GITHUB_SHA:0:8}" | |
| - name: Compile image helper binaries | |
| env: | |
| COMPONENT: ${{ matrix.component }} | |
| PLATFORM_PAIR: ${{ env.PLATFORM_PAIR }} | |
| run: | | |
| task build:binary:lprobe:${PLATFORM_PAIR} | |
| if [ "${COMPONENT}" = "trivy-adapter" ]; then | |
| task build:binary:trivy:${PLATFORM_PAIR} | |
| fi | |
| - uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0 | |
| if: env.BUILDX_HOST == '' | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| with: | |
| driver: ${{ env.BUILDX_HOST && 'remote' || '' }} | |
| endpoint: ${{ env.BUILDX_HOST }} | |
| - name: Log in to registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 | |
| with: | |
| registry: ${{ env.REGISTRY_ADDRESS }} | |
| username: ${{ vars.PR_REGISTRY_USERNAME }} | |
| password: ${{ secrets.PR_REGISTRY_PASSWORD }} | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| file: dockerfile/${{ matrix.component }}.dockerfile | |
| platforms: ${{ matrix.platform }} | |
| build-args: | | |
| ALPINE_VERSION=${{ env.ALPINE_VERSION }} | |
| NGINX_VERSION=${{ env.NGINX_VERSION }} | |
| BUN_VERSION=${{ env.BUN_VERSION }} | |
| GO_VERSION=${{ env.GO_VERSION }} | |
| DISTRIBUTION_VERSION=${{ env.DISTRIBUTION_VERSION }} | |
| LPROBE_VERSION=${{ env.LPROBE_VERSION }} | |
| TRIVY_BASE_IMAGE_VERSION=${{ env.TRIVY_BASE_IMAGE_VERSION }} | |
| HARBOR_SCANNER_TRIVY_VERSION=${{ env.HARBOR_SCANNER_TRIVY_VERSION }} | |
| tags: ${{ env.REGISTRY_ADDRESS }}/${{ env.PR_REGISTRY_PROJECT }}/${{ steps.prepare.outputs.image_name }} | |
| outputs: type=image,push-by-digest=true,name-canonical=true,push=true | |
| - name: Export digest | |
| run: | | |
| mkdir -p "${{ runner.temp }}/digests" | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "${{ runner.temp }}/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: preview-digest-${{ matrix.component }}-${{ env.PLATFORM_PAIR }} | |
| path: ${{ runner.temp }}/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| merge: | |
| name: "Merge ${{ matrix.component }}" | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'renovate[bot]' }} | |
| needs: [build] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| component: [core, jobservice, registryctl, exporter, portal, registry, trivy-adapter] | |
| runs-on: ${{ vars.RUNNER || 'ubuntu-latest' }} | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Prepare BuildKit | |
| id: prepare | |
| run: | | |
| if [ "${{ matrix.component }}" = "trivy-adapter" ]; then | |
| echo "image_name=trivy-adapter" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "image_name=harbor-${{ matrix.component }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [ -n "$BUILDX_HOST" ]; then | |
| echo "BUILDX_HOST=$BUILDX_HOST" >> "$GITHUB_ENV" | |
| fi | |
| - name: Download digests | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: ${{ runner.temp }}/digests | |
| pattern: preview-digest-${{ matrix.component }}-* | |
| merge-multiple: true | |
| - name: Log in to registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 | |
| with: | |
| registry: ${{ env.REGISTRY_ADDRESS }} | |
| username: ${{ vars.PR_REGISTRY_USERNAME }} | |
| password: ${{ secrets.PR_REGISTRY_PASSWORD }} | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| with: | |
| driver: ${{ env.BUILDX_HOST && 'remote' || '' }} | |
| endpoint: ${{ env.BUILDX_HOST }} | |
| - name: Create manifest list and push | |
| working-directory: ${{ runner.temp }}/digests | |
| env: | |
| IMAGE: ${{ env.REGISTRY_ADDRESS }}/${{ env.PR_REGISTRY_PROJECT }}/${{ steps.prepare.outputs.image_name }} | |
| run: | | |
| # shellcheck disable=SC2046 | |
| docker buildx imagetools create \ | |
| -t "${IMAGE}:${PREVIEW_TAG}" \ | |
| $(printf "${IMAGE}@sha256:%s " *) | |
| sign: | |
| name: Sign preview images | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'renovate[bot]' }} | |
| needs: [merge] | |
| runs-on: ${{ vars.RUNNER || 'ubuntu-latest' }} | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Setup Go | |
| uses: ./.github/actions/setup-go-cached | |
| with: | |
| go-version-file: src/go.mod | |
| go-sum-path: src/go.sum | |
| - name: Install crane | |
| run: go install github.com/google/go-containerregistry/cmd/crane@v0.20.3 | |
| - name: Install envsubst | |
| run: command -v envsubst || (sudo apt-get update && sudo apt-get install -y gettext-base) | |
| - name: Install cosign | |
| uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 | |
| - name: Install syft | |
| uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| - name: Log in to registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 | |
| with: | |
| registry: ${{ env.REGISTRY_ADDRESS }} | |
| username: ${{ vars.PR_REGISTRY_USERNAME }} | |
| password: ${{ secrets.PR_REGISTRY_PASSWORD }} | |
| - name: Sign images, generate SBOMs, and attest | |
| run: | | |
| for image in core jobservice registryctl exporter portal registry trivy-adapter; do | |
| image_name="harbor-${image}" | |
| if [ "${image}" = "trivy-adapter" ]; then | |
| image_name="trivy-adapter" | |
| fi | |
| ref="${REGISTRY_ADDRESS}/${PR_REGISTRY_PROJECT}/${image_name}:${PREVIEW_TAG}" | |
| digest="$(crane digest "${ref}")" | |
| image_ref="${REGISTRY_ADDRESS}/${PR_REGISTRY_PROJECT}/${image_name}@${digest}" | |
| cosign sign --yes "${image_ref}" | |
| syft "${image_ref}" -o spdx-json > "sbom-${image}.spdx.json" | |
| cosign attest --yes --predicate "sbom-${image}.spdx.json" --type spdxjson "${image_ref}" | |
| done | |
| pr-comment: | |
| name: Comment preview image refs | |
| if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'renovate[bot]' }} | |
| needs: [sign] | |
| runs-on: ${{ vars.RUNNER || 'ubuntu-latest' }} | |
| permissions: | |
| issues: write | |
| pull-requests: write | |
| steps: | |
| - name: Install gh CLI | |
| run: | | |
| if ! command -v gh &>/dev/null; then | |
| curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ | |
| | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg | |
| echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ | |
| | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null | |
| sudo apt-get update && sudo apt-get install -y gh | |
| fi | |
| - name: Create or update PR comment | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| MARKER: "<!-- harbor-next-pr-preview -->" | |
| with: | |
| script: | | |
| const marker = process.env.MARKER; | |
| const registryAddress = process.env.REGISTRY_ADDRESS; | |
| const registryProject = process.env.PR_REGISTRY_PROJECT; | |
| const previewTag = process.env.PREVIEW_TAG; | |
| const repository = process.env.GITHUB_REPOSITORY; | |
| const issueNumber = context.payload.pull_request.number; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const body = `${marker} | |
| Preview images for this PR are available in \`${registryAddress}/${registryProject}\` with tag \`${previewTag}\`. | |
| - \`${registryAddress}/${registryProject}/harbor-core:${previewTag}\` | |
| - \`${registryAddress}/${registryProject}/harbor-jobservice:${previewTag}\` | |
| - \`${registryAddress}/${registryProject}/harbor-registryctl:${previewTag}\` | |
| - \`${registryAddress}/${registryProject}/harbor-exporter:${previewTag}\` | |
| - \`${registryAddress}/${registryProject}/harbor-portal:${previewTag}\` | |
| - \`${registryAddress}/${registryProject}/harbor-registry:${previewTag}\` | |
| - \`${registryAddress}/${registryProject}/trivy-adapter:${previewTag}\` | |
| Verify a preview image: | |
| \`\`\` | |
| cosign verify \\ | |
| --certificate-identity-regexp="https://github.com/${repository}/.github/workflows/pr-ci.yml@.*" \\ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \\ | |
| ${registryAddress}/${registryProject}/harbor-core:${previewTag} | |
| \`\`\` | |
| Verify SBOM attestation: | |
| \`\`\` | |
| cosign verify-attestation \\ | |
| --certificate-identity-regexp="https://github.com/${repository}/.github/workflows/pr-ci.yml@.*" \\ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \\ | |
| --type spdxjson \\ | |
| ${registryAddress}/${registryProject}/harbor-core:${previewTag} | |
| \`\`\``; | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| per_page: 100, | |
| }); | |
| const existingComment = comments.find(comment => | |
| comment.user?.login === 'github-actions[bot]' && | |
| comment.body?.startsWith(marker) | |
| ); | |
| if (existingComment) { | |
| await github.rest.issues.updateComment({ | |
| owner, | |
| repo, | |
| comment_id: existingComment.id, | |
| body, | |
| }); | |
| return; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| body, | |
| }); |