diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79bad483..44a002fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,11 +17,31 @@ env: IMAGE_NAME: ${{ github.repository }} jobs: + platforms: + runs-on: ubuntu-latest + outputs: + platforms: '${{ steps.platforms.outputs.platforms }}' + steps: + - name: Docker compute platforms + id: platforms + run: | + DEFAULT_PLATFORM=linux/amd64 + echo "default=$DEFAULT_PLATFORM" >> $GITHUB_OUTPUT + if ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}; then + echo 'platforms=["'"$DEFAULT_PLATFORM"'"]' >> $GITHUB_OUTPUT + else + echo 'platforms=["linux/amd64","linux/arm64/v8"]' >> $GITHUB_OUTPUT + fi + # see https://docs.docker.com/build/ci/github-actions/test-before-push/ test-proposals: + needs: [platforms] runs-on: ubuntu-latest # UNTIL https://github.com/Agoric/agoric-3-proposals/issues/2 timeout-minutes: 120 + strategy: + matrix: + platform: ${{ fromJSON(needs.platforms.outputs.platforms) }} steps: - name: free up disk space run: | @@ -37,25 +57,20 @@ jobs: echo "=== After cleanup:" df -h + - name: Set environment + run: | + echo "DEFAULT_PLATFORM=${{ needs.platforms.outputs.default }}" >> $GITHUB_ENV + echo "PLATFORMS=${{ needs.platforms.outputs.platforms }}" >> $GITHUB_ENV + - name: Checkout repository uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Docker multiplatform builds - run: | - DEFAULT_PLATFORM=linux/amd64 - echo "DEFAULT_PLATFORM=$DEFAULT_PLATFORM" >> $GITHUB_ENV - if ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}; then - echo PLATFORMS=$DEFAULT_PLATFORM >> $GITHUB_ENV - else - echo PLATFORMS=linux/amd64,linux/arm64/v8 >> $GITHUB_ENV - fi - - name: Set up QEMU for cross-platform builds uses: docker/setup-qemu-action@v3 - if: ${{ env.PLATFORMS != env.DEFAULT_PLATFORM }} + if: ${{ matrix.platform != env.DEFAULT_PLATFORM }} - name: Log in to the Container registry uses: docker/login-action@v3 @@ -74,12 +89,28 @@ jobs: # The .ts scripts depend upon this - run: npm install --global tsx - - name: build test images + - name: build test images ${{ matrix.platform }} == ${{ env.DEFAULT_PLATFORM }} run: | docker info - ./buildTestImages.ts + ./buildTestImages.ts ${{ matrix.platform == env.DEFAULT_PLATFORM && ' ' || '--dry' }} - name: run test images + if: ${{ matrix.platform == env.DEFAULT_PLATFORM }} run: ./runTestImages.ts + + - name: Compute tags + id: docker-tags + run: | + sep= + SUFFIXED= + uarch=$(echo "${{ matrix.platform }}" | tr / _) + for TAG in ${{ steps.meta.outputs.tags }}; do + SUFFIXED="$SUFFIXED$sep$TAG-$uarch" + if test -z "$sep"; then + sep=, + echo "tag=$TAG-$uarch" >> $GITHUB_OUTPUT + fi + done + echo "tags=$SUFFIXED" >> $GITHUB_OUTPUT # XXX this should be instant for the local platform because all the stages # were already built in the steps above but it's re-building the last @@ -89,9 +120,57 @@ jobs: uses: docker/build-push-action@v5 with: context: . - platforms: ${{ env.PLATFORMS }} + platforms: ${{ matrix.platform }} # push to registry on every repo push. A PR #2 will push with tag `pr-2` and `main` will have tag `main`. # See https://github.com/docker/metadata-action?tab=readme-ov-file#basic. push: true - tags: ${{ steps.meta.outputs.tags }} + tags: ${{ steps.docker-tags.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + + # Publish the build's multiarch images to Docker Registry. + docker-publish-multiarch: + needs: [test-proposals, platforms] + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: --debug + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Login to Docker Registry + uses: docker/login-action@v3 + with: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + registry: ${{ env.REGISTRY }} + - name: Compute tags + id: docker-tags + run: | + echo "tags=${{ steps.meta.outputs.tags }}" >> $GITHUB_OUTPUT + + - name: Push multiarch image + run: | + set -ex + for TAG in ${{ steps.docker-tags.outputs.tags }}; do + sources= + for ARCH in ${{ fromJson(needs.platforms.outputs.platforms) }}; do + uarch=$(echo "$ARCH" | tr / _) + BUILD_TAG="$TAG-$uarch" + sources="$sources $BUILD_TAG" + done + docker buildx imagetools create --tag "$TAG"$sources + done