Skip to content

Commit

Permalink
build-aux/snap, .github/workflows: bump go snap version for building …
Browse files Browse the repository at this point in the history
…and testing (#14752)

* build-aux/snap: up go snap channel, for snapd snap build, from 1.18/stable to 1.23/stable

* .github/workflows: add workflow to determine required version of go snap for testing

.github/workflows: changed versions to channels and other corrections

* .github/workflows: review improvements
  • Loading branch information
ernestl authored Dec 3, 2024
1 parent e6b71b0 commit 11f4060
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 15 deletions.
37 changes: 37 additions & 0 deletions .github/actions/combine-results/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Combine results
description: |
Determines a single result from one or more results. A single skipped or
failed will cause the action to fail. Details for each job will be output
as part of a results summary.
inputs:
needs-json:
description: Job outputs in JSON format
required: true
type: string

runs:
using: composite
steps:
- name: Summarise and combine results
shell: bash
run: |
needs_results=$(echo '${{ inputs.needs-json }}' | jq -r 'to_entries[] | "\(.key) \(.value.result)"')
echo "Summary:"
failed="false"
while IFS=" " read -r job result; do
if [[ "$result" != "success" ]]; then
failed="true"
echo "- ❌ Job \"$job\" returned result \"$result\""
else
echo "- ✅ Job \"$job\" returned result \"$result\""
fi
done <<< "$needs_results"
if [[ "$failed" == "false" ]]; then
echo "Overall result: success"
else
echo "Overall result: failure"
exit 1
fi
158 changes: 158 additions & 0 deletions .github/actions/resolve-go-channels/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Resolve Go snap channels
description: |
Compiles a list of Go snap channels with unique versions according to the
given optional input flags and specific channels. Looks up the snapd build
and snapd FIPS build Go channels from build-aux/snap/snapcraft.yaml. Assumes
risk stable if not specified.
inputs:
include-snapd-build-go-channel:
description: Flag instructing to include the channel of Go snap used to build Snapd snap
required: false
type: boolean
include-snapd-build-fips-go-channel:
description: Flag instructing to include the channel of Go snap used to build Snapd snap for FIPS
required: false
type: string
include-latest-go-channel:
description: Flag instructing to include the latest channel of Go snap
required: false
type: boolean
specific-go-channels:
description: Space separated list of required Go snap channels
required: false
type: string

outputs:
go-channels:
description: JSON list of Go snap channels
value: ${{ steps.resolve-go-channels.outputs.go-channels }}

runs:
using: composite
steps:
- name: Resolve Go snap channels
id: resolve-go-channels
shell: bash
run: |
# Get the Go snap version corresponding to a channel format <version>[/<risk>]
# - If optional risk is omitted, default stable will be assumed
# - Assumes both device and snap architecture amd64
go_version_from_channel() {
channel=$1
risk_default="stable"
arch_default="amd64"
# channel=<track>/<risk>
if [[ "$channel" =~ ^([0-9]+\.[0-9]+|[0-9]+\.[0-9]+-fips|latest)/(stable|candidate|beta|edge)$ ]]; then
track=${channel%%/*}
risk=${channel##*/}
# channel=<track>
elif [[ "$channel" =~ ^([0-9]+\.[0-9]+|[0-9]+\.[0-9]+-fips|latest)$ ]]; then
track=$channel
risk=$risk_default
# Not supported
else
echo "Cannot use Go channel \"$channel\""
return 1
fi
# Query params
device_arch="Snap-Device-Architecture: $arch_default"
channel_arch="$arch_default"
device_series="Snap-Device-Series: 16"
endpoint="https://api.snapcraft.io/v2/snaps/info/go"
# Query store
if ! result="$(curl -s --fail -H "$device_arch" -H "$device_series" -X GET "$endpoint")"; then
echo "Cannot use endpoint \"$endpoint\": $result"
return 1
else
version="$(jq -r ".\"channel-map\"[] \
| select ( .channel.track == \"$track\" and .channel.risk == \"$risk\" and .channel.architecture == \"$channel_arch\" ) \
| .version" <<< "$result")"
if [ -z "$version" ] || [ "$version" = "null" ]; then
echo "Cannot find version corresponding to: arch=$channel_arch, track=$track, risk=$track"
return 1
else
# Return the version
echo "$version"
fi
fi
}
go_channels=()
echo "Gathering required Go channels"
# Optional Go channel used to build Snapd snap
if [ "${{ inputs.include-snapd-build-go-channel }}" = "true" ]; then
echo "> Require Go channel used to build Snapd snap"
yaml="build-aux/snap/snapcraft.yaml"
if ! channel="$(yq '.parts.snapd.build-snaps[]' $yaml | grep "go/.*/.*")"; then
echo "Error: Cannot find valid Snapd build Go channel"
exit 1
fi
channel="$(yq '.parts.snapd.build-snaps[] | select(. == "go/*/*") | sub("^go/", "")' $yaml)"
echo "> Adding Go channel \"$channel\""
go_channels+=("$channel")
fi
# Optional Go channel used to build Snapd snap for FIPS
if [ "${{ inputs.include-snapd-build-fips-go-channel }}" = "true" ]; then
echo "> Require Go channel used to build Snapd snap for FIPS"
yaml="build-aux/snap/snapcraft.yaml"
if ! channel="$(yq '.parts.snapd.override-build' $yaml | grep "GO_TOOLCHAIN_FIPS_CHANNEL=\".*\"")"; then
echo "Error: Cannot find valid Snapd FIPS build Go channel"
exit 1
fi
channel="$(echo "$channel" | sed -n 's/^GO_TOOLCHAIN_FIPS_CHANNEL="\([^"]*\)"/\1/p')"
echo "> Adding Go channel \"$channel\""
go_channels+=("$channel")
fi
# Optional latest stable Go channel
if [ "${{ inputs.include-latest-go-channel }}" = "true" ]; then
echo "> Require latest stable Go channel"
channel="latest/stable"
echo "> Adding Go channel \"$channel\""
go_channels+=("$channel")
fi
# Optional specific Go channel(s)
if [ -n "${{ inputs.specific-go-channels }}" ]; then
echo "> Require specific Go channel(s)"
for channel in ${{ inputs.specific-go-channels }}; do
echo "> Adding Go channel \"$channel\""
go_channels+=("$channel")
done
fi

declare -A go_versions
go_channels_with_unique_version=()
echo "Dropping Go channels that duplicates Go versions"

# Iterate all the required channels and create list of
# channels with unique versions.
for channel in "${go_channels[@]}"; do
if ! output="$(go_version_from_channel "$channel")"; then
echo "Error: $output"
else
if [[ -v go_versions["$output"] ]]; then
echo "> Dropping channel \"$channel\": same Go version as channel \"${go_versions[$output]}\""
else
echo "> Keeping channel \"$channel\" with unique Go version \"$output\""
go_versions["$output"]="$channel"
go_channels_with_unique_version+=("$channel")
fi
fi
done

# Convert to single line JSON array and remove duplicates
go_channels_output="[]"
if [[ ${#go_channels_with_unique_version[@]} -gt 0 ]]; then
go_channels_output="$(printf '%s\n' "${go_channels_with_unique_version[@]}" | jq -R . | jq -s -c .)"
fi
echo "Unique Go channels: $go_channels_output"

# Output the single line JSON array
echo "go-channels=$go_channels_output" >> "$GITHUB_OUTPUT"
80 changes: 67 additions & 13 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ concurrency:
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@v4

- 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: true

snap-builds:
uses: ./.github/workflows/snap-builds.yaml
with:
Expand Down Expand Up @@ -68,7 +84,9 @@ jobs:

static-checks:
uses: ./.github/workflows/static-checks.yaml
needs: [cache-build-deps]
needs:
- go-channels
- cache-build-deps
with:
runs-on: ubuntu-latest
gochannel: ${{ matrix.gochannel }}
Expand All @@ -77,16 +95,13 @@ jobs:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
gochannel:
- 1.18
- latest/stable
gochannel: ${{ fromJson(needs.go-channels.outputs.go-channels) }}

branch-static-checks:
runs-on: ubuntu-latest
needs: [cache-build-deps]
if: github.ref != 'refs/heads/master'
steps:

- name: Checkout code
uses: actions/checkout@v4
with:
Expand All @@ -102,9 +117,30 @@ jobs:
test "$system_daily" == "$current_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: Checkout code
uses: actions/checkout@v4

- name: Confirm required static checks passed
uses: ./.github/actions/combine-results
with:
needs-json: ${{ toJSON(needs) }}

unit-tests:
uses: ./.github/workflows/unit-tests.yaml
needs: [static-checks]
needs:
- go-channels
- static-checks
name: "unit-tests default ${{ matrix.gochannel }}"
with:
runs-on: ubuntu-22.04
Expand All @@ -114,14 +150,14 @@ jobs:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
gochannel:
- 1.18
- latest/stable
gochannel: ${{ fromJson(needs.go-channels.outputs.go-channels) }}

# TODO run unit tests of C code
unit-tests-special:
uses: ./.github/workflows/unit-tests.yaml
needs: [static-checks]
needs:
- go-channels
- static-checks
name: "unit-tests (${{ matrix.gochannel }} ${{ matrix.test-case.go-build-tags }}
${{ matrix.test-case.go-test-race && ' test-race' || ''}}
${{ matrix.test-case.snapd-debug && ' snapd-debug' || ''}})"
Expand All @@ -136,9 +172,7 @@ jobs:
# we cache successful runs so it's fine to keep going
fail-fast: false
matrix:
gochannel:
- 1.18
- latest/stable
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}
Expand All @@ -161,6 +195,26 @@ jobs:
# TODO add arch?
- fedora:latest
- opensuse/tumbleweed

# 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-cross-distro
if: always()
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Confirm required unit tests passed
uses: ./.github/actions/combine-results
with:
needs-json: ${{ toJSON(needs) }}

code-coverage:
needs: [unit-tests, unit-tests-special]
Expand Down
4 changes: 2 additions & 2 deletions build-aux/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ parts:
plugin: nil
source: .
build-snaps:
- go/1.18/stable # the default Go toolchain
- go/1.23/stable # the default Go toolchain
after:
- apparmor
build-packages:
Expand Down Expand Up @@ -261,7 +261,7 @@ parts:
snap refresh --channel "$GO_TOOLCHAIN_FIPS_CHANNEL" go
# make sure it is really the Go FIPS toolchain
if ! test -f /snap/go/current/src/crypto/internal/backend/openssl_linux.go; then
echo "Go 1.21 FIPS toolchain not found"
echo "Go FIPS toolschain verification failed: cannot find /snap/go/current/src/crypto/internal/backend/openssl_linux.go"
exit 1
fi
fi
Expand Down

0 comments on commit 11f4060

Please sign in to comment.