Skip to content

fix: Use unique locks for each podman invocation #2347

fix: Use unique locks for each podman invocation

fix: Use unique locks for each podman invocation #2347

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
});
}