From ff6487b4a3241426d80ce68cf8f3a2ef3bfda658 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Fri, 3 May 2024 12:01:30 -0400 Subject: [PATCH] Allow PRs to build images (#54) * Allow PR to build firmware * Add a no-op step * Run CI on any push * Add missing `runs-on` * Fix typo in `get-build-container-names` output * Only push the new container if the GitHub event is itself `push` * Only build the new container if necessary * Move `env` variable to step output * Only ignore a few paths instead of listing all paths to include * Use a Python script to query the GitHub API to determine `base` and `head` * Use correct environment variable name * Revert "Use correct environment variable name" This reverts commit bfc2f70f1a3215318bf9c33e907f4738f6ce23dc. * Revert "Use a Python script to query the GitHub API to determine `base` and `head`" This reverts commit 7bf64ee3238ec7b06e189d2c376d0ce32980b5a9. * Handle `push` and `pull_request` separately * Forgot `tag_name` * Detect the current PR * Remove extraneous parentheses * Ensure CI works for both pull requests and pushes * Fix shell script logic * Use correct step name in `steps.` * Oops, too many replaces * Truncate the tag name to 16 characters * Include the registry name in Docker steps * Revert removal of `actions/checkout` * Download Gecko SDKs as ZIP files * Unzip quietly * Fail if we must build a container in a PR --- .github/workflows/build.yaml | 80 +++++++++++++++++++++++++----------- Dockerfile | 14 ++++--- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 37eaa9a0..1e17b875 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,16 +1,14 @@ name: Build firmwares on: + pull_request: + paths-ignore: + - '.gitignore' + - 'README.md' push: - paths: - - Dockerfile - - .github/workflows/build.yaml - - manifests/**/*.yaml - branches: - - main - tags: - - '*' - + paths-ignore: + - '.gitignore' + - 'README.md' env: REGISTRY: ghcr.io @@ -22,39 +20,73 @@ jobs: packages: write steps: - uses: actions/checkout@v4.1.4 - - name: Create container name - id: create-container-name - run: | - repository_owner=$(echo $GITHUB_REPOSITORY_OWNER | tr [:upper:] [:lower:]) - image_name="${{ env.REGISTRY }}/$repository_owner/silabs-firmware-builder" - tag_name="${{ hashFiles('Dockerfile') }}" - - echo "image_name=$image_name" >> $GITHUB_OUTPUT - echo "tag_name=$tag_name" >> $GITHUB_OUTPUT - echo "container_name=$image_name:$tag_name" >> $GITHUB_OUTPUT - name: Log in to the GitHub container registry uses: docker/login-action@v3.1.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Read repository information + id: read-repo-info + run: | + if [[ $GITHUB_EVENT_NAME == "pull_request" ]]; then + base_image=$(echo ${{ github.event.pull_request.base.repo.full_name }} | awk '{print tolower($0)}') + head_image=$(echo ${{ github.event.pull_request.head.repo.full_name }} | awk '{print tolower($0)}') + else + base_image=$(echo ${{ github.repository }} | awk '{print tolower($0)}') + head_image=$(echo ${{ github.repository }} | awk '{print tolower($0)}') + fi + + tag_name=$(echo "${{ hashFiles('Dockerfile') }}" | cut -c-16) + + # Default to building a new container under the original repo + image_name=$head_image + build_image=true + + # Check if we can use the base image (Nabu Casa) + if docker manifest inspect ${{ env.REGISTRY }}/$base_image:$tag_name; then + image_name=$base_image + build_image=false + fi + + # Check if we can use the head image (if this is a PR) + if [[ $base_image != $head_image ]]; then + if docker manifest inspect ${{ env.REGISTRY }}/$head_image:$tag_name; then + image_name=$head_image + build_image=false + fi + fi + + if [[ $build_image == "true" && $GITHUB_EVENT_NAME == "pull_request" ]]; then + echo "Cannot build a new container within a PR. Please re-run this action after $head_image:$tag_name is built." + exit 1 + fi + + echo "build_image=$build_image" >> $GITHUB_OUTPUT + echo "tag_name=$tag_name" >> $GITHUB_OUTPUT + echo "image_name=$image_name" >> $GITHUB_OUTPUT + echo "container_name=${{ env.REGISTRY }}/$image_name:$tag_name" >> $GITHUB_OUTPUT - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.3.0 + if: steps.read-repo-info.outputs.build_image == 'true' - name: Build and Push uses: docker/build-push-action@v5.3.0 + if: steps.read-repo-info.outputs.build_image == 'true' with: context: . file: Dockerfile - tags: ${{ steps.create-container-name.outputs.container_name }} - cache-from: ${{ steps.create-container-name.outputs.image_name }}:cache-${{ steps.create-container-name.outputs.tag_name }} - cache-to: ${{ steps.create-container-name.outputs.image_name }}:cache-${{ steps.create-container-name.outputs.tag_name }} + tags: ${{ env.REGISTRY }}/${{ steps.read-repo-info.outputs.image_name }}:${{ steps.read-repo-info.outputs.tag_name }} + cache-from: ${{ env.REGISTRY }}/${{ steps.read-repo-info.outputs.image_name }}:cache-${{ steps.read-repo-info.outputs.tag_name }} + cache-to: ${{ env.REGISTRY }}/${{ steps.read-repo-info.outputs.image_name }}:cache-${{ steps.read-repo-info.outputs.tag_name }} push: true outputs: - container_name: ${{ steps.create-container-name.outputs.container_name }} + tag_name: ${{ steps.read-repo-info.outputs.tag_name }} + image_name: ${{ steps.read-repo-info.outputs.image_name }} + container_name: ${{ steps.read-repo-info.outputs.container_name }} + list-manifests: name: List firmware manifests - needs: build-container runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} diff --git a/Dockerfile b/Dockerfile index 6baf7c3b..f26e0a84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN \ # is known to be working with Commander_linux_x86_64_1v15p0b1306.tar.bz). RUN \ curl -O https://www.silabs.com/documents/login/software/SimplicityCommander-Linux.zip \ - && unzip SimplicityCommander-Linux.zip \ + && unzip -q SimplicityCommander-Linux.zip \ && tar -C /opt -xjf SimplicityCommander-Linux/Commander_linux_x86_64_*.tar.bz \ && rm -r SimplicityCommander-Linux \ && rm SimplicityCommander-Linux.zip @@ -34,7 +34,7 @@ ENV PATH="$PATH:/opt/commander" # Install Silicon Labs Configurator (slc) RUN \ curl -O https://www.silabs.com/documents/login/software/slc_cli_linux.zip \ - && unzip -d /opt slc_cli_linux.zip \ + && unzip -q -d /opt slc_cli_linux.zip \ && rm slc_cli_linux.zip ENV PATH="$PATH:/opt/slc_cli" @@ -53,13 +53,15 @@ RUN \ # Gecko SDK 4.4.0 RUN \ - git clone --depth 1 -b v4.4.0 https://github.com/SiliconLabs/gecko_sdk.git gecko_sdk_4.4.0 \ - && rm -rf gecko_sdk_4.4.0/.git + curl -o gecko_sdk_4.4.0.zip -L https://github.com/SiliconLabs/gecko_sdk/releases/download/v4.4.0/gecko-sdk.zip \ + && unzip -q -d gecko_sdk_4.4.0 gecko_sdk_4.4.0.zip \ + && rm gecko_sdk_4.4.0.zip # Gecko SDK 4.3.1 RUN \ - git clone --depth 1 -b v4.3.1 https://github.com/SiliconLabs/gecko_sdk.git gecko_sdk_4.3.1 \ - && rm -rf gecko_sdk_4.3.1/.git + curl -o gecko_sdk_4.3.1.zip -L https://github.com/SiliconLabs/gecko_sdk/releases/download/v4.3.1/gecko-sdk.zip \ + && unzip -q -d gecko_sdk_4.3.1 gecko_sdk_4.3.1.zip \ + && rm gecko_sdk_4.3.1.zip ARG USERNAME=builder ARG USER_UID=1000