fix: Use unique locks for each podman invocation #2347
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: Container IC Build Image | |
| on: | |
| pull_request: | |
| paths: | |
| - '.github/workflows/container-autobuild.yml' | |
| - 'rust-toolchain.toml' | |
| - 'ci/container/**' | |
| push: | |
| branches: | |
| - 'dev-gh-*' | |
| paths: | |
| - '.github/workflows/container-autobuild.yml' | |
| - 'rust-toolchain.toml' | |
| - 'ci/container/**' | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: write | |
| packages: write | |
| pull-requests: write | |
| jobs: | |
| build-image-prep: | |
| name: Build Image Prep | |
| runs-on: ubuntu-latest | |
| outputs: | |
| build_image: ${{ steps.set-output.outputs.build_image }} | |
| image_tag: ${{ steps.set-output.outputs.image_tag }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Set Build Output | |
| shell: bash | |
| id: set-output | |
| run: | | |
| # Check if we've previously already built ic-build image | |
| set -eExuo pipefail | |
| image_tag="$(ci/container/get-image-tag.sh)" | |
| if grep $image_tag ci/container/TAG; then | |
| echo "build_image=false" >> "$GITHUB_OUTPUT" | |
| echo "Update with this image already in this PR!" | |
| echo "Modify ci/container/TAG with random string to trigger new build." | |
| else | |
| echo "build_image=true" >> "$GITHUB_OUTPUT" | |
| echo "image_tag=$image_tag" >> "$GITHUB_OUTPUT" | |
| fi | |
| ic-build-image: | |
| name: Build Container Image ${{ matrix.image }} | |
| runs-on: ubuntu-latest | |
| needs: [build-image-prep] | |
| if: ${{ needs.build-image-prep.outputs.build_image == 'true' }} | |
| timeout-minutes: 60 | |
| strategy: | |
| matrix: | |
| include: | |
| - image: ic-build | |
| target: build | |
| - image: ic-dev | |
| target: dev | |
| outputs: | |
| ic-build-imagedigest: ${{ steps.set-output-imagedigest.outputs.ic-build-imagedigest }} | |
| ic-dev-imagedigest: ${{ steps.set-output-imagedigest.outputs.ic-dev-imagedigest }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@a530e948adbeb357dbca95a7f8845d385edf4438 # v3 | |
| - name: Login to GHCR | |
| uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build Container Image ${{ matrix.image }} | |
| # this sets the output 'digest' to the sha256 of the output image | |
| uses: docker/build-push-action@eb539f44b153603ccbfbd98e2ab9d4d0dcaf23a4 # v5 | |
| id: build | |
| with: | |
| context: . | |
| file: ci/container/Dockerfile | |
| push: true | |
| tags: ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}:${{ needs.build-image-prep.outputs.image_tag }} | |
| target: ${{ matrix.target }} | |
| - name: Set output image digest | |
| id: set-output-imagedigest | |
| run: | | |
| if [ "${{ matrix.image }}" == "ic-build" ]; then | |
| echo "ic-build-imagedigest=${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT | |
| elif [ "${{ matrix.image }}" == "ic-dev" ]; then | |
| echo "ic-dev-imagedigest=${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "Unknown image: ${{ matrix.image }}" | |
| exit 1 | |
| fi | |
| rbe-worker-image: | |
| name: Create Remote Build Execution Worker Image @ Namespace | |
| runs-on: namespace-profile-default;permissions.additional_grant=baseimage:*:* | |
| permissions: {} | |
| needs: [build-image-prep, ic-build-image] | |
| if: | | |
| needs.build-image-prep.outputs.build_image == 'true' && | |
| github.repository == 'dfinity/ic' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| timeout-minutes: 30 | |
| outputs: | |
| worker-image: ${{ steps.worker.outputs.worker-image }} | |
| steps: | |
| - name: Mirror ic-build to nscr.io and optimize it for Remote Build Execution @ Namespace | |
| id: worker | |
| shell: bash | |
| run: | | |
| set -xeuo pipefail | |
| nsc docker login | |
| ic_build_repo="ghcr.io/dfinity/ic-build" | |
| src="${ic_build_repo}@${{ needs.ic-build-image.outputs.ic-build-imagedigest }}" | |
| upload_log="$(mktemp)" | |
| nsc base-image upload "$src" "ic-build:${{ needs.build-image-prep.outputs.image_tag }}" 2>&1 | tee "$upload_log" | |
| worker_digest="$(grep -i 'Uploaded base image' "$upload_log" | grep -oE 'sha256:[0-9a-f]{64}' | tail -n1 || true)" | |
| : "${worker_digest:?could not parse pushed image digest from nsc base-image upload output}" | |
| worker_image="${NSC_CONTAINER_REGISTRY}/ic-build@${worker_digest}" | |
| echo "Resolved worker image: $worker_image" | |
| nsc base-image optimize --image_ref "$worker_image" | |
| echo "worker-image=$worker_image" >> "$GITHUB_OUTPUT" | |
| update-image-references: | |
| name: Update Image References in Repo | |
| runs-on: ubuntu-latest | |
| needs: [build-image-prep, ic-build-image, rbe-worker-image] | |
| if: ${{ needs.build-image-prep.outputs.build_image == 'true' }} | |
| steps: | |
| - name: Create GitHub App Token | |
| uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 | |
| id: app-token | |
| with: | |
| app-id: ${{ vars.PR_CREATION_BOT_APP_ID }} | |
| private-key: ${{ secrets.PR_CREATION_BOT_PRIVATE_KEY }} | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ github.head_ref }} | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Update Image References | |
| shell: bash | |
| run: | | |
| # Update container image references | |
| set -xeuo pipefail | |
| IMAGE_PREFIX="ghcr.io/dfinity/" | |
| IMG_NAME_IC_BUILD="${IMAGE_PREFIX}ic-build@${{ needs.ic-build-image.outputs.ic-build-imagedigest }}" | |
| IMG_NAME_IC_DEV="${IMAGE_PREFIX}ic-dev@${{ needs.ic-build-image.outputs.ic-dev-imagedigest }}" | |
| echo '${{ needs.build-image-prep.outputs.image_tag }}' > ci/container/TAG | |
| pushd .devcontainer | |
| sed -i -E "s|${IMAGE_PREFIX}ic-dev(:\|@)[^\"]{5,}|$IMG_NAME_IC_DEV|g" -- * | |
| popd | |
| pushd .github | |
| sed -i -E "s|${IMAGE_PREFIX}ic-build(:\|@)[^\"]{5,}|$IMG_NAME_IC_BUILD|g" -- workflow*/* | |
| WORKER_IMAGE='${{ needs.rbe-worker-image.outputs.worker-image }}' | |
| sed -i -E "s|nscr\.io/[^\"/]+/ic-build@sha256:[0-9a-f]{64}|${WORKER_IMAGE}|g" -- workflow*/* | |
| popd | |
| git config --global user.name "IDX GitHub Automation" | |
| git config --global user.email "<>" | |
| git add . | |
| git commit \ | |
| -m 'Updating container images to tag: ${{ needs.build-image-prep.outputs.image_tag }}' \ | |
| -m 'ic-build: ${{ needs.ic-build-image.outputs.ic-build-imagedigest }}' \ | |
| -m 'ic-dev: ${{ needs.ic-build-image.outputs.ic-dev-imagedigest }}' | |
| git push | |
| - name: Add PR Comment | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| if: ${{ github.event_name == 'pull_request' }} | |
| with: | |
| script: | | |
| // Hidden marker used to find this workflow's comment on subsequent runs | |
| const marker = '<!-- container-autobuild-image-tag -->'; | |
| let message = marker + '\n' | |
| message += 'Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\n\n' | |
| message += 'New container images with tag: `${{ needs.build-image-prep.outputs.image_tag }}`\n' | |
| message += 'ic-build: `${{ needs.ic-build-image.outputs.ic-build-imagedigest }}`\n' | |
| message += 'ic-dev: `${{ needs.ic-build-image.outputs.ic-dev-imagedigest }}`\n' | |
| // Find existing comment from this workflow | |
| const comments = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number | |
| }); | |
| const botComment = comments.data.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes(marker) | |
| ); | |
| if (botComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: message | |
| }); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: message | |
| }); | |
| } |