Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/reusable_edge_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ jobs:
package: ${{ matrix.package.package }}
ros_distro: ${{ matrix.ros_distro }}
version_suffix: ${{ matrix.package.suffix }}
archive_channels: edge stable
runner: ${{ inputs.runner }}
continue_on_failure: true

Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/reusable_release_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ on:
description: 'Appended to the version in package.xml, e.g. "+git20261027153012.ab12cd3" for a build of main'
default: ''
type: string
archive_channels:
description: 'Archive channels whose packages the build depends on, e.g. "edge stable" for a build of main'
default: 'stable'
type: string
workflow_call:
inputs:
repository:
Expand Down Expand Up @@ -86,6 +90,11 @@ on:
default: ''
required: false
type: string
archive_channels:
description: 'Archive channels whose packages the build depends on, e.g. "edge stable" for a build of main'
default: 'stable'
required: false
type: string
outputs:
artifact:
description: 'Artifact name without its architecture: one artifact per architecture built, <artifact>-<arch>'
Expand Down Expand Up @@ -114,6 +123,22 @@ jobs:
ref: v1
path: .devtools

# Dependencies on packages already published resolve from the archive the ARCHIVE_URL
# organization variable names, trusted by its key's fingerprint.
- name: Fetch the archive key
if: vars.ARCHIVE_URL != ''
env:
ARCHIVE_URL: ${{ vars.ARCHIVE_URL }}
FPR: ${{ vars.ARCHIVE_KEY_FINGERPRINT }}
run: |
[ -n "$FPR" ] || { echo "::error::ARCHIVE_URL is set without ARCHIVE_KEY_FINGERPRINT"; exit 1; }
mkdir -p "$RUNNER_TEMP/keys"
key="$RUNNER_TEMP/keys/duatic-archive.gpg"
curl -fsSL "${ARCHIVE_URL%/}/duatic-archive.gpg" -o "$key"
fprs="$(gpg --show-keys --with-colons "$key" | awk -F: '/^pub/{p=1; next} p && /^fpr/{print $10; p=0}')"
[ "$fprs" = "$FPR" ] \
|| { echo "::error::the archive key is ${fprs:-unreadable}, not $FPR" | tr "\n" " "; exit 1; }

- name: Build the package into a .deb
id: build
continue-on-error: ${{ inputs.continue_on_failure }}
Expand All @@ -123,12 +148,20 @@ jobs:
ROS_DISTRO_TARGET: ${{ inputs.ros_distro }}
ARCH: ${{ matrix.arch }}
SUFFIX: ${{ inputs.version_suffix }}
ARCHIVE_URL: ${{ vars.ARCHIVE_URL }}
ARCHIVE_CHANNELS: ${{ inputs.archive_channels }}
run: |
mkdir -p "$RUNNER_TEMP/out"
archive=()
if [ -n "$ARCHIVE_URL" ]; then
archive=(-e ARCHIVE_URL="$ARCHIVE_URL" -e ARCHIVE_CHANNELS="$ARCHIVE_CHANNELS"
-e ARCHIVE_KEYRING=/keys/duatic-archive.gpg -v "$RUNNER_TEMP/keys:/keys:ro")
fi
docker run --rm -i --platform "linux/$ARCH" \
-e HOST_UID="$(id -u)" -e HOST_GID="$(id -g)" \
-e ROS_DISTRO="$ROS_DISTRO_TARGET" \
-e DEB_VERSION_SUFFIX="$SUFFIX" \
"${archive[@]}" \
-v "$PWD/src:/src" \
-v "$PWD/.devtools/packaging/builder:/builder" \
-v "$RUNNER_TEMP/out:/out" \
Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,12 @@ symbols and, when the package declares `<duatic_publish_source>`, its source tar
It takes a tag to check out and the package to build inside it, and a `version_suffix` appended to
the `package.xml` version for a build of main. The package is named explicitly, whether the tag is
a `<package>/<version>` tag, a repo-wide `v<version>` tag or a commit, so the build does not need to
guess it from the tag's shape. It is not wired into any repository yet: a
package's dependencies on other packages in the org resolve only from the builder's local
repository, so a build stops at the first such dependency. Signing and publishing belong to the
archive host.
guess it from the tag's shape. A dependency on a package already published resolves from the
archive the organization variable `ARCHIVE_URL` names, read from the channels in
`archive_channels`: `stable` for a release, `edge stable` for a build of main, so a dependency
without a build of main comes from its release. The archive's key is fetched from it and used only
when its fingerprint is `ARCHIVE_KEY_FINGERPRINT`. Without `ARCHIVE_URL` the build resolves no
such dependency and fails at the first one. Signing and publishing belong to the archive host.

**`reusable_release_publish.yml`** takes one of those artifacts and publishes it into a signed archive root,
by delivering it to the publish host and calling `duatic_devtools`' archive tooling there. The
Expand Down Expand Up @@ -418,6 +420,7 @@ And in `ci.yml`, beside the orchestrator, for either mode:
| `repository` | build | no | the caller | `owner/name` of the repository holding the tag, for a dispatch from elsewhere. |
| `ros_distro` | build | no | `jazzy` | Distro to build for. The Ubuntu base is not an input; it's derived from this instead. |
| `version_suffix` | build | no | | Appended to the `package.xml` version, starting with `+` or `~`. The build fails if the `.deb` does not carry it. |
| `archive_channels` | build | no | `stable` | Archive channels the build's dependencies are read from, e.g. `edge stable`. |
| `channel` | publish | no | `stable` | Archive channel to publish into: `stable` or `edge`. |
| `runner` | prepare, prepare-repo, tag, repo-tag, build | no | `ubuntu-latest` | Runner label(s), e.g. `self-hosted`. |

Expand Down
Loading