diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 140a38f..fb58d06 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -2,6 +2,12 @@ name: Build containers on: workflow_dispatch: + inputs: + image: + description: Image to build + type: choice + options: [all, fedora-cosmic, fedora-remote, fedora-intune] + default: all pull_request: branches: ["main"] push: @@ -15,11 +21,17 @@ jobs: changes: name: Compute changes runs-on: job-v2 + # The runner has no git: without it actions/checkout falls back to a + # tarball with no history, `git diff` fails and every image is rebuilt. + container: + image: "quay.io/fedora-ostree-desktops/buildroot:44" outputs: cosmic: ${{ steps.changes.outputs.cosmic }} remote: ${{ steps.changes.outputs.remote }} intune: ${{ steps.changes.outputs.intune }} steps: + - name: Install tools + run: dnf install -y nodejs git - name: Checkout uses: actions/checkout@v4 with: @@ -27,17 +39,53 @@ jobs: - name: Detect changed images id: changes shell: bash + env: + EVENT: ${{ github.event_name }} + BEFORE: ${{ github.event.before }} + SHA: ${{ github.sha }} + BASE_REF: ${{ github.base_ref }} + DISPATCH_IMAGE: ${{ inputs.image }} run: | set -euo pipefail - if [[ "${{ github.event_name }}" == "push" \ - && -n "${{ github.event.before }}" \ - && "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]]; then - changed="$(git diff --name-only "${{ github.event.before }}" "${{ github.sha }}" || true)" - elif [[ "${{ github.event_name }}" == "pull_request" ]]; then - changed="$(git diff --name-only "origin/${{ github.base_ref }}...HEAD" || true)" - else - changed="" - fi + # Diff the event's commits; any failure rebuilds everything, but + # say so instead of hiding it. + diff_or_all() { + if ! changed="$(git diff --name-only "$@")"; then + echo "::warning::git diff $* failed; rebuilding every image" + changed="" + elif [[ -z "${changed}" ]]; then + # Nothing changed (e.g. an empty merge): build nothing rather + # than everything. + changed="(none)" + fi + } + case "${EVENT}" in + push) + if [[ -n "${BEFORE}" && "${BEFORE}" != 0000000000000000000000000000000000000000 ]]; then + diff_or_all "${BEFORE}" "${SHA}" + else + echo "::warning::push without a previous commit; rebuilding every image" + changed="" + fi + ;; + pull_request) + diff_or_all "origin/${BASE_REF}...HEAD" + ;; + workflow_dispatch) + # Pretend the chosen image's directory changed; "all" (or no + # input) rebuilds everything. + if [[ -n "${DISPATCH_IMAGE}" && "${DISPATCH_IMAGE}" != all ]]; then + changed="images/${DISPATCH_IMAGE}/" + else + changed="" + fi + ;; + *) + # schedule: the weekly rebuild picks up package updates for all. + changed="" + ;; + esac + printf 'Changed paths:\n%s\n' "${changed:-(all)}" eval "$(printf '%s\n' "${changed}" | ./ci-changes.sh)" echo "cosmic=${cosmic}" >> "$GITHUB_OUTPUT" echo "remote=${remote}" >> "$GITHUB_OUTPUT"