Skip to content

Enable file prefix map for Makefiles, for reproducible builds (#68) #19

Enable file prefix map for Makefiles, for reproducible builds (#68)

Enable file prefix map for Makefiles, for reproducible builds (#68) #19

Workflow file for this run

name: Build firmwares
on:
pull_request:
paths-ignore:
- '.gitignore'
- 'README.md'
push:
paths-ignore:
- '.gitignore'
- 'README.md'
release:
types:
- published
env:
REGISTRY: ghcr.io
jobs:
run-pre-commit:
name: Run pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- name: Install pre-commit
run: |
pip install pre-commit
pre-commit install
- name: Run pre-commit
run: |
pre-commit run --show-diff-on-failure --color=always --all-files
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=$(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: ${{ 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:
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
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: 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
id: 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
python3 tools/build_project.py \
$sdk_args \
$toolchain_args \
--manifest "${{ matrix.manifest }}" \
--build-dir build \
--build-system makefile \
--output-dir outputs \
--output gbl \
--output hex \
--output out
# Get the basename of the GBL in `outputs`
output_basename=$(basename -- $(basename -- $(ls -1 outputs/*.gbl | head -n 1)) .gbl)
echo "output_basename=$output_basename" >> $GITHUB_OUTPUT
- 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: firmware-build-${{ steps.build-firmware.outputs.output_basename }}
path: outputs/*
compression-level: 9
if-no-files-found: error
release-assets:
name: Upload release assets
needs: [build-firmwares]
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all workflow artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
pattern: firmware-build-*
- name: Upload artifacts
uses: softprops/action-gh-release@v1
with:
files: artifacts/*.gbl