Skip to content

Allow PRs to build images #74

Allow PRs to build images

Allow PRs to build images #74

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: Create container name
id: create-container-info
shell: python -u {0}
run: |
import os
import json
import pathlib
import subprocess
import urllib.request
GITHUB_OUTPUT = pathlib.Path(os.environ["GITHUB_OUTPUT"])
TAG_NAME = "${{ hashFiles('Dockerfile') }}"
req = urllib.request.Request(
url=f"https://api.github.com/repos/{os.environ['GITHUB_REPOSITORY']}",
headers={
"Authorization": "token ${{ secrets.GITHUB_TOKEN }}",
"Accept": "application/vnd.github.v3+json",
"X-GitHub-Api-Version": "2022-11-28",
}
)
with urllib.request.urlopen(req) as response:
assert response.status == 200
data = json.loads(response.read().decode())
head_image = data["full_name"].lower()
if data["parent"]:
base_image = data["parent"]["full_name"].lower()
else:
base_image = head_image
image_name = head_image
build = True
for image in {base_image, head_image}:
try:
subprocess.run([
"docker", "manifest", "inspect",
f"{os.environ['REGISTRY']}/{image}:{TAG_NAME}"
], check=True)
except subprocess.CalledProcessError:
continue
else:
image_name = image
build = False
break
with GITHUB_OUTPUT.open("a") as f:
f.writelines([
f"build={build}\n",
f"tag_name={TAG_NAME}\n",
f"image_name={image_name}\n",
f"container_name={os.environ['REGISTRY']}/{image_name}:{TAG_NAME}\n",
])
- 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