Skip to content

Commit 2de7065

Browse files
authored
A re-usable static SDK compilation workflow (#3019)
A re-usable static SDK compilation workflow ### Motivation: We would like to offer the ability to opt-in to CI coverage for compilation against the Linux static SDK. ### Modifications: Introduce a workflow which will install a Swift snapshot and Linux SDK and test the repository builds against it. The script which sets up the VM will install snapshots and SDKs for either branch or released-version snapshots. They can be specified as: - a specific version string - the 'latest' version, the script attempts to find the most recent version enumerated on swift.org with both SDK and toolchain available - the most recent snapshot for the specified branch name enumerated on swift.org with both SDK and toolchain available At the moment the script should work on ubuntu and amazonlinux OSes, this can be expanded in the future. The current matrix covers testing building on Ubuntu Jammy for the main branch and latest released Swift version (6.0.3) and enables it on our periodic CI runs. See https://github.com/apple/swift-nio/actions/runs/13722773053/job/38381907947?pr=3019 for a recent example of this workflow in action. ### Result: Increased CI coverage
1 parent 21429ce commit 2de7065

File tree

5 files changed

+174
-2
lines changed

5 files changed

+174
-2
lines changed

.github/workflows/main.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,8 @@ jobs:
5454
with:
5555
name: "Integration tests"
5656
matrix_string: '${{ needs.construct-integration-test-matrix.outputs.integration-test-matrix }}'
57+
58+
static-sdk:
59+
name: Static SDK
60+
# Workaround https://github.com/nektos/act/issues/1875
61+
uses: apple/swift-nio/.github/workflows/static_sdk.yml@main

.github/workflows/static_sdk.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Static SDK
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
static-sdk:
8+
name: Static SDK
9+
# Workaround https://github.com/nektos/act/issues/1875
10+
uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main
11+
with:
12+
name: "Static SDK"
13+
matrix_string: >-
14+
{
15+
"config":[
16+
{
17+
"name":"latest-release Jammy",
18+
"swift_version":"latest-release",
19+
"platform":"Linux",
20+
"runner":"ubuntu-latest",
21+
"image":"ubuntu:jammy",
22+
"setup_command":"INSTALL_SWIFT_STATIC_SDK_VERSION=latest INSTALL_SWIFT_STATIC_SDK_ARCH=x86_64 ./scripts/install_static_sdk.sh",
23+
"command":"swift build",
24+
"command_arguments":"--swift-sdk x86_64-swift-linux-musl"
25+
},
26+
{
27+
"name":"main Jammy",
28+
"swift_version":"main",
29+
"platform":"Linux",
30+
"runner":"ubuntu-latest",
31+
"image":"ubuntu:jammy",
32+
"setup_command":"INSTALL_SWIFT_STATIC_SDK_BRANCH=main INSTALL_SWIFT_STATIC_SDK_ARCH=x86_64 ./scripts/install_static_sdk.sh",
33+
"command":"swift build",
34+
"command_arguments":"--swift-sdk x86_64-swift-linux-musl"
35+
}
36+
]
37+
}

.github/workflows/swift_load_test_matrix.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ jobs:
2828
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
2929
- id: load-matrix
3030
run: |
31-
printf "swift-matrix=%s" "$(jq -c '.' ${{ inputs.matrix_path }})" >> "$GITHUB_OUTPUT"
31+
printf "swift-matrix=%s" "$(jq -ec '.' ${{ inputs.matrix_path }})" >> "$GITHUB_OUTPUT"
32+
3233
3334
execute-matrix:
3435
name: Execute matrix

.github/workflows/swift_test_matrix.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
-e setup_command_expression="$setup_command_expression" \
5050
-e workspace="$workspace" \
5151
${{ matrix.config.image }} \
52-
bash -c "swift --version && git config --global --add safe.directory \"$workspace\" && $setup_command_expression ${{ matrix.config.command }} ${{ matrix.config.command_arguments }}"
52+
bash -c "$setup_command_expression ${{ matrix.config.command }} ${{ matrix.config.command_arguments }}"
5353
- name: Run matrix job (Windows)
5454
if: ${{ matrix.config.platform == 'Windows' }}
5555
run: |

scripts/install_static_sdk.sh

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/bin/bash
2+
##===----------------------------------------------------------------------===##
3+
##
4+
## This source file is part of the SwiftNIO open source project
5+
##
6+
## Copyright (c) 2024 Apple Inc. and the SwiftNIO project authors
7+
## Licensed under Apache License v2.0
8+
##
9+
## See LICENSE.txt for license information
10+
## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
11+
##
12+
## SPDX-License-Identifier: Apache-2.0
13+
##
14+
##===----------------------------------------------------------------------===##
15+
16+
set -uo pipefail
17+
18+
log() { printf -- "** %s\n" "$*" >&2; }
19+
error() { printf -- "** ERROR: %s\n" "$*" >&2; }
20+
fatal() { error "$@"; exit 1; }
21+
22+
# Parameter environment variables
23+
branch="${INSTALL_SWIFT_STATIC_SDK_BRANCH:=""}"
24+
version="${INSTALL_SWIFT_STATIC_SDK_VERSION:=""}"
25+
arch="${INSTALL_SWIFT_STATIC_SDK_ARCH:="aarch64"}"
26+
os_image="${INSTALL_SWIFT_STATIC_SDK_OS_IMAGE:="ubuntu22.04"}"
27+
28+
if [[ ! ( -n "$branch" && -z "$version" ) && ! ( -z "$branch" && -n "$version") ]]; then
29+
fatal "Exactly one of build or version must be defined."
30+
fi
31+
32+
log "Installing tools for this script"
33+
if command -v apt-get >/dev/null; then
34+
package_manager="apt-get"
35+
apt-get update > /dev/null
36+
elif command -v yum >/dev/null; then
37+
package_manager="yum"
38+
else
39+
fatal "Cannot find either 'apt' or 'yum'"
40+
fi
41+
42+
"$package_manager" install -y curl rsync jq tar > /dev/null
43+
case "$arch" in
44+
"aarch64")
45+
arch_suffix="-$arch" ;;
46+
"x86_64")
47+
arch_suffix="" ;;
48+
*)
49+
fatal "Unexpected architecture: $arch" ;;
50+
esac
51+
52+
os_image_sanitized="${os_image//./}"
53+
54+
if [[ -n "$branch" ]]; then
55+
# Some snapshots may not have all the artefacts we require
56+
log "Discovering branch snapshot for branch $branch"
57+
snapshots="$(curl -s "https://www.swift.org/api/v1/install/dev/main/${os_image_sanitized}.json" | jq -r --arg arch "$arch" '.[$arch] | unique | reverse | .[].dir')"
58+
for snapshot in $snapshots; do
59+
snapshot_url="https://download.swift.org/development/${os_image_sanitized}${arch_suffix}/${snapshot}/${snapshot}-${os_image}${arch_suffix}.tar.gz"
60+
static_sdk_url="https://download.swift.org/development/static-sdk/${snapshot}/${snapshot}_static-linux-0.0.1.artifactbundle.tar.gz"
61+
62+
# check that the files exist
63+
curl -sILXGET --fail "$snapshot_url" > /dev/null; snapshot_return_code=$?
64+
curl -sILXGET --fail "$static_sdk_url" > /dev/null; static_sdk_return_code=$?
65+
66+
if [[ ("$snapshot_return_code" -eq 0) && ("$static_sdk_return_code" -eq 0) ]]; then
67+
log "Discovered branch snapshot: $snapshot"
68+
break
69+
else
70+
log "Snapshot unavailable: $snapshot (Snapshot return code: $snapshot_return_code, Static SDK return code: $static_sdk_return_code)"
71+
snapshot=""
72+
fi
73+
done
74+
if [[ -z "$snapshot" ]]; then
75+
fatal "Failed to discover usable Swift snapshot"
76+
fi
77+
78+
elif [[ -n "$version" ]]; then
79+
if [[ "$version" == "latest" ]]; then
80+
log "Discovering latest version"
81+
version=$(curl -s https://www.swift.org/api/v1/install/releases.json | jq -r '.[-1].tag' | sed -E 's/swift-([0-9]+\.[0-9]+\.[0-9]+)-RELEASE/\1/')
82+
if [[ -z "$version" ]]; then
83+
fatal "Failed to discover latest Swift version"
84+
fi
85+
log "Discovered latest Swift version: $version"
86+
fi
87+
88+
snapshot_url="https://download.swift.org/swift-${version}-release/${os_image_sanitized}${arch_suffix}/swift-${version}-RELEASE/swift-${version}-RELEASE-${os_image}${arch_suffix}.tar.gz"
89+
static_sdk_url="https://download.swift.org/swift-${version}-release/static-sdk/swift-${version}-RELEASE/swift-${version}-RELEASE_static-linux-0.0.1.artifactbundle.tar.gz"
90+
fi
91+
92+
log "Installing standard Swift pre-requisites" # pre-reqs list taken from swift.org
93+
DEBIAN_FRONTEND=noninteractive "$package_manager" install -y\
94+
binutils\
95+
git\
96+
gnupg2\
97+
libc6-dev\
98+
libcurl4-openssl-dev\
99+
libedit2\
100+
libgcc-11-dev\
101+
libpython3-dev\
102+
libsqlite3-0\
103+
libstdc++-11-dev\
104+
libxml2-dev\
105+
libz3-dev\
106+
pkg-config\
107+
python3-lldb-13\
108+
tzdata\
109+
unzip\
110+
zlib1g-dev\
111+
> /dev/null
112+
113+
log "Obtaining Swift toolchain"
114+
log "Snapshot URL: $snapshot_url"
115+
snapshot_path="/tmp/$(basename "$snapshot_url")"
116+
curl -sL "$snapshot_url" -o "$snapshot_path"
117+
118+
log "Installing Swift toolchain"
119+
mkdir -p /tmp/snapshot
120+
tar xfz "$snapshot_path" --strip-components 1 -C /tmp/snapshot
121+
rsync -a /tmp/snapshot/* /
122+
123+
log "Obtaining Static SDK"
124+
log "Static SDK URL: $static_sdk_url"
125+
static_sdk_path="/tmp/$(basename "$static_sdk_url")"
126+
curl -sL "$static_sdk_url" -o "$static_sdk_path"
127+
128+
log "Installing Static SDK"
129+
swift sdk install "$static_sdk_path"

0 commit comments

Comments
 (0)