Skip to content

o/ifacestate: properly handle undo scenarios where auto-connections are dropped #8182

o/ifacestate: properly handle undo scenarios where auto-connections are dropped

o/ifacestate: properly handle undo scenarios where auto-connections are dropped #8182

Workflow file for this run

name: Tests
on:
pull_request:
branches: [ "master", "release/**", "core-snap-security-release/**", "security-release/**", "hotfix/**" ]
push:
branches: [ "release/**", "core-snap-security-release/**", "security-release/**" ]
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
go-channels:
runs-on: ubuntu-latest
outputs:
go-channels: ${{ steps.resolve-go-channels.outputs.go-channels }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Resolve Go snap channels
id: resolve-go-channels
uses: ./.github/actions/resolve-go-channels
with:
include-snapd-build-go-channel: true
include-snapd-build-fips-go-channel: true
include-latest-go-channel: false
- name: Check go channels
run: |
echo "Resolved Go channels: ${{ steps.resolve-go-channels.outputs.go-channels }}"
if [ -z "${{ steps.resolve-go-channels.outputs.go-channels }}" ]; then
echo "Error: No Go channels resolved" >&2
exit 1
fi
snap-builds:
uses: ./.github/workflows/snap-builds.yaml
with:
runs-on: ${{ matrix.runs-on }}
toolchain: ${{ matrix.toolchain }}
variant: ${{ matrix.variant }}
strategy:
matrix:
runs-on:
- '["ubuntu-22.04"]'
- ${{ github.event.repository.private && '["self-hosted", "Linux", "jammy", "ARM64", "large"]' || '["ubuntu-22.04-arm"]' }}
toolchain:
- default
- FIPS
variant:
# test version is a build of snapd with test keys and should
# only be installed by test runners. The pristine versions
# are the build that should be installed by human users.
- pristine
- test
# Exclude building everything for ARM but the version for testing
# to keep the number of builds down as we currently don't have a
# clear need for these excluded builds.
exclude:
- runs-on: ${{ github.event.repository.private && '["self-hosted", "Linux", "jammy", "ARM64", "large"]' || '["ubuntu-22.04-arm"]' }}
toolchain: FIPS
- runs-on: ${{ github.event.repository.private && '["self-hosted", "Linux", "jammy", "ARM64", "large"]' || '["ubuntu-22.04-arm"]' }}
variant: pristine
create-vendor-dir:
runs-on: ubuntu-latest
name: Create go vendor
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: vendor
run: |
sudo snap install --classic --channel 1.18/stable go
/snap/bin/go mod vendor
(
cd c-vendor
./vendor.sh
)
mkdir /tmp/pkg
base_version="$(head -1 packaging/ubuntu-16.04/changelog | awk -F '[()]' '{print $2}')"
version="1337.$base_version"
./packaging/pack-source -v "$version" -o /tmp/pkg
./packaging/pack-source -v "$version" -o /tmp/pkg -s
echo "$version" > /tmp/pkg/version
- name: Upload vendors
uses: actions/upload-artifact@v7
with:
name: vendor-pkgs
path: /tmp/pkg
package-snapd-rpm-mock:
needs: create-vendor-dir
uses: ./.github/workflows/rpm-mock-builds.yaml
name: Package ${{ matrix.build-config.system }}
with:
runs-on: '["ubuntu-latest"]'
system: ${{ matrix.build-config.system }}
pkg-dir: ${{ matrix.build-config.pkg-dir }}
config: ${{ matrix.build-config.config }}
strategy:
fail-fast: false
matrix:
build-config:
- { system: fedora-42-64, pkg-dir: fedora-42, config: fedora-42-x86_64 }
- { system: centos-9-64, pkg-dir: centos-9, config: centos-stream-9-x86_64 }
package-snapd-rpm-rpmbuild:
needs: create-vendor-dir
uses: ./.github/workflows/rpm-rpmbuild-builds.yaml
secrets: inherit
name: Package ${{ matrix.build-config.system }}
with:
runs-on: '["ubuntu-latest"]'
pkg-dir: ${{ matrix.build-config.pkg-dir }}
system: ${{ matrix.build-config.system }}
dockerfile: ${{ matrix.build-config.dockerfile }}
image-name: ${{ matrix.build-config.image-name }}
image-tag: ${{ matrix.build-config.image-tag }}
strategy:
fail-fast: false
matrix:
build-config:
- { system: "opensuse-tumbleweed-64", dockerfile: "opensuse.dockerfile", image-name: "opensuse/tumbleweed", image-tag: "latest", pkg-dir: "opensuse-tumbleweed" }
- { system: "opensuse-15.6-64", dockerfile: "opensuse.dockerfile", image-name: "opensuse/leap", image-tag: "15.6", pkg-dir: "opensuse-15.6" }
- { system: "opensuse-16.0-64", dockerfile: "opensuse.dockerfile", image-name: "opensuse/leap", image-tag: "16.0", pkg-dir: "opensuse-16.0" }
- { system: "amazon-linux-2-64", dockerfile: "amazon.dockerfile", image-name: "amazonlinux", image-tag: "2", pkg-dir: "amzn-2" }
- { system: "amazon-linux-2023-64", dockerfile: "amazon.dockerfile", image-name: "amazonlinux", image-tag: "2023", pkg-dir: "amzn-2023" }
package-snapd-arch:
needs: create-vendor-dir
uses: ./.github/workflows/arch-builds.yaml
name: Package arch-linux-64
with:
runs-on: '["ubuntu-latest"]'
package-snapd-deb:
needs: create-vendor-dir
uses: ./.github/workflows/deb-builds.yaml
name: Package ${{ matrix.build-config.system }}
with:
runs-on: ${{ matrix.build-config.runs-on }}
system: ${{ matrix.build-config.system }}
os-version: ${{ matrix.build-config.os-version }}
os: ${{ matrix.build-config.os }}
strategy:
fail-fast: false
matrix:
build-config:
- { system: "ubuntu-26.04-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '26.04' }
- { system: "ubuntu-25.10-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '25.10' }
- { system: "ubuntu-25.04-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '25.04' }
- { system: "ubuntu-24.04-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '24.04' }
- { system: "ubuntu-22.04-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '22.04' }
- { system: "ubuntu-20.04-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '20.04' }
- { system: "ubuntu-18.04-64", runs-on: '["ubuntu-latest"]', os: ubuntu, os-version: '18.04' }
- { system: "debian-sid-64", runs-on: '["ubuntu-latest"]', os: debian, os-version: 'sid' }
- { system: "ubuntu-24.04-arm-64", runs-on: '["ubuntu-24.04-arm"]', os: ubuntu, os-version: '24.04' }
- { system: "ubuntu-22.04-arm-64", runs-on: '["ubuntu-24.04-arm"]', os: ubuntu, os-version: '22.04' }
cache-build-deps:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Download Debian dependencies
run: |
sudo apt clean
sudo apt update
ln -s packaging/ubuntu-16.04 debian
sudo apt build-dep -d -y ${{ github.workspace }}
# for indent
sudo apt install texinfo autopoint
- name: Copy dependencies
run: |
sudo tar cvf cached-apt.tar /var/cache/apt
- name: upload Debian dependencies
uses: actions/upload-artifact@v7
with:
name: debian-dependencies
path: ./cached-apt.tar
static-checks:
uses: ./.github/workflows/static-checks.yaml
needs:
- go-channels
- cache-build-deps
with:
runs-on: ubuntu-latest
gochannel: ${{ matrix.gochannel }}
strategy:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
gochannel: ${{ fromJson(needs.go-channels.outputs.go-channels) }}
static-checks-not-required:
uses: ./.github/workflows/static-checks.yaml
needs:
- cache-build-deps
with:
runs-on: ubuntu-latest
gochannel: 'latest/stable'
branch-static-checks:
runs-on: ubuntu-latest
needs: [cache-build-deps]
if: github.ref != 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
# needed for git commit history
fetch-depth: 0
- name: check-branch-ubuntu-daily-spread
run: |
# Compare the daily system in master and in the current branch
get_daily_system() {
json1=$1
json2=$2
jq -s '{ include: [ .[0].include, .[1].include ] | add }' "$json1" "$json2" | \
jq '.include.[] | select(.group == "ubuntu-daily") | .systems'
}
wget -q -O master_fundsys.json https://raw.githubusercontent.com/snapcore/snapd/master/.github/workflows/data-fundamental-systems.json
wget -q -O master_nonfundsys.json https://raw.githubusercontent.com/snapcore/snapd/master/.github/workflows/data-non-fundamental-systems.json
master_daily="$(get_daily_system master_fundsys.json master_nonfundsys.json)"
branch_daily="$(get_daily_system .github/workflows/data-fundamental-systems.json .github/workflows/data-non-fundamental-systems.json)"
test "$master_daily" == "$branch_daily"
shell: bash
# The required-static-checks job was introduced to maintain a consistent
# status check name, regardless of changes to the Go channel used for static
# checks. This avoids the need to update required status checks whenever the
# Go channel changes.
required-static-checks:
runs-on: ubuntu-latest
needs:
- static-checks
- branch-static-checks
if: always()
steps:
- name: Filter out branch-static-checks from needs
run: |
# The branch-static-checks job is skipped when testing on the master
# branch. The combine-results action treats skipped jobs as failed
# because a failure earlier in the chain (e.g., in cache-build-deps)
# would also cause branch-static-checks to be skipped, which
# constitutes a legitimate failure. To handle this, when
# branch-static-checks is skipped during testing on the master branch
# we remove it from the list of dependencies whose results are checked.
if [[ "${GITHUB_REF}" == "refs/heads/master" ]]; then
filtered_needs=$(echo '${{ toJSON(needs) }}' | jq 'del(.["branch-static-checks"])')
echo "NEEDS_FILTERED=$(echo $filtered_needs | jq -c)" >> $GITHUB_ENV
else
echo "NEEDS_FILTERED=$(echo '${{ toJSON(needs) }}' | jq -c)" >> $GITHUB_ENV
fi
shell: bash
- name: Checkout code
uses: actions/checkout@v6
- name: Confirm required static checks passed
uses: ./.github/actions/combine-results
with:
needs-json: ${{ env.NEEDS_FILTERED }}
unit-tests:
uses: ./.github/workflows/unit-tests.yaml
needs:
- go-channels
- static-checks
name: "unit-tests (Go default ${{ matrix.gochannel }})"
with:
runs-on: ubuntu-latest
gochannel: ${{ matrix.gochannel }}
skip-coverage: false
code: 'go'
strategy:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
gochannel: ${{ fromJson(needs.go-channels.outputs.go-channels) }}
unit-tests-not-required:
uses: ./.github/workflows/unit-tests.yaml
needs:
- static-checks-not-required
name: "unit-tests (Go default latest/stable})"
with:
runs-on: ubuntu-latest
gochannel: 'latest/stable'
skip-coverage: true
code: 'go'
unit-tests-c:
uses: ./.github/workflows/unit-tests.yaml
needs:
- cache-build-deps
name: "unit-tests (C ${{ matrix.test-case.c-compiler }})"
with:
runs-on: ubuntu-latest
code: 'c'
c-compiler: ${{ matrix.test-case.c-compiler }}
strategy:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
test-case:
- { c-compiler: gcc }
- { c-compiler: clang }
unit-tests-special:
uses: ./.github/workflows/unit-tests.yaml
needs:
- go-channels
- static-checks
name: "unit-tests (Go ${{ matrix.gochannel }} ${{ matrix.test-case.go-build-tags }}
${{ matrix.test-case.go-test-race && ' test-race' || ''}}
${{ matrix.test-case.snapd-debug && ' snapd-debug' || ''}})"
with:
runs-on: ubuntu-latest
gochannel: ${{ matrix.gochannel }}
skip-coverage: ${{ matrix.gochannel == 'latest/stable' || matrix.test-case.skip-coverage }}
go-build-tags: ${{ matrix.test-case.go-build-tags }}
go-test-race: ${{ matrix.test-case.go-test-race }}
snapd-debug: ${{ matrix.test-case.snapd-debug }}
code: 'go'
strategy:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
gochannel: ${{ fromJson(needs.go-channels.outputs.go-channels) }}
test-case:
- { go-build-tags: snapd_debug, skip-coverage: false, snapd-debug: true, go-test-race: false}
- { go-build-tags: withbootassetstesting, skip-coverage: false, snapd-debug: false, go-test-race: false}
- { go-build-tags: optee, skip-coverage: false, snapd-debug: false, go-test-race: false}
- { go-build-tags: nosecboot, skip-coverage: false, snapd-debug: false, go-test-race: false}
- { go-build-tags: faultinject, skip-coverage: false, snapd-debug: false, go-test-race: false}
- { go-build-tags: statelocktrace, skip-coverage: true, snapd-debug: false, go-test-race: false}
- { go-build-tags: snapdusergo, skip-coverage: false, snapd-debug: false, go-test-race: false}
- { go-build-tags: structuredlogging, skip-coverage: true, snapd-debug: false, go-test-race: false}
- { go-build-tags: "", skip-coverage: true, snapd-debug: false, go-test-race: true }
unit-tests-special-not-required:
uses: ./.github/workflows/unit-tests.yaml
needs:
- static-checks-not-required
name: "unit-tests (Go latest/stable ${{ matrix.test-case.go-build-tags }}
${{ matrix.test-case.go-test-race && ' test-race' || ''}}
${{ matrix.test-case.snapd-debug && ' snapd-debug' || ''}})"
with:
runs-on: ubuntu-latest
gochannel: 'latest/stable'
skip-coverage: true
go-build-tags: ${{ matrix.test-case.go-build-tags }}
go-test-race: ${{ matrix.test-case.go-test-race }}
snapd-debug: ${{ matrix.test-case.snapd-debug }}
code: 'go'
strategy:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
test-case:
- { go-build-tags: snapd_debug, snapd-debug: true, go-test-race: false}
- { go-build-tags: withbootassetstesting, snapd-debug: false, go-test-race: false}
- { go-build-tags: optee, snapd-debug: false, go-test-race: false}
- { go-build-tags: nosecboot, snapd-debug: false, go-test-race: false}
- { go-build-tags: faultinject, snapd-debug: false, go-test-race: false}
- { go-build-tags: statelocktrace, snapd-debug: false, go-test-race: false}
- { go-build-tags: snapdusergo, snapd-debug: false, go-test-race: false}
- { go-build-tags: structuredlogging, snapd-debug: false, go-test-race: false}
- { go-build-tags: "", snapd-debug: false, go-test-race: true }
unit-tests-cross-distro:
uses: ./.github/workflows/unit-tests-cross-distro.yaml
needs: [static-checks]
with:
runs-on: ubuntu-latest
distro: ${{ matrix.distro }}
strategy:
fail-fast: false
matrix:
distro:
# TODO add arch?
- fedora:latest
- opensuse/tumbleweed
unit-tests-python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '>=3.9'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- run: |
find tests/ -name 'requirements.txt' -exec pip install -r {} \;
pytest tests
unit-tests-fuzzing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Fuzz go unit tests
uses: ./.github/actions/go-fuzz
with:
fuzzing-search-dir: confdb
# The required-unit-tests job was introduced to maintain a consistent
# status check name, regardless of changes to the Go channel used for unit
# tests. This avoids the need to update required status checks whenever the
# Go channel changes.
required-unit-tests:
runs-on: ubuntu-latest
needs:
- unit-tests
- unit-tests-special
- unit-tests-c
- unit-tests-cross-distro
if: always()
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Confirm required unit tests passed
uses: ./.github/actions/combine-results
with:
needs-json: ${{ toJSON(needs) }}
code-coverage:
needs: [unit-tests, unit-tests-special, unit-tests-c]
runs-on: ubuntu-latest
env:
GOPATH: ${{ github.workspace }}
# Set PATH to ignore the load of magic binaries from /usr/local/bin And
# to use the go snap automatically. Note that we install go from the
# snap in a step below. Without this we get the GitHub-controlled latest
# version of go.
PATH: /snap/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:${{ github.workspace }}/bin
GOROOT: ""
steps:
- name: Download the coverage files
uses: actions/download-artifact@v8
with:
pattern: coverage-files-*
path: .coverage/
merge-multiple: true
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v6
# uploading to codecov occasionally fails, so continue running the test
# workflow regardless of the upload
continue-on-error: true
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
name: codecov-umbrella
verbose: true
# exclude codecov binaries
exclude: codecov*
disable_search: true
files: .coverage/*
# only pick files under .coverage directory
network_filter: .coverage/
read-systems:
runs-on: ubuntu-latest
# This dependency only serves to ensure this job runs after the
# labeler finishes its work
needs: snap-builds
env:
GH_TOKEN: ${{ github.token }}
outputs:
fundamental-systems: ${{ steps.read-systems.outputs.fundamental-systems }}
non-fundamental-systems: ${{ steps.read-systems.outputs.non-fundamental-systems }}
nested-systems: ${{ steps.read-systems.outputs.nested-systems }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Read matrix file
id: read-systems
shell: bash
run: |
set -x
echo "fundamental-systems=$(jq -c . ./.github/workflows/data-fundamental-systems.json)" >> $GITHUB_OUTPUT
echo "non-fundamental-systems=$(jq -c . ./.github/workflows/data-non-fundamental-systems.json)" >> $GITHUB_OUTPUT
echo "nested-systems=$(jq -c . ./.github/workflows/data-nested-systems.json)" >> $GITHUB_OUTPUT
if [ -n "${{ github.event.pull_request.number }}" ]; then
labels=$(gh pr view ${{ github.event.pull_request.number }} --json labels | jq -r '.labels[].name')
if grep -q '^Run only one system$' <<<$labels; then
body="$(gh pr view ${{ github.event.pull_request.number }} --json body --jq .body)"
# grab the regex that follows the #runonlyonesystem tag if it exists
# if it doesn't exist, don't fail here; that case will be caught when checking
# the number of filtered systems vs. total systems
filter="$(grep -ioP '#runonlyonesystem\K.*' <<<"$body" || true)"
# remove all whitespaces (systems shouldn't have spaces in their names anyway)
filter="$(tr -d '[:space:]' <<<"$filter")"
# use the regex to filter in systems in both fundamental and non-fundamental systems
fundamental_systems="$(jq -c --arg regex "$filter" '.include |= map(select(.systems | test($regex)))' .github/workflows/data-fundamental-systems.json)"
non_fundamental_systems="$(jq -c --arg regex "$filter" '.include |= map(select(.systems | test($regex)))' .github/workflows/data-non-fundamental-systems.json)"
# count the number of systems selected vs. total number
selected_fund="$(grep -o "systems" <<<"$fundamental_systems" | wc -l || true)"
selected_non_fund="$(grep -o "systems" <<<"$non_fundamental_systems" | wc -l || true)"
total_fund="$(jq -c . .github/workflows/data-fundamental-systems.json | grep -o "systems" | wc -l)"
total_nonfund="$(jq -c . .github/workflows/data-non-fundamental-systems.json | grep -o "systems" | wc -l)"
# if no systems were filtered in, then filter in only noble
# this condition can trigger if something like a '.*' was used as regex or
# if the #runonlyonesystem tag was not present in the PR description
if [[ ( "$selected_fund" -eq "$total_fund" && "$selected_non_fund" -eq "$total_nonfund" ) || \
( "$selected_fund" -eq 0 && "$selected_non_fund" -eq 0 ) ]]; then
echo "filtering out everything except for noble since no systems were filtered out"
echo "If you wanted to choose different systems to run, use the #runonlyonesystem tag followed by a regex of what you wish to select"
echo "filtered fundamental systems are $fundamental_systems"
echo "filtered non-fundamental systems are $non_fundamental_systems"
fundamental_systems="$(jq -c --arg regex 'ubuntu-24.04-64' '.include |= map(select(.systems | test($regex)))' .github/workflows/data-fundamental-systems.json)"
non_fundamental_systems="$(jq -c --arg regex 'ubuntu-24.04-64' '.include |= map(select(.systems | test($regex)))' .github/workflows/data-non-fundamental-systems.json)"
fi
echo "fundamental-systems=$fundamental_systems" >> $GITHUB_OUTPUT
echo "non-fundamental-systems=$non_fundamental_systems" >> $GITHUB_OUTPUT
if ! grep -q '^Run nested$' <<<$labels; then
echo "nested-systems=" >> $GITHUB_OUTPUT
fi
fi
fi
spread-fundamental:
uses: ./.github/workflows/spread-tests.yaml
needs: [unit-tests, unit-tests-c, snap-builds, read-systems]
if: contains(needs.read-systems.outputs.fundamental-systems, 'systems')
name: "spread ${{ matrix.group }}"
secrets: inherit
with:
# Github doesn't support passing sequences as parameters.
# Instead here we create a json array and pass it as a string.
# Then in the spread workflow it turns it into a sequence
# using the fromJSON expression.
runs-on: '${{ matrix.runs-on }}'
group: ${{ matrix.group }}
backend: ${{ matrix.backend }}
alternative-backend: ${{ matrix.alternative-backend }}
systems: ${{ matrix.systems }}
tasks: ${{ matrix.tasks }}
rules: ${{ matrix.rules }}
is-fundamental: true
strategy:
# FIXME: enable fail-fast mode once spread can cancel an executing job.
# Disable fail-fast mode as it doesn't function with spread. It seems
# that cancelling tasks requires short, interruptible actions and
# interrupting spread, notably, does not work today. As such disable
# fail-fast while we tackle that problem upstream.
fail-fast: false
matrix: ${{ fromJson(needs.read-systems.outputs.fundamental-systems) }}
spread-not-fundamental-pr:
uses: ./.github/workflows/spread-tests.yaml
if: |
always() &&
needs.unit-tests.result == 'success' &&
needs.unit-tests-c.result == 'success' &&
needs.snap-builds.result == 'success' &&
needs.read-systems.result == 'success' &&
( needs.spread-fundamental.result == 'success' || needs.spread-fundamental.result == 'skipped' ) &&
github.event_name == 'pull_request' &&
!contains(github.base_ref, 'release') &&
!contains(github.event.pull_request.labels.*.name, 'cross-distro') &&
contains(needs.read-systems.outputs.non-fundamental-systems, 'systems')
# For workflow runs that are PRs, run this non-fundamental systems job
# only after the fundamental systems job succeeds.
needs: [unit-tests, unit-tests-c, snap-builds, read-systems, spread-fundamental]
name: "spread ${{ matrix.group }}"
secrets: inherit
with:
# Github doesn't support passing sequences as parameters.
# Instead here we create a json array and pass it as a string.
# Then in the spread workflow it turns it into a sequence
# using the fromJSON expression.
runs-on: '${{ matrix.runs-on }}'
group: ${{ matrix.group }}
backend: ${{ matrix.backend }}
alternative-backend: ${{ matrix.alternative-backend }}
systems: ${{ matrix.systems }}
tasks: ${{ matrix.tasks }}
rules: ${{ matrix.rules }}
strategy:
# FIXME: enable fail-fast mode once spread can cancel an executing job.
# Disable fail-fast mode as it doesn't function with spread. It seems
# that cancelling tasks requires short, interruptible actions and
# interrupting spread, notably, does not work today. As such disable
# fail-fast while we tackle that problem upstream.
fail-fast: false
matrix: ${{ fromJson(needs.read-systems.outputs.non-fundamental-systems) }}
spread-not-fundamental-not-pr:
uses: ./.github/workflows/spread-tests.yaml
if: |
contains(needs.read-systems.outputs.non-fundamental-systems, 'systems') &&
(
github.event_name != 'pull_request' ||
contains(github.base_ref, 'release') ||
contains(github.event.pull_request.labels.*.name, 'cross-distro')
)
# For workflow runs that are not for PRs, no need to impose a dependency
# on the fundamental systems job's success before running this job.
needs: [unit-tests, unit-tests-c, snap-builds, read-systems]
name: "spread ${{ matrix.group }}"
secrets: inherit
with:
# Github doesn't support passing sequences as parameters.
# Instead here we create a json array and pass it as a string.
# Then in the spread workflow it turns it into a sequence
# using the fromJSON expression.
runs-on: '${{ matrix.runs-on }}'
group: ${{ matrix.group }}
backend: ${{ matrix.backend }}
alternative-backend: ${{ matrix.alternative-backend }}
systems: ${{ matrix.systems }}
tasks: ${{ matrix.tasks }}
rules: ${{ matrix.rules }}
strategy:
# FIXME: enable fail-fast mode once spread can cancel an executing job.
# Disable fail-fast mode as it doesn't function with spread. It seems
# that cancelling tasks requires short, interruptible actions and
# interrupting spread, notably, does not work today. As such disable
# fail-fast while we tackle that problem upstream.
fail-fast: false
matrix: ${{ fromJson(needs.read-systems.outputs.non-fundamental-systems) }}
spread-nested:
uses: ./.github/workflows/spread-tests.yaml
needs: [unit-tests, unit-tests-c, snap-builds, read-systems]
if: contains(needs.read-systems.outputs.nested-systems, 'systems')
name: "spread ${{ matrix.group }}"
secrets: inherit
with:
# Github doesn't support passing sequences as parameters.
# Instead here we create a json array and pass it as a string.
# Then in the spread workflow it turns it into a sequence
# using the fromJSON expression.
runs-on: '${{ matrix.runs-on }}'
group: ${{ matrix.group }}
backend: ${{ matrix.backend }}
alternative-backend: ${{ matrix.alternative-backend }}
systems: ${{ matrix.systems }}
tasks: ${{ matrix.tasks }}
rules: ${{ matrix.rules }}
strategy:
# FIXME: enable fail-fast mode once spread can cancel an executing job.
# Disable fail-fast mode as it doesn't function with spread. It seems
# that cancelling tasks requires short, interruptible actions and
# interrupting spread, notably, does not work today. As such disable
# fail-fast while we tackle that problem upstream.
fail-fast: false
matrix: ${{ fromJson(needs.read-systems.outputs.nested-systems) }}
# The spread-results-reporter needs the PR number to be able to
# comment on the relevant PR with spread failures. Because the PR
# number is not in the github.event object during the
# spread-results-reporter.yaml job run, we upload it along side other
# artifacts to be subsequently downloaded by spread-results-reporter.
upload_pr_number:
if: ${{ github.event.pull_request.number }}
runs-on: ubuntu-latest
steps:
- name: Create PR number file
run: echo "${{ github.event.pull_request.number }}" > pr_number
- name: Upload PR number
uses: actions/upload-artifact@v7
with:
name: pr_number
path: pr_number