Skip to content

Allow PRs to build images #77

Allow PRs to build images

Allow PRs to build images #77

Workflow file for this run

name: Build firmwares
on:
pull_request:
paths-ignore:
- '.gitignore'
- 'README.md'
push:
paths-ignore:
- '.gitignore'
- 'README.md'
env:
REGISTRY: ghcr.io
jobs:
build-container:
name: Create build container image
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4.1.4
- 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="${{ hashFiles('Dockerfile') }}"
# Default to building a new container under the original repo
image_name=$head_image
build=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=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=false
fi
fi
echo "build=$build" >> $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.create-container-info.outputs.build == 'true'
- name: Build and Push
uses: docker/build-push-action@v5.3.0
if: steps.create-container-info.outputs.build == 'true'
with:
context: .
file: Dockerfile
tags: ${{ steps.create-container-info.outputs.tag_name }}
cache-from: ${{ steps.create-container-info.outputs.image_name }}:cache-${{ steps.create-container-info.outputs.tag_name }}
cache-to: ${{ steps.create-container-info.outputs.image_name }}:cache-${{ steps.create-container-info.outputs.tag_name }}
push: true
outputs:
tag_name: ${{ steps.create-container-info.outputs.tag_name }}
image_name: ${{ steps.create-container-info.outputs.image_name }}
container_name: ${{ steps.create-container-info.outputs.container_name }}
list-manifests:
name: List firmware manifests
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4.1.4
- id: set-matrix
run: |
echo "matrix=$(find manifests -type f \( -name "*.yaml" -o -name "*.yml" \) -print | sort | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT
build-firmwares:
name: Firmware builder
needs: [list-manifests, build-container]
runs-on: ubuntu-latest
container:
image: ${{ needs.build-container.outputs.container_name }}
options: --user root
strategy:
matrix:
manifest: ${{ fromJson(needs.list-manifests.outputs.matrix) }}
steps:
- uses: actions/checkout@v4.1.4
- name: Parse firmware manifest
id: read_manifest_yaml
run: |
yq -r '
to_entries
| .[]
| select(.value | type == "string")
| .key + "=" + .value
' "${{ matrix.manifest }}" >> $GITHUB_OUTPUT
manifest_filename=$(basename "${{ matrix.manifest }}")
manifest_base="${manifest_filename%%.*}"
echo "manifest_base=$manifest_base" >> $GITHUB_OUTPUT
- name: Install SDK extensions
run: |
# XXX: slc-cli does not actually work when the extensions aren't in the SDK!
for sdk in /gecko_sdk_*; do
slc signature trust --sdk "$sdk"
ln -s $PWD/gecko_sdk_extensions "$sdk"/extension
for ext in "$sdk"/extension/*/; do
slc signature trust --sdk "$sdk" --extension-path "$ext"
done
done
- name: Build firmware
run: |
# Fix `fatal: detected dubious ownership in repository at`
git config --global --add safe.directory "$GITHUB_WORKSPACE"
# Pass all SDKs as consecutive `--sdk ...` arguments
sdk_args=""
for sdk_dir in /gecko_sdk*; do
sdk_args="$sdk_args --sdk $sdk_dir"
done
# Pass all toolchains as consecutive `--toolchain ...` arguments
toolchain_args=""
for toolchain_dir in /opt/*arm-none-eabi*; do
toolchain_args="$toolchain_args --toolchain $toolchain_dir"
done
# Build it
mkdir outputs
filename="${{ steps.read_manifest_yaml.outputs['manifest_base'] }}"
python3 tools/build_project.py \
$sdk_args \
$toolchain_args \
--manifest "${{ matrix.manifest }}" \
--build-dir build \
--build-system makefile \
--output "gbl:outputs/$filename.gbl" \
--output "hex:outputs/$filename.hex" \
--output "out:outputs/$filename.out"
- name: Install node within container (act)
if: ${{ env.ACT }}
run: |
curl -fsSL https://deb.nodesource.com/nsolid_setup_deb.sh | bash -s 20
apt-get install -y nodejs
- name: Upload artifact
uses: actions/upload-artifact@v4.3.3
with:
name: ${{ steps.read_manifest_yaml.outputs['manifest_base'] }}
path: outputs/*
compression-level: 9
if-no-files-found: error