From 22e1ba33be1a58058334a34f62efc1e1d12e4ec5 Mon Sep 17 00:00:00 2001 From: rob thijssen Date: Thu, 16 Apr 2026 12:30:48 +0300 Subject: [PATCH] feat: initial copr-publish composite action Wraps copr-cli submit/watch/download-build with per-chroot log dumping as collapsible ::group:: blocks. Moves the logic previously living at .gitea/scripts/copr-build.sh in helexa/cortex into a reusable action so every consumer gets live log visibility and consistent failure diagnostics. Inputs: project, srpm (glob OK), copr-config (secret). Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++ action.yml | 44 +++++++++++++++++++++++++++ scripts/copr-build.sh | 63 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 README.md create mode 100644 action.yml create mode 100755 scripts/copr-build.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..5a50e6e --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# copr-publish + +Gitea composite action that submits a source RPM to [Fedora COPR](https://copr.fedorainfracloud.org/), +watches the build, and dumps each chroot's `builder-live.log` into the +CI output as collapsible groups. + +## Why use this + +`copr-cli build` by itself only prints status transitions +(`pending` / `importing` / `running` / `succeeded`). When a build fails +you have to click through to the COPR web UI to see the actual log. +This action: + +- Submits with `--nowait` and captures the build ID. +- Prints a clickable `https://copr.fedorainfracloud.org/coprs/build/...` link so you can follow live. +- Watches the build to completion (blocks, propagates exit status). +- On completion, fetches each chroot's `builder-live.log` via + `copr-cli download-build` and emits them as `::group::` blocks. +- Fails CI if the build fails, but always dumps logs first. + +## Requirements + +The runner must already have: + +- `copr-cli` on `PATH` (provided by the `copr-cli` RPM on Fedora runners). +- `grep -P` (PCRE, default on Fedora). + +## Inputs + +| Input | Required | Description | +| ------------- | -------- | -------------------------------------------------------------------------- | +| `project` | yes | COPR project in the form `/`, e.g. `helexa/cortex`. | +| `srpm` | yes | Path or glob to the source RPM(s) to submit, e.g. `*.src.rpm`. | +| `copr-config` | yes | Contents of `~/.config/copr`. Fetch from and store as a repo or org secret. | + +## Usage + +```yaml +jobs: + publish: + runs-on: fedora + steps: + - uses: actions/download-artifact@v3 + with: + name: my-srpm + + - name: Publish to COPR + uses: https://git.lair.cafe/actions/copr-publish@v1 + with: + project: helexa/cortex + srpm: '*.src.rpm' + copr-config: ${{ secrets.COPR_CONFIG }} +``` + +Note the fully-qualified URL in `uses:` — the Gitea instance's +`DEFAULT_ACTIONS_URL` points at github.com, so internal actions must be +referenced by absolute URL. + +## Versioning + +Pin to a major version tag (`@v1`) for automatic patch/minor updates. +Pin to an exact tag (`@v1.0.3`) to freeze. + +## Obtaining `COPR_CONFIG` + +1. Log in to . +2. Visit . +3. Copy the entire `[copr-cli]` config block. +4. Save as a Gitea secret named `COPR_CONFIG` in the consuming repo + (or at org level to share across all org repos). diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..fe41be1 --- /dev/null +++ b/action.yml @@ -0,0 +1,44 @@ +name: 'Publish to Fedora COPR' +description: > + Submit a source RPM to Fedora COPR, watch the build through to + completion, and dump each chroot's builder-live.log into the CI + output as collapsible groups. +author: 'helexa' + +branding: + icon: package + color: blue + +inputs: + project: + description: 'COPR project in the form / (e.g. helexa/cortex).' + required: true + srpm: + description: > + Path(s) to the source RPM(s) to submit. Glob patterns are expanded + by the shell, so '*.src.rpm' is fine. + required: true + copr-config: + description: > + Contents of ~/.config/copr — obtain from + https://copr.fedorainfracloud.org/api/ and pass via secrets. + required: true + +runs: + using: composite + steps: + - name: Configure copr-cli + shell: bash + run: | + mkdir -p ~/.config + umask 077 + printf '%s\n' "${{ inputs.copr-config }}" > ~/.config/copr + + - name: Submit build and stream logs + shell: bash + env: + COPR_PROJECT: ${{ inputs.project }} + COPR_SRPM: ${{ inputs.srpm }} + run: | + # shellcheck disable=SC2086 + bash "${{ github.action_path }}/scripts/copr-build.sh" "$COPR_PROJECT" $COPR_SRPM diff --git a/scripts/copr-build.sh b/scripts/copr-build.sh new file mode 100755 index 0000000..435aae1 --- /dev/null +++ b/scripts/copr-build.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Submit an SRPM to COPR, watch the build, and dump per-chroot build logs +# to stdout so they are captured in CI output. +# +# Usage: copr-build.sh [srpm...] +# Example: copr-build.sh helexa/cortex ./cortex-0.1.2-1.fc43.src.rpm +# +# Requires: copr-cli on PATH, a valid ~/.config/copr. + +set -o pipefail + +PROJECT="$1" +shift + +if [ -z "$PROJECT" ] || [ "$#" -eq 0 ]; then + echo "usage: $0 [srpm...]" >&2 + exit 2 +fi + +# Submit without waiting; capture the build ID from stdout. +SUBMIT_OUT=$(copr-cli build --nowait "$PROJECT" "$@") +echo "$SUBMIT_OUT" +BUILD_ID=$(echo "$SUBMIT_OUT" | grep -oP 'Created builds: \K[0-9]+' | head -n1) + +if [ -z "$BUILD_ID" ]; then + echo "error: could not parse build ID from copr-cli output" >&2 + exit 1 +fi + +echo +echo "Build $BUILD_ID submitted to $PROJECT" +echo "Follow live: https://copr.fedorainfracloud.org/coprs/build/$BUILD_ID" +echo + +# Watch the build; captures status transitions to stdout. Exit non-zero +# on build failure, but defer propagating that until after we've fetched +# logs so the CI output contains diagnostics either way. +if copr-cli watch-build "$BUILD_ID"; then + STATUS=0 +else + STATUS=$? +fi + +# Fetch per-chroot results (logs + rpms). Anonymous download — no auth needed. +LOG_DIR="$(mktemp -d -t copr-logs.XXXXXX)" +copr-cli download-build --dest "$LOG_DIR" "$BUILD_ID" || { + echo "warning: failed to download build artifacts" >&2 +} + +# Dump each chroot's builder-live.log as a collapsible group. +for chroot_dir in "$LOG_DIR"/*/; do + [ -d "$chroot_dir" ] || continue + chroot=$(basename "$chroot_dir") + log="${chroot_dir}builder-live.log" + if [ -f "$log" ]; then + echo + echo "::group::${chroot} builder-live.log" + cat "$log" + echo "::endgroup::" + fi +done + +exit "$STATUS"