Skip to content

Build PR #372

Build PR #372 #687

Workflow file for this run

name: Build
run-name: >-
Build${{ github.event_name == 'workflow_dispatch'
&& format(
' target {0} from {1}@{2} (os {3}@{4}, smartcard {5})',
github.event.inputs.target || 'pi0',
github.event.inputs['app-repo'] || github.repository,
github.event.inputs['source-ref'],
github.event.inputs['os-repo'] || '3rdIteration/seedsigner-os',
github.event.inputs['os-ref'],
(fromJSON(github.event.inputs.smartcard || 'true') && 'enabled') || 'disabled'
)
|| github.event_name == 'push' && format(' push {0}', github.ref_name)
|| github.event_name == 'pull_request' && format(' PR #{0}', github.event.pull_request.number)
|| ''
}}
on:
pull_request:
push:
branches:
- main
- dev
workflow_dispatch:
inputs:
os-repo:
description: The repository containing the SeedSigner OS sources
required: false
default: 3rdIteration/seedsigner-os
os-ref:
description: The seedsigner-os ref (tag/branch/sha1) to use
default: main
required: true
app-repo:
description: The repository containing the SeedSigner application sources
required: false
default: 3rdIteration/seedsigner
source-ref:
description: The seedsigner ref (tag/branch/sha1) to use
default: dev
required: true
target:
description: Build target profile (pi0, pi2, pi02w, pi4, or "all" for every target)
required: false
default: pi0
smartcard:
description: Enable smartcard support for the build
required: false
default: 'true'
type: boolean
dev:
description: Build dev image
required: false
default: 'false'
type: boolean
debug-rootfs:
description: Build and export the rootfs debug archive
required: false
default: 'false'
type: boolean
upload-release:
description: Upload built .img files to the matching GitHub release (if it exists)
required: false
default: 'false'
type: boolean
# Increment this number as part of a PR to trigger an image build for the PR
# trigger = 0
permissions:
contents: read
# Cancel in-progress builds when a PR is updated; unique per-PR or per-SHA
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
build:
name: >-
build${{ github.event_name == 'workflow_dispatch'
&& format(
' ({0} from {1}@{2}, os {3}@{4}, smartcard {5})',
github.event.inputs.target || 'pi0',
github.event.inputs['app-repo'] || github.repository,
github.event.inputs['source-ref'],
github.event.inputs['os-repo'] || '3rdIteration/seedsigner-os',
github.event.inputs['os-ref'],
(fromJSON(github.event.inputs.smartcard || 'true') && 'enabled') || 'disabled'
)
|| ''
}}
runs-on: ubuntu-latest
env:
DOCKER_DEFAULT_PLATFORM: linux/amd64
strategy:
fail-fast: false
matrix:
# PRs build both pi0 and pi02w; push defaults to pi0;
# workflow_dispatch uses user input ("all" expands to every target)
target: >-
${{
github.event_name == 'pull_request'
&& fromJSON('["pi0", "pi02w"]')
|| github.event_name == 'workflow_dispatch'
&& (github.event.inputs.target == 'all'
&& fromJSON('["pi0", "pi02w", "pi2", "pi4"]')
|| fromJSON(format('["{0}"]', github.event.inputs.target || 'pi0')))
|| fromJSON('["pi0"]')
}}
steps:
- name: checkout seedsigner-os
uses: actions/checkout@v6
with:
repository: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs['os-repo'] || '3rdIteration/seedsigner-os' }}
# use the os-ref input parameter in case of workflow_dispatch or default to main in case of cron triggers
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.os-ref || 'main' }}
submodules: true
path: "seedsigner-os"
# get full history + tags for "git describe"
fetch-depth: 0
- name: Prepare build metadata
run: |
echo "builder_hash=$(git -C seedsigner-os rev-parse --short HEAD)" | tee -a "$GITHUB_ENV"
APP_REPO_INPUT="${{ github.event_name == 'workflow_dispatch' && github.event.inputs['app-repo'] || github.repository }}"
if [[ "${APP_REPO_INPUT}" =~ ^https?:// ]]; then
APP_REPO_URL="${APP_REPO_INPUT}"
else
APP_REPO_URL="https://github.com/${APP_REPO_INPUT}"
fi
APP_REF="${{
github.event_name == 'workflow_dispatch' && github.event.inputs['source-ref']
|| github.event_name == 'pull_request' && github.event.pull_request.head.sha
|| github.sha
}}"
if [[ "${{ github.event_name }}" = "workflow_dispatch" ]] && ! [[ "${APP_REF}" =~ ^[0-9a-fA-F]{7,40}$ ]]; then
APP_REF_ARG="--app-branch=${APP_REF}"
else
APP_REF_ARG="--app-commit-id=${APP_REF}"
fi
SS_ARGS="--${{ matrix.target }} --app-repo=${APP_REPO_URL} ${APP_REF_ARG}"
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.dev }}" = "true" ]; then
SS_ARGS+=" --dev"
fi
if [ "${{ github.event_name }}" != "workflow_dispatch" ] || [ "${{ github.event.inputs.smartcard }}" = "true" ]; then
SS_ARGS+=" --smartcard"
fi
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.debug-rootfs }}" = "true" ]; then
SS_ARGS+=" --debug-rootfs"
fi
echo "SS_ARGS=${SS_ARGS}" | tee -a "$GITHUB_ENV"
- name: free disk space
run: |
echo "Disk usage before cleanup:"
df -h
sudo rm -rf \
/opt/hostedtoolcache/CodeQL \
/usr/local/lib/android/sdk \
/usr/share/dotnet
sudo apt-get clean
docker system prune --all --force || true
echo "Disk usage after cleanup:"
df -h
- name: restore build cache
uses: actions/cache@v5
# Caching reduces the build time to ~50% (currently: ~30 mins instead of ~1 hour,
# while consuming ~850 MB storage space).
with:
path: |
seedsigner-os/.buildroot-ccache
seedsigner-os/.ccache
key: build-cache-${{ matrix.target }}-${{ env.builder_hash }}
restore-keys: |
build-cache-${{ matrix.target }}-
- name: Build image with docker compose
run: |
cd seedsigner-os
mkdir -p .buildroot-ccache .ccache images
docker compose up --force-recreate --build
docker compose down
- name: Fix permissions
run: |
sudo chown -R $USER:$USER seedsigner-os/images seedsigner-os/.buildroot-ccache seedsigner-os/.ccache
- name: list images
run: |
ls -la seedsigner-os/images
- name: print sha256sum
run: |
cd seedsigner-os/images
shopt -s nullglob
zip_files=(*.img.zip)
for zip in "${zip_files[@]}"; do
unzip -o "$zip"
done
if ((${#zip_files[@]})); then
sha256sum "${zip_files[@]}"
fi
img_files=(*.img)
if ((${#img_files[@]})); then
sha256sum "${img_files[@]}"
fi
- name: zip images for upload
run: |
cd seedsigner-os/images
shopt -s nullglob
for img in *.img; do
zip "${img}.zip" "$img"
done
- name: upload images
uses: actions/upload-artifact@v7
with:
name: seedsigner_os_images-${{ matrix.target }}
path: "seedsigner-os/images/*.img.zip"
if-no-files-found: error
# maximum 90 days retention
retention-days: 90
- name: upload rootfs debug archives
uses: actions/upload-artifact@v7
with:
name: seedsigner_os_rootfs-${{ matrix.target }}
path: "seedsigner-os/images/*.tar.gz"
if-no-files-found: warn
# maximum 90 days retention
retention-days: 90
sha256sum:
name: calculate sha256sum
runs-on: ubuntu-latest
needs: build
steps:
- name: download images
uses: actions/download-artifact@v8
with:
path: images
- name: list images
run: |
ls -lRa images
- name: get seedsigner latest commit hash
id: get-seedsigner-hash
run: |
git init
echo "source_hash=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV
- name: write sha256sum
run: |
cd images
# each downloaded image is in its own subfolder
find . -name "*.img.zip" -exec mv {} . \;
shopt -s nullglob
zip_files=(*.img.zip)
for zip in "${zip_files[@]}"; do
unzip -o "$zip"
done
img_files=(*.img)
checksum_files=()
((${#zip_files[@]})) && checksum_files+=("${zip_files[@]}")
((${#img_files[@]})) && checksum_files+=("${img_files[@]}")
if ((${#checksum_files[@]})); then
sha256sum "${checksum_files[@]}" > seedsigner_os.${{ env.source_hash }}.sha256
else
echo "No image files found for checksums" >&2
exit 1
fi
- name: upload checksums
uses: actions/upload-artifact@v7
with:
name: seedsigner_os_images_sha256
path: "images/*.sha256"
if-no-files-found: error
# maximum 90 days retention
retention-days: 90
upload_release:
name: upload images to release
runs-on: ubuntu-latest
needs: [build, sha256sum]
if: github.event_name == 'workflow_dispatch' && github.event.inputs.upload-release == 'true'
permissions:
contents: write
steps:
- name: download build artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
- name: prepare release assets
id: prepare
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.event.inputs['source-ref'] }}
run: |
set -euo pipefail
if ! gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "release_exists=false" >> "$GITHUB_OUTPUT"
echo "has_files=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "release_exists=true" >> "$GITHUB_OUTPUT"
mkdir -p release-assets
find artifacts -name "*.img.zip" -exec cp {} release-assets/ \;
cd release-assets
shopt -s nullglob
zip_files=(*.img.zip)
if ((${#zip_files[@]})); then
for zip in "${zip_files[@]}"; do
unzip -o "$zip"
done
fi
existing_assets=$(gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[].name')
for img in *.img; do
if echo "$existing_assets" | grep -Fxq "$img"; then
rm -f "$img"
fi
done
if ls *.img >/dev/null 2>&1; then
printf '%s\n' *.img > upload_list.txt
echo "has_files=true" >> "$GITHUB_OUTPUT"
else
echo "has_files=false" >> "$GITHUB_OUTPUT"
fi
- name: upload images to release
if: steps.prepare.outputs.release_exists == 'true' && steps.prepare.outputs.has_files == 'true'
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.event.inputs['source-ref'] }}
file: release-assets/*.img*
file_glob: true
overwrite: false
- name: append sha256 to release notes
if: steps.prepare.outputs.release_exists == 'true' && steps.prepare.outputs.has_files == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.event.inputs['source-ref'] }}
run: |
set -euo pipefail
sha_file=$(ls artifacts/seedsigner_os_images_sha256/*.sha256 | head -n 1)
if [[ -z "${sha_file}" ]]; then
exit 0
fi
note_lines=""
while read -r hash filename; do
base_name=$(basename "$filename")
if grep -Fxq "$base_name" release-assets/upload_list.txt; then
note_lines+="- ${base_name}: ${hash}"$'\n'
fi
done < "$sha_file"
if [[ -n "${note_lines}" ]]; then
current_body=$(gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json body --jq '.body')
printf "%s\n\nUploaded images:\n%s" "$current_body" "$note_lines" > release-body.txt
gh release edit "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --notes-file release-body.txt
fi