Merge branch 'main' into ci/opt-in-sccache

# Conflicts:
#	.github/workflows/gate.yml
#	README.md
This commit is contained in:
FredApps committed 2026-11-13 20:46:39 +01:00
commit bc67c8a00c
48 files changed
+2732 -129

No files matched your search

+3
View File
@@ -40,6 +40,9 @@ jobs:
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
api.github.com:443
github.com:443
objects.githubusercontent.com:443
+8 -8
View File
@@ -142,11 +142,11 @@ jobs:
run: bash --noprofile --norc -eo pipefail -c "$PRE_BUILD_COMMAND"
- name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
uses: step-security/setup-buildx-action@e50058a0fcd8d1a7d626c905502d010a468bf238 # v4.4.1
- name: Log in to Docker Hub (DHI base images)
if: ${{ inputs.dhi-login }}
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
uses: step-security/docker-login-action@8c7b695d8738c5699a679ff5254baf0f19f20a94 # v4.6.0
with:
registry: dhi.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -154,7 +154,7 @@ jobs:
- name: Log in to GHCR
if: ${{ contains(inputs.images, 'ghcr.io') }}
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
uses: step-security/docker-login-action@8c7b695d8738c5699a679ff5254baf0f19f20a94 # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -162,7 +162,7 @@ jobs:
- name: Log in to Docker Hub
if: ${{ contains(inputs.images, 'docker.io/') }}
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
uses: step-security/docker-login-action@8c7b695d8738c5699a679ff5254baf0f19f20a94 # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -268,11 +268,11 @@ jobs:
merge-multiple: true
- name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
uses: step-security/setup-buildx-action@e50058a0fcd8d1a7d626c905502d010a468bf238 # v4.4.1
- name: Log in to GHCR
if: ${{ contains(inputs.images, 'ghcr.io') }}
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
uses: step-security/docker-login-action@8c7b695d8738c5699a679ff5254baf0f19f20a94 # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -280,14 +280,14 @@ jobs:
- name: Log in to Docker Hub
if: ${{ contains(inputs.images, 'docker.io/') }}
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
uses: step-security/docker-login-action@8c7b695d8738c5699a679ff5254baf0f19f20a94 # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker metadata
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
uses: step-security/metadata-action@21378f5b76c96c69ac34d21cc3873d85e26381b1 # v6.2.0
with:
images: ${{ inputs.images }}
tags: ${{ inputs.tags }}
+3
View File
@@ -47,6 +47,9 @@ jobs:
name: release-linux-${{ matrix.arch }}
path: dist/linux
- name: Configure apt mirrors
uses: storytold/craft-common-actions/actions/configure-apt-mirrors@main
- name: Install Flatpak and Skopeo
run: |
sudo apt-get update
+7 -1
View File
@@ -94,8 +94,14 @@ jobs:
x86_64|aarch64) ;;
*) echo "::error::unsupported architecture '$ARCH' (use x86_64 or aarch64)"; exit 1 ;;
esac
# The VM action apt-installs QEMU on the host: give it the mirrors outside ubuntu.com, and
# drop the image's Microsoft source, which this job never installs from.
- name: Configure apt mirrors
uses: storytold/craft-common-actions/actions/configure-apt-mirrors@main
- name: Drop the Microsoft apt source
run: sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list /etc/apt/sources.list.d/microsoft-prod.sources
- name: Start the FreeBSD VM
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1.5.9
uses: step-security/freebsd-vm@a2f5754275f7b0d5cea7f2762c9960727950f128 # v1.5.9
with:
release: ${{ inputs.freebsd-release == '15.1-STABLE' && '15.1' || inputs.freebsd-release }}
# Always an x86_64 guest, which KVM accelerates: aarch64 is cross-compiled in it,
+25 -2
View File
@@ -17,6 +17,11 @@ on:
type: string
required: false
default: "cargo xtask ci"
setup-command:
description: "Optional setup script, run from the repository root before the gate (for example, fetch SHA-verified corpora)"
type: string
required: false
default: ""
windows-command:
description: "The gate on Windows legs; empty runs `command`"
type: string
@@ -128,6 +133,9 @@ jobs:
with:
egress-policy: audit
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
*.crates.io:443
*.github.com:443
*.githubusercontent.com:443
@@ -141,8 +149,13 @@ jobs:
azure.archive.ubuntu.com:80
azure.archive.ubuntu.com:443
crates.io:443
ftp.tu-chemnitz.de:443
github.com:443
index.crates.io:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
objects.githubusercontent.com:443
packages.microsoft.com:443
release-assets.githubusercontent.com:443
@@ -237,7 +250,7 @@ jobs:
- name: Install cargo tools
if: inputs.tools != ''
uses: taiki-e/install-action@b80e2bb2635f28eb98b9fce1e2f0887e1535c6b2 # v2.90.0
uses: step-security/taiki-e-install-action@76747d22a7567cc4438546a84f11bdf18e670ab8 # v2.87.32
with:
tool: ${{ inputs.tools }}
@@ -264,7 +277,7 @@ jobs:
# Default-branch writes remain the default. Maintainers can explicitly opt manual
# branch runs into branch-scoped writes; pull-request runs never save a cache.
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
prefix-key: ${{ inputs.cache-version }}-rust
key: ${{ steps.cache-profile.outputs.key }}
@@ -298,6 +311,16 @@ jobs:
echo "SCCACHE_GHA_RW_MODE=READ_ONLY" >> "$GITHUB_ENV"
fi
- name: Caller setup
if: inputs.setup-command != ''
shell: bash
env:
SETUP: ${{ inputs.setup-command }}
run: |
set -euo pipefail
printf '%s\n' "$SETUP" > "$RUNNER_TEMP/gate-setup.sh"
bash -euo pipefail "$RUNNER_TEMP/gate-setup.sh"
- name: Gate
shell: bash
env:
+3
View File
@@ -35,6 +35,9 @@ jobs:
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
api.github.com:443
github.com:443
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+7
View File
@@ -24,6 +24,9 @@ jobs:
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
*.github.com:443
*.githubusercontent.com:443
*.microsoft.com:443
@@ -35,6 +38,10 @@ jobs:
azure.archive.ubuntu.com:80
azure.archive.ubuntu.com:443
github.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
objects.githubusercontent.com:443
packages.microsoft.com:443
release-assets.githubusercontent.com:443
+84 -26
View File
@@ -84,6 +84,23 @@ on:
type: boolean
required: false
default: false
publish:
description: >-
Publish the draft when the run is done, instead of leaving it for a maintainer: only on
the release branch, only when no build job failed or was cancelled, and only when the
draft has at least as many assets as the last published release (a skipped job leaves the
run green).
type: boolean
required: false
default: false
dry-run:
description: >-
Build and check without releasing: no signing, no `release` environment, no macOS (its
larger runner is paid for), no Flatpak OCI push and no draft. For a nightly run on main
that finds release-only breakage (riscv64, Flatpak, FreeBSD, packaging) before release day.
type: boolean
required: false
default: false
secrets:
APPLE_CERTIFICATE:
@@ -214,9 +231,10 @@ jobs:
macos:
timeout-minutes: 90
name: macOS universal
if: ${{ !inputs.dry-run }}
needs: [version]
runs-on: macos-15-xlarge
environment: release
environment: ${{ !inputs.dry-run && 'release' || '' }}
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
@@ -277,11 +295,11 @@ jobs:
ref: ${{ inputs.craft-fonts-ref }}
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
targets: aarch64-apple-darwin, x86_64-apple-darwin
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: release-macos-universal
- name: Apply version override
@@ -335,14 +353,16 @@ jobs:
timeout-minutes: 90
name: Windows ${{ matrix.arch }}
needs: [version]
runs-on: windows-latest
environment: release
# arm64 builds natively on GitHub's Arm runner (free for public repositories). Cross-compiled
# on x64 it was the slowest job of the 11 Nov 2026 releases (30 to 39 minutes).
runs-on: ${{ matrix.runner }}
environment: ${{ !inputs.dry-run && 'release' || '' }}
strategy:
fail-fast: false
matrix:
include:
- { arch: x64, target: x86_64-pc-windows-msvc }
- { arch: arm64, target: aarch64-pc-windows-msvc }
- { arch: x64, target: x86_64-pc-windows-msvc, runner: windows-latest }
- { arch: arm64, target: aarch64-pc-windows-msvc, runner: windows-11-arm }
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
@@ -405,11 +425,11 @@ jobs:
ref: ${{ inputs.craft-fonts-ref }}
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: release-windows-${{ matrix.arch }}
- name: Apply version override
@@ -446,7 +466,7 @@ jobs:
needs: [version]
# The signing key lives in the release environment, as it does for the macOS, Windows and
# flatpak jobs; without this the Linux packages are built unsigned.
environment: release
environment: ${{ !inputs.dry-run && 'release' || '' }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
@@ -496,10 +516,10 @@ jobs:
with:
deb-arch: ${{ matrix.deb }}
nfpm-version: ${{ inputs.nfpm-version }}
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: release-linux-${{ matrix.arch }}
- name: Apply version override
@@ -543,7 +563,7 @@ jobs:
needs: [version, linux]
runs-on: ${{ matrix.runner }}
# LINUX_SIGNING_KEY comes from the repo's release environment, as the macOS secrets do.
environment: release
environment: ${{ !inputs.dry-run && 'release' || '' }}
permissions:
contents: read
packages: write
@@ -582,6 +602,8 @@ jobs:
with:
name: release-linux-${{ matrix.arch }}
path: dist/linux
- name: Configure apt mirrors
uses: storytold/craft-common-actions/actions/configure-apt-mirrors@main
- name: Install flatpak-builder
run: |
sudo apt-get update
@@ -617,7 +639,7 @@ jobs:
packaging/linux/flatpak-bundle.sh "$tarball"
printf 'tarball=%s\n' "$tarball" >> "$GITHUB_OUTPUT"
- name: Publish Flatpak OCI layout to GHCR and Docker Hub
if: github.event_name != 'pull_request'
if: github.event_name != 'pull_request' && !inputs.dry-run
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}
ARCH: ${{ matrix.arch }}
@@ -793,7 +815,7 @@ jobs:
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- name: Start the FreeBSD VM
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1.5.9
uses: step-security/freebsd-vm@a2f5754275f7b0d5cea7f2762c9960727950f128 # v1.5.9
with:
release: ${{ inputs.freebsd-release == '15.1-STABLE' && '15.1' || inputs.freebsd-release }}
# Always an x86_64 guest, which KVM accelerates: aarch64 is cross-compiled in it,
@@ -883,7 +905,11 @@ jobs:
uses: storytold/craft-common-actions/actions/freebsd-cargo-cache@main
with:
profile: release
configuration: ${{ toJSON(inputs) }}
# Only what changes the FreeBSD build. Not toJSON(inputs): contributors-artifact names
# this run (contributor-snapshot-<run id>-<attempt>), so no later run could restore the
# entry, and dry-run must share it, so that a dry run warms the release's cache.
configuration: ${{ format('{{"app-name":{0},"arch":{1},"craft-fonts-ref":{2},"freebsd-release":{3}}}', toJSON(inputs.app-name), toJSON(matrix.arch), toJSON(inputs.craft-fonts-ref), toJSON(inputs.freebsd-release)) }}
target: ${{ matrix.arch == 'aarch64' && 'aarch64-unknown-freebsd' || '' }}
source-hash: ${{ hashFiles('**/Cargo.lock', '**/Cargo.toml', '**/build.rs', '.cargo/**', 'rust-toolchain*', 'packaging/**', '.github/workflows/release.yml') }}
- name: Build and package
shell: freebsd {0}
@@ -967,7 +993,11 @@ jobs:
with:
phase: save
profile: release
configuration: ${{ toJSON(inputs) }}
# Only what changes the FreeBSD build. Not toJSON(inputs): contributors-artifact names
# this run (contributor-snapshot-<run id>-<attempt>), so no later run could restore the
# entry, and dry-run must share it, so that a dry run warms the release's cache.
configuration: ${{ format('{{"app-name":{0},"arch":{1},"craft-fonts-ref":{2},"freebsd-release":{3}}}', toJSON(inputs.app-name), toJSON(matrix.arch), toJSON(inputs.craft-fonts-ref), toJSON(inputs.freebsd-release)) }}
target: ${{ matrix.arch == 'aarch64' && 'aarch64-unknown-freebsd' || '' }}
source-hash: ${{ hashFiles('**/Cargo.lock', '**/Cargo.toml', '**/build.rs', '.cargo/**', 'rust-toolchain*', 'packaging/**', '.github/workflows/release.yml') }}
key: ${{ steps.cargo-cache.outputs.key }}
@@ -1009,11 +1039,11 @@ jobs:
app-name: ${{ inputs.app-name }}
version: ${{ needs.version.outputs.version }}
date: ${{ needs.version.outputs.date }}
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: release-web
- uses: storytold/craft-common-actions/actions/install-trunk@main
@@ -1049,7 +1079,7 @@ jobs:
name: Linux riscv64
if: inputs.has-riscv64
needs: [version]
environment: release
environment: ${{ !inputs.dry-run && 'release' || '' }}
# Not 22.04 like the other Linux jobs: Ubuntu never built jammy's ncurses security update for
# riscv64, so the amd64 and riscv64 libtinfo6 can't match and the cross deps don't install (#44).
runs-on: ubuntu-24.04
@@ -1094,11 +1124,11 @@ jobs:
ref: ${{ inputs.craft-fonts-ref }}
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
targets: riscv64gc-unknown-linux-gnu
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: release-linux-riscv64
- name: Apply version override
@@ -1189,10 +1219,10 @@ jobs:
date: ${{ needs.version.outputs.date }}
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: release-server-${{ matrix.arch }}
- name: Apply version override
@@ -1215,10 +1245,10 @@ jobs:
release:
timeout-minutes: 10
name: Draft GitHub Release
if: "!cancelled() && !contains(needs.*.result, 'failure')"
if: "!inputs.dry-run && !cancelled() && !contains(needs.*.result, 'failure')"
needs: [version, macos, windows, linux, linux-riscv64, flatpak, arch, freebsd, web, server]
runs-on: ubuntu-24.04
environment: release
environment: ${{ !inputs.dry-run && 'release' || '' }}
permissions:
contents: write
steps:
@@ -1233,3 +1263,31 @@ jobs:
prerelease: ${{ needs.version.outputs.prerelease }}
github-token: ${{ secrets.GITHUB_TOKEN }}
signing-key: ${{ github.ref == 'refs/heads/release' && secrets.LINUX_SIGNING_KEY || '' }}
- name: Publish the release
if: inputs.publish && !inputs.dry-run && github.ref == 'refs/heads/release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
TAG: v${{ needs.version.outputs.version }}
CANCELLED: ${{ contains(needs.*.result, 'cancelled') }}
run: |
set -euo pipefail
refuse() {
echo "::error::$1"
echo "Not published: $1" >> "$GITHUB_STEP_SUMMARY"
exit 1
}
if [ "$CANCELLED" != false ]; then
refuse "a build job was cancelled: $TAG stays a draft"
fi
now="$(gh release view "$TAG" --json assets --jq '.assets | length')"
# The most recently published release; gh lists by creation, not publication.
last="$(gh release list --exclude-drafts --exclude-pre-releases --limit 50 --json tagName,publishedAt --jq 'sort_by(.publishedAt) | last | .tagName // ""')"
if [ -n "$last" ] && [ "$last" != "$TAG" ]; then
before="$(gh release view "$last" --json assets --jq '.assets | length')"
if [ "$now" -lt "$before" ]; then
refuse "$TAG has $now assets where $last had $before: it stays a draft"
fi
fi
gh release edit "$TAG" --draft=false
echo "Published $TAG ($now assets)." >> "$GITHUB_STEP_SUMMARY"
+194 -28
View File
@@ -97,7 +97,11 @@ jobs:
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
with:
egress-policy: block
# Ubuntu Pro APT hooks use esm.ubuntu.com for security-update metadata.
# Keep this explicit alongside the archive hosts instead of allowing all Ubuntu subdomains.
allowed-endpoints: >
*.amazontrust.com:80
motd.ubuntu.com:443
*.amazonaws.com:443
*.crates.io:443
*.s3.amazonaws.com:443
@@ -109,8 +113,6 @@ jobs:
*.pythonhosted.org:443
*.sonarcloud.io:443
*.sonarsource.com:443
*.ubuntu.com:80
*.ubuntu.com:443
api.github.com:443
archive.ubuntu.com:80
archive.ubuntu.com:443
@@ -118,11 +120,16 @@ jobs:
azure.archive.ubuntu.com:443
binaries.sonarsource.com:443
crates.io:443
esm.ubuntu.com:443
files.pythonhosted.org:443
github.com:443
index.crates.io:443
keys.openpgp.org:443
keyserver.ubuntu.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
objects.githubusercontent.com:443
packages.microsoft.com:443
pypi.org:443
@@ -168,7 +175,11 @@ jobs:
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
with:
egress-policy: block
# Ubuntu Pro APT hooks use esm.ubuntu.com for security-update metadata.
# Keep this explicit alongside the archive hosts instead of allowing all Ubuntu subdomains.
allowed-endpoints: >
*.amazontrust.com:80
motd.ubuntu.com:443
*.amazonaws.com:443
*.crates.io:443
*.s3.amazonaws.com:443
@@ -180,8 +191,6 @@ jobs:
*.pythonhosted.org:443
*.sonarcloud.io:443
*.sonarsource.com:443
*.ubuntu.com:80
*.ubuntu.com:443
api.github.com:443
archive.ubuntu.com:80
archive.ubuntu.com:443
@@ -189,11 +198,16 @@ jobs:
azure.archive.ubuntu.com:443
binaries.sonarsource.com:443
crates.io:443
esm.ubuntu.com:443
files.pythonhosted.org:443
github.com:443
index.crates.io:443
keys.openpgp.org:443
keyserver.ubuntu.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
objects.githubusercontent.com:443
packages.microsoft.com:443
pypi.org:443
@@ -211,6 +225,8 @@ jobs:
uses: storytold/craft-common-actions/actions/checkout-craft-fonts@main
with:
ref: ${{ inputs.fonts-ref }}
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- name: Require requested craft-fonts
if: inputs.fonts-ref != ''
shell: bash
@@ -234,10 +250,10 @@ jobs:
run: |
rustup toolchain install stable --profile minimal --component llvm-tools-preview
rustup default stable
- uses: taiki-e/install-action@b80e2bb2635f28eb98b9fce1e2f0887e1535c6b2 # v2.90.0
- uses: step-security/taiki-e-install-action@76747d22a7567cc4438546a84f11bdf18e670ab8 # v2.87.32
with:
tool: cargo-llvm-cov,cargo-nextest@0.9.150
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Provision pinned PDF test fonts
@@ -291,7 +307,11 @@ jobs:
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
with:
egress-policy: block
# Ubuntu Pro APT hooks use esm.ubuntu.com for security-update metadata.
# Keep this explicit alongside the archive hosts instead of allowing all Ubuntu subdomains.
allowed-endpoints: >
*.amazontrust.com:80
motd.ubuntu.com:443
*.amazonaws.com:443
*.crates.io:443
*.s3.amazonaws.com:443
@@ -303,8 +323,6 @@ jobs:
*.pythonhosted.org:443
*.sonarcloud.io:443
*.sonarsource.com:443
*.ubuntu.com:80
*.ubuntu.com:443
api.github.com:443
archive.ubuntu.com:80
archive.ubuntu.com:443
@@ -312,11 +330,16 @@ jobs:
azure.archive.ubuntu.com:443
binaries.sonarsource.com:443
crates.io:443
esm.ubuntu.com:443
files.pythonhosted.org:443
github.com:443
index.crates.io:443
keys.openpgp.org:443
keyserver.ubuntu.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
objects.githubusercontent.com:443
packages.microsoft.com:443
pypi.org:443
@@ -334,6 +357,8 @@ jobs:
uses: storytold/craft-common-actions/actions/checkout-craft-fonts@main
with:
ref: ${{ inputs.fonts-ref }}
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- name: Require requested craft-fonts
if: inputs.fonts-ref != ''
shell: bash
@@ -349,7 +374,7 @@ jobs:
pkg-config libxkbcommon-dev libwayland-dev libx11-dev libxcursor-dev libxrandr-dev
libxi-dev libgtk-3-dev libfontconfig1-dev libfreetype-dev libasound2-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev
libgl1-mesa-dev mesa-vulkan-drivers
- uses: taiki-e/install-action@b80e2bb2635f28eb98b9fce1e2f0887e1535c6b2 # v2.90.0
- uses: step-security/taiki-e-install-action@76747d22a7567cc4438546a84f11bdf18e670ab8 # v2.87.32
with:
tool: cargo-nextest@0.9.150
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
@@ -371,8 +396,8 @@ jobs:
run: |
mkdir -p profraw
# nextest exits 100 when tests fail. A red test must not hide the static analysis, so
# that alone keeps the job green. Any other exit means the shard could not run its
# tests at all (for example a test binary nextest cannot list): fail the job, because a
# record that status for the scan job to fail after uploading analysis. Any other exit
# means the shard could not run its tests at all (for example a test binary nextest cannot list): fail the job, because a
# shard that runs nothing would scan an empty coverage report.
rc=0
cargo nextest run --archive-file archive/nextest-archive.tar.zst \
@@ -381,15 +406,73 @@ jobs:
echo "::error::nextest could not run shard $SHARD (exit $rc)"
exit "$rc"
fi
if ! ls profraw/*.profraw >/dev/null 2>&1; then
mkdir -p profdata
printf '%s\n' "$rc" > "profdata/shard-$SHARD.status"
if ls profraw/*.profraw >/dev/null 2>&1; then
profiles=true
else
profiles=false
fi
if [ "$rc" -eq 100 ]; then
echo "::warning::Coverage shard $SHARD/$TOTAL_SHARDS has failing tests; see this job's test log."
if [ "$profiles" = true ]; then
result="**Tests failed.** Coverage profiles are available, so the SonarCloud scan will continue. A green coverage job does not mean the tests passed; see this job's log for failed tests and diagnostics."
else
result='**Tests failed.** This shard produced no coverage profiles, so its tests cannot be included in the SonarCloud scan.'
fi
else
if [ "$profiles" = true ]; then
result='**Tests passed.** Coverage profiles are available for the SonarCloud scan.'
else
result='**Tests passed.** This shard produced no coverage profiles, so its tests cannot be included in the SonarCloud scan.'
fi
fi
printf '### Coverage shard %s/%s\n\n%s\n' "$SHARD" "$TOTAL_SHARDS" "$result" >> "$GITHUB_STEP_SUMMARY"
if [ "$profiles" != true ]; then
echo "::error::shard $SHARD produced no coverage profiles"
exit 1
fi
- name: Install LLVM tools for the archive's toolchain
run: rustup toolchain install "$(cat archive/rustc-release.txt)" --profile minimal --component llvm-tools-preview
- name: Merge this shard's profiles
# Raw profiles of a large workspace run to tens of gigabytes per shard; the scan job cannot
# hold every shard's at once. One sparse indexed profile per shard is a small fraction of that.
shell: bash
env:
SHARD: ${{ matrix.shard }}
run: |
set -euo pipefail
toolchain="$(cat archive/rustc-release.txt)"
llvm_bin="$(rustup run "$toolchain" rustc --print sysroot)/lib/rustlib/$(rustup run "$toolchain" rustc -vV | sed -n 's/^host: //p')/bin"
echo "Raw profiles: $(du -sh profraw | cut -f1) in $(find profraw -name '*.profraw' | wc -l) files"
df -h .
mkdir -p profdata
# failure-mode=any stops on any unreadable input. A profile cut short (a test process that
# crashed while writing it, or a full disk) fails this shard and names the file, instead of
# being uploaded and failing the scan's merge later with no shard to look at.
status=0
"$llvm_bin/llvm-profdata" merge -sparse --failure-mode=any profraw/*.profraw \
-o "profdata/shard-$SHARD.profdata" 2>merge-errors.txt || status=$?
if [ "$status" -ne 0 ]; then
cat merge-errors.txt >&2
sed -n 's/^warning: \(.*\.profraw\): \(.*\)$/\1: \2/p' merge-errors.txt | while IFS= read -r bad; do
echo "::error::shard $SHARD wrote a truncated or corrupt coverage profile: $bad"
done
echo "::error::llvm-profdata could not merge shard $SHARD's profiles (exit $status)"
rm -rf profdata
exit "$status"
fi
rm -rf profraw merge-errors.txt
echo "Merged profile: $(du -sh "profdata/shard-$SHARD.profdata" | cut -f1)"
df -h .
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: profraw-${{ matrix.shard }}
path: profraw/
if-no-files-found: ignore
name: profdata-${{ matrix.shard }}
path: profdata/
if-no-files-found: error
retention-days: 1
sonarcloud:
@@ -404,7 +487,11 @@ jobs:
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
with:
egress-policy: block
# Ubuntu Pro APT hooks use esm.ubuntu.com for security-update metadata.
# Keep this explicit alongside the archive hosts instead of allowing all Ubuntu subdomains.
allowed-endpoints: >
*.amazontrust.com:80
motd.ubuntu.com:443
*.amazonaws.com:443
*.crates.io:443
*.s3.amazonaws.com:443
@@ -416,8 +503,6 @@ jobs:
*.pythonhosted.org:443
*.sonarcloud.io:443
*.sonarsource.com:443
*.ubuntu.com:80
*.ubuntu.com:443
api.github.com:443
archive.ubuntu.com:80
archive.ubuntu.com:443
@@ -425,11 +510,16 @@ jobs:
azure.archive.ubuntu.com:443
binaries.sonarsource.com:443
crates.io:443
esm.ubuntu.com:443
files.pythonhosted.org:443
github.com:443
index.crates.io:443
keys.openpgp.org:443
keyserver.ubuntu.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
objects.githubusercontent.com:443
packages.microsoft.com:443
pypi.org:443
@@ -469,12 +559,31 @@ jobs:
echo "::error::Invalid SonarCloud project key: must start with an alphanumeric character or underscore and contain only letters, digits, dash, underscore, period or colon (max 400 characters)."
exit 1
fi
printf 'key=%s\n' "$PROJECT_KEY" >>"$GITHUB_OUTPUT"
# A -D argument replaces the same property in sonar-project.properties, so the repository's
# own duplication exclusions are appended to the shared one here.
cpd='**/i18n/**'
own=""
if [[ -f sonar-project.properties ]]; then
# Properties syntax: optional blanks around `=` or `:`, and a CRLF file leaves a trailing \r.
own=$(sed -n 's/^[ \t]*sonar\.cpd\.exclusions[ \t]*[=:][ \t]*//p' sonar-project.properties | tail -n 1 | sed 's/[ \t\r]*$//')
fi
if [[ -n "$own" ]]; then
if [[ ! "$own" =~ ^[a-zA-Z0-9_.*?/,-]+$ ]]; then
echo "::error::Invalid sonar.cpd.exclusions in sonar-project.properties: only letters, digits, and _ . * ? / , - are allowed."
exit 1
fi
cpd="$cpd,$own"
fi
printf 'key=%s\ncpd=%s\n' "$PROJECT_KEY" "$cpd" >>"$GITHUB_OUTPUT"
- name: Check out craft-fonts
if: steps.token.outputs.available == 'true' && inputs.shards <= 1
uses: storytold/craft-common-actions/actions/checkout-craft-fonts@main
with:
ref: ${{ inputs.fonts-ref }}
- name: Check out craft-i18n
if: steps.token.outputs.available == 'true' && inputs.shards <= 1
id: i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- name: Require requested craft-fonts
if: inputs.fonts-ref != '' && steps.token.outputs.available == 'true' && inputs.shards <= 1
shell: bash
@@ -504,11 +613,11 @@ jobs:
run: |
rustup toolchain install stable --profile minimal --component llvm-tools-preview
rustup default stable
- uses: taiki-e/install-action@b80e2bb2635f28eb98b9fce1e2f0887e1535c6b2 # v2.90.0
- uses: step-security/taiki-e-install-action@76747d22a7567cc4438546a84f11bdf18e670ab8 # v2.87.32
if: steps.token.outputs.available == 'true' && hashFiles('Cargo.toml') != '' && inputs.shards <= 1
with:
tool: cargo-llvm-cov
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
if: steps.token.outputs.available == 'true' && hashFiles('Cargo.toml') != '' && inputs.shards <= 1
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
@@ -518,6 +627,9 @@ jobs:
run: |
python3 scripts/fetch-pdf-test-fonts.py "$RUNNER_TEMP/craft-pdf-test-fonts"
echo "CRAFT_PDF_TEST_FONT_DIR=$RUNNER_TEMP/craft-pdf-test-fonts" >> "$GITHUB_ENV"
- name: Fetch locked Rust dependencies
if: steps.token.outputs.available == 'true' && hashFiles('Cargo.toml') != '' && inputs.shards <= 1
run: cargo fetch --locked
- name: Generate Rust coverage
id: coverage
if: steps.token.outputs.available == 'true' && hashFiles('Cargo.toml') != '' && inputs.shards <= 1
@@ -538,14 +650,23 @@ jobs:
if [ "$SQLX_OFFLINE_INPUT" = true ]; then export SQLX_OFFLINE=true; fi
features=()
if [ -n "$CARGO_FEATURES" ]; then features=(--features "$CARGO_FEATURES"); fi
cargo llvm-cov --workspace "${features[@]}" --ignore-run-fail --lcov --output-path lcov.info \
# Run every instrumented test and remember failures, but still create coverage so
# SonarCloud can publish diagnostics before this workflow reports a red result.
set +e
cargo llvm-cov --workspace "${features[@]}" --no-report --no-fail-fast \
--ignore-filename-regex "$COVERAGE_IGNORE"
test_status=$?
set -e
echo "test_status=$test_status" >> "$GITHUB_OUTPUT"
cargo llvm-cov report --lcov --output-path lcov.info \
--ignore-filename-regex "$COVERAGE_IGNORE"
- name: Download shard profiles and archive
if: steps.token.outputs.available == 'true' && inputs.shards > 1 && hashFiles('Cargo.toml') != ''
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
pattern: profraw-*
path: profraw
# One merged profile per shard (shard-N.profdata), never the raw profiles.
pattern: profdata-*
path: profdata
merge-multiple: true
- name: Download test archive
if: steps.token.outputs.available == 'true' && inputs.shards > 1 && hashFiles('Cargo.toml') != ''
@@ -564,10 +685,10 @@ jobs:
toolchain="$(cat archive/rustc-release.txt)"
llvm_bin="$(rustup run "$toolchain" rustc --print sysroot)/lib/rustlib/$(rustup run "$toolchain" rustc -vV | sed -n 's/^host: //p')/bin"
df -h . "$RUNNER_TEMP"
# Do not hold every raw profile beside the expanded archive. Retain the raw inputs
# Each shard merged its own raw profiles; combine those. Retain the shard profiles
# until the merge succeeds, then release them before unpacking the test binaries.
"$llvm_bin/llvm-profdata" merge -sparse profraw/*.profraw -o coverage.profdata
rm -f profraw/*.profraw
"$llvm_bin/llvm-profdata" merge -sparse profdata/*.profdata -o coverage.profdata
rm -f profdata/*.profdata
df -h . "$RUNNER_TEMP"
# Unpack outside the checkout: the scanner analyses everything under the workspace, and build
# output (generated sources) there would be counted as duplicated code.
@@ -656,9 +777,18 @@ jobs:
status=0
npm run --silent -- "$NODE_COVERAGE_SCRIPT" || status=$?
echo "status=$status" >>"$GITHUB_OUTPUT"
# The checkout is a build input, not caller source. Moving it after all coverage runs
# prevents an unsharded scan from counting another repository's files as this project.
- name: Move craft-i18n outside scan workspace
if: steps.i18n.outputs.rev != ''
shell: bash
run: |
set -euo pipefail
destination="$(mktemp -d "$RUNNER_TEMP/craft-i18n.XXXXXX")"
mv -- "$GITHUB_WORKSPACE/craft-i18n" "$destination/checkout"
- name: SonarCloud Scan
if: steps.token.outputs.available == 'true'
uses: SonarSource/sonarqube-scan-action@e805d875275f728fac1885b413934be6d7c63f65 # v8.4.1
uses: step-security/sonarqube-scan-action@c2312f8888f2bff4220bd815febb9d4a7cb32433 # v8.2.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_CLOUD_PAT || secrets.SONAR_TOKEN }}
SONAR_HOST_URL: https://sonarcloud.io
@@ -667,7 +797,21 @@ jobs:
"-Dsonar.projectKey=${{ steps.project.outputs.key }}"
-Dsonar.organization=storytold
-Dsonar.rust.lcov.reportPaths=lcov.info
"-Dsonar.cpd.exclusions=**/i18n/**"
"-Dsonar.cpd.exclusions=${{ steps.project.outputs.cpd }}"
- name: Fail on Rust coverage generation failure
if: steps.coverage.outcome == 'failure'
shell: bash
run: |
echo "::error::cargo llvm-cov failed to build the test archive or write lcov.info"
exit 1
- name: Fail on Rust instrumented test failures
if: steps.coverage.outputs.test_status != '' && steps.coverage.outputs.test_status != '0'
shell: bash
env:
RUST_TEST_STATUS: ${{ steps.coverage.outputs.test_status }}
run: |
echo "::error::instrumented Rust tests exited with status $RUST_TEST_STATUS"
exit 1
- name: Fail on JavaScript/TypeScript test failures
if: steps.node-coverage.outputs.status != '' && steps.node-coverage.outputs.status != '0'
env:
@@ -675,3 +819,25 @@ jobs:
run: |
echo "::error::node-coverage-script exited with status $NODE_COVERAGE_STATUS"
exit 1
- name: Fail on Rust shard test failures
if: steps.token.outputs.available == 'true' && inputs.shards > 1 && hashFiles('Cargo.toml') != ''
shell: bash
env:
TOTAL_SHARDS: ${{ inputs.shards }}
run: |
set -euo pipefail
failed=0
for ((shard=1; shard<=TOTAL_SHARDS; shard++)); do
path="profdata/shard-$shard.status"
if [ ! -f "$path" ]; then
echo "::error::Missing test status for coverage shard $shard"
failed=1
continue
fi
status="$(cat "$path")"
if [ "$status" != 0 ]; then
echo "::error::Coverage shard $shard tests failed (exit $status); analysis was still uploaded"
failed=1
fi
done
exit "$failed"
+3
View File
@@ -27,6 +27,9 @@ jobs:
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
api.github.com:443
github.com:443
objects.githubusercontent.com:443
+22
View File
@@ -28,6 +28,9 @@ jobs:
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
api.github.com:443
github.com:443
archive.ubuntu.com:80
@@ -38,10 +41,29 @@ jobs:
archive.ubuntu.com:443
azure.archive.ubuntu.com:443
security.ubuntu.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Configure apt mirrors
uses: ./actions/configure-apt-mirrors
- name: Install YAML parser
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends python3-yaml tcsh rpm debsigs dpkg-dev skopeo
# On 11 Nov 2026 one run found no candidate for tcsh or debsigs right after an update that
# fetched every index, while the runs before and after passed. These answer whether apt
# read those indexes, and whether this CPU runs the amd64v3 packages they list.
- name: Show why apt found no candidate
if: failure()
run: |
set +e
apt-cache policy tcsh debsigs
apt-config dump | grep -iE 'architecture|variant'
ls -l /var/lib/apt/lists/ | grep -E 'universe.*Packages'
grep -m1 'model name' /proc/cpuinfo
echo "avx2 cores: $(grep -c avx2 /proc/cpuinfo)"
/lib64/ld-linux-x86-64.so.2 --help | grep -A6 'glibc-hwcaps'
- name: Exercise failing tests, package validation and required fonts
run: /usr/bin/python3 -m unittest discover -s tests -v
+3
View File
@@ -29,6 +29,9 @@ jobs:
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
api.github.com:443
github.com:443
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -4,11 +4,13 @@ on:
pull_request:
paths:
- actions/install-apt-packages/**
- actions/configure-apt-mirrors/**
- .github/workflows/test-install-apt-packages.yml
push:
branches: [main]
paths:
- actions/install-apt-packages/**
- actions/configure-apt-mirrors/**
- .github/workflows/test-install-apt-packages.yml
workflow_dispatch:
@@ -17,14 +19,30 @@ permissions:
jobs:
install:
runs-on: ubuntu-24.04
name: install (${{ matrix.runner }}${{ matrix.outage && ', ubuntu.com down' || '' }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- { runner: ubuntu-24.04, outage: false }
- { runner: ubuntu-latest, outage: false }
# The images the apps' jobs use, with no ubuntu.com host reachable.
- { runner: ubuntu-22.04, outage: true }
- { runner: ubuntu-24.04, outage: true }
- { runner: ubuntu-latest, outage: true }
- { runner: ubuntu-22.04-arm, outage: true }
- { runner: ubuntu-24.04-arm, outage: true }
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
with:
egress-policy: block
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
api.github.com:443
github.com:443
archive.ubuntu.com:80
@@ -35,18 +53,54 @@ jobs:
archive.ubuntu.com:443
azure.archive.ubuntu.com:443
security.ubuntu.com:443
ports.ubuntu.com:80
ports.ubuntu.com:443
*.dotsrc.org:443
*.kernel.org:443
mirrors.dotsrc.org:443
mirrors.edge.kernel.org:443
ftp.tu-chemnitz.de:443
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Take ubuntu.com offline
if: matrix.outage
# As on 11 Nov 2026, when no ubuntu.com host resolved: the Ubuntu hosts the images use
# point at addresses that never answer, so only the mirrors outside ubuntu.com can serve.
run: |
set -euo pipefail
for host in azure.archive.ubuntu.com archive.ubuntu.com security.ubuntu.com ports.ubuntu.com; do
printf '192.0.2.1 %s\n100::1 %s\n' "$host" "$host"
done | sudo tee -a /etc/hosts
- name: Install packages
uses: ./actions/install-apt-packages
with:
# pkg-config is on every image and needs no download, so the outage legs add hello: a
# package no image has, and a list no cache was saved for (save: never), so it has to
# come from a mirror.
packages: |
pkg-config libxkbcommon-dev
mesa-vulkan-drivers
${{ matrix.outage && 'hello' || '' }}
save: ${{ matrix.outage && 'never' || 'default-branch' }}
- name: Check the packages and the kept downloads
run: |
set -euo pipefail
dpkg -s pkg-config libxkbcommon-dev mesa-vulkan-drivers > /dev/null
ls "$HOME"/.cache/craft-apt-debs/*.deb > /dev/null
test -z "$(find "$HOME/.cache/craft-apt-debs" ! -user "$(id -un)" -print -quit)"
- name: Check apt went around ubuntu.com
if: matrix.outage
run: |
set -euo pipefail
dpkg -s hello > /dev/null
cat /etc/apt/craft-apt-mirrors.txt
# The first mirror apt tries is outside ubuntu.com, and a fresh update of the Ubuntu
# sources gets every index, which apt can only have fetched from there. The image's
# other repositories (sources.list.d) are left out: they are not what this tests.
head -n 1 /etc/apt/craft-apt-mirrors.txt | grep -v 'ubuntu\.com'
parts=$(mktemp -d)
if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then
cp /etc/apt/sources.list.d/ubuntu.sources "$parts/"
fi
sudo apt-get update -o Dir::Etc::SourceParts="$parts" -o APT::Update::Error-Mode=any
@@ -0,0 +1,59 @@
name: install-riscv64-cross test
on:
pull_request:
paths:
- actions/install-riscv64-cross/**
- .github/workflows/test-install-riscv64-cross.yml
push:
branches: [main]
paths:
- actions/install-riscv64-cross/**
- .github/workflows/test-install-riscv64-cross.yml
workflow_dispatch:
permissions:
contents: read
jobs:
install:
name: install (${{ matrix.outage && 'ubuntu.com down' || 'ubuntu.com up' }})
# The image release.yml's Linux riscv64 job uses.
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
outage: [false, true]
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Take ubuntu.com offline
if: matrix.outage
# As on 11 Nov 2026, when no ubuntu.com host resolved on the runners.
run: |
set -euo pipefail
for host in azure.archive.ubuntu.com archive.ubuntu.com security.ubuntu.com ports.ubuntu.com; do
echo "192.0.2.1 $host"
echo "100::1 $host"
done | sudo tee -a /etc/hosts
- name: Install the riscv64 cross toolchain
uses: ./actions/install-riscv64-cross
- name: Check the cross toolchain and the sources it used
run: |
set -euo pipefail
dpkg -s gcc-riscv64-linux-gnu libc6-dev:riscv64 libxkbcommon-dev:riscv64 libasound2-dev:riscv64 > /dev/null
printf 'int main(void) { return 0; }\n' > "$RUNNER_TEMP/t.c"
riscv64-linux-gnu-gcc -o "$RUNNER_TEMP/t" "$RUNNER_TEMP/t.c"
cat /etc/apt/sources.list.d/amd64-primary.list /etc/apt/sources.list.d/riscv64.list
if [ "${{ matrix.outage }}" = true ]; then
# Nothing came from ubuntu.com: every Ubuntu source is a fallback mirror.
if grep -h ubuntu.com /etc/apt/sources.list.d/amd64-*.list /etc/apt/sources.list.d/riscv64.list; then
exit 1
fi
fi
+8 -2
View File
@@ -60,6 +60,9 @@ jobs:
with:
egress-policy: audit
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
*.crates.io:443
*.github.com:443
*.githubusercontent.com:443
@@ -76,14 +79,14 @@ jobs:
persist-credentials: false
- name: Check out craft-i18n
uses: storytold/craft-common-actions/actions/checkout-craft-i18n@main
- uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
with:
toolchain: stable
targets: aarch64-pc-windows-msvc
# The nightly run on main saves; pull requests and `release` restore it. A pull request's
# cache (about 0.7 GB) is visible to that pull request alone, and the apps' caches sit at
# the 10 GB limit, so each one evicted a cache main's gate restores.
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
with:
key: windows-arm64-package
save-if: ${{ github.ref == 'refs/heads/main' }}
@@ -114,6 +117,9 @@ jobs:
with:
egress-policy: audit
allowed-endpoints: >
*.amazontrust.com:80
esm.ubuntu.com:443
motd.ubuntu.com:443
*.crates.io:443
*.github.com:443
*.githubusercontent.com:443