mirror of
https://github.com/storytold/craft-common-actions.git
synced 2026-11-15 15:02:24 +00:00
Merge branch 'main' into ci/opt-in-sccache
# Conflicts: # .github/workflows/gate.yml # README.md
This commit is contained in:
commit
bc67c8a00c
48 files changed
+2732
-129
No files matched your search
@@ -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
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user