Skip to content

Commit dc93ecd

Browse files
authored
feat: added custom toolchains support (#273)
1 parent de12b65 commit dc93ecd

33 files changed

+599
-106
lines changed

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"parserOptions": {
66
"ecmaVersion": 9,
77
"sourceType": "module",
8-
"project": "./tsconfig.json"
8+
"project": [ "./tsconfig.base.json", "./tsconfig.json"]
99
},
1010
"rules": {
1111
"i18n-text/no-en": "off",
File renamed without changes.

.github/workflows/main.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ jobs:
169169
- os: windows-latest
170170
swift: '5.3'
171171
development: false
172+
- os: ubuntu-22.04
173+
swift: ${{ fromJSON(vars.SETUPSWIFT_CUSTOM_TOOLCHAINS).ubuntu2204 }}
174+
development: true
175+
noverify: true
172176

173177
steps:
174178
- name: Checkout repository
@@ -201,10 +205,11 @@ jobs:
201205
cache-snapshot: ${{ !matrix.development }}
202206

203207
- name: Verify Swift version in macos
204-
if: runner.os == 'macOS'
208+
if: runner.os == 'macOS' && matrix.noverify != 'true'
205209
run: xcrun --toolchain ${{ env.TOOLCHAINS || '""' }} swift --version | grep ${{ steps.setup-swift.outputs.swift-version }} || exit 1
206210

207211
- name: Verify Swift version
212+
if: matrix.noverify != 'true'
208213
run: swift --version | grep ${{ steps.setup-swift.outputs.swift-version }} || exit 1
209214

210215
dry-run:

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ In other words specifying...
9999
- `"4"` will resolve to latest minor and patch version (aka `4.2.4`)
100100
- `"4.0.0"` will resolve to version `4.0`
101101

102+
<details>
103+
<summary>Additionally, to use custom toolchains, download URL can be provided. The download URL must point to a `tar` archive for `Linux`, `pkg` file for `macOS` and `exe` file for `Windows`.</summary>
104+
105+
i.e. for `macOS`: https://github.com/swiftwasm/swift/releases/download/swift-wasm-5.10-SNAPSHOT-2024-03-30-a/swift-wasm-5.10-SNAPSHOT-2024-03-30-a-macos_x86_64.pkg
106+
for `Linux`: https://github.com/swiftwasm/swift/releases/download/swift-wasm-5.10-SNAPSHOT-2024-03-30-a/swift-wasm-5.10-SNAPSHOT-2024-03-30-a-ubuntu22.04_x86_64.tar.gz
107+
108+
> [!IMPORTANT]
109+
> When using custom toolchains, please ensure that the toolchain can be installed and used on the GitHub runner, this action won't be able to validate this for custom toolchains.
110+
</details>
111+
102112
### Caveats
103113

104114
YAML interprets eg. `4.0` as a float, this action will then interpret that as `4` which will result in eg. Swift `4.2.4` being resolved. Quote your inputs! Thus surround version input with quotations:

__tests__/installer/linux.test.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import os from 'os'
12
import * as path from 'path'
23
import {promises as fs} from 'fs'
4+
// @ts-ignore
5+
import {__setos as setos} from 'getos'
36
import * as core from '@actions/core'
47
import * as exec from '@actions/exec'
58
import * as cache from '@actions/cache'
69
import * as toolCache from '@actions/tool-cache'
710
import {coerce as parseSemVer} from 'semver'
811
import {LinuxToolchainInstaller} from '../../src/installer/linux'
12+
import {ToolchainVersion} from '../../src/version'
13+
import {Platform} from '../../src/platform'
914

1015
describe('linux toolchain installation verification', () => {
1116
const env = process.env
@@ -17,7 +22,8 @@ describe('linux toolchain installation verification', () => {
1722
dir: 'swift-5.8-RELEASE',
1823
docker: '5.8-jammy',
1924
platform: 'ubuntu2204',
20-
branch: 'swift-5.8-release'
25+
branch: 'swift-5.8-release',
26+
preventCaching: false
2127
}
2228

2329
beforeEach(() => {
@@ -32,7 +38,7 @@ describe('linux toolchain installation verification', () => {
3238
it('tests download', async () => {
3339
const installer = new LinuxToolchainInstaller(toolchain)
3440
expect(installer['version']).toStrictEqual(parseSemVer('5.8'))
35-
expect(installer['baseUrl']).toBe(
41+
expect(installer['baseUrl'].href).toBe(
3642
'https://download.swift.org/swift-5.8-release/ubuntu2204/swift-5.8-RELEASE'
3743
)
3844

@@ -127,4 +133,35 @@ describe('linux toolchain installation verification', () => {
127133
const devVersion = await installer.installedSwiftVersion()
128134
expect(devVersion).toBe('5.9-dev')
129135
})
136+
137+
it('tests custom swift tool caching', async () => {
138+
setos({os: 'linux', dist: 'Ubuntu', release: '22.04'})
139+
jest.spyOn(os, 'arch').mockReturnValue('x64')
140+
const swiftwasm = 'https://github.com/swiftwasm/swift/releases/download'
141+
const name = 'swift-wasm-5.10-SNAPSHOT-2024-03-30-a'
142+
const resource = `${name}-ubuntu22.04_x86_64.tar.gz`
143+
const toolchainUrl = `${swiftwasm}/${name}/${resource}`
144+
const cVer = ToolchainVersion.create(toolchainUrl, false)
145+
const download = path.resolve('tool', 'download', 'path')
146+
const extracted = path.resolve('tool', 'extracted', 'path')
147+
const cached = path.resolve('tool', 'cached', 'path')
148+
jest.spyOn(core, 'getBooleanInput').mockReturnValue(true)
149+
jest.spyOn(cache, 'restoreCache').mockResolvedValue(undefined)
150+
jest.spyOn(toolCache, 'find').mockReturnValue('')
151+
jest.spyOn(fs, 'cp').mockResolvedValue()
152+
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue(download)
153+
jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted)
154+
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue(cached)
155+
jest.spyOn(exec, 'exec').mockResolvedValue(0)
156+
const cacheSpy = jest.spyOn(cache, 'saveCache')
157+
const installer = await Platform.install(cVer)
158+
expect(cacheSpy).not.toHaveBeenCalled()
159+
expect(installer.data.baseUrl?.href).toBe(path.posix.dirname(toolchainUrl))
160+
expect(installer.data.preventCaching).toBe(true)
161+
expect(installer.data.name).toBe('Swift Custom Snapshot')
162+
expect(installer.data.platform).toBe('ubuntu2204')
163+
expect(installer.data.download).toBe(resource)
164+
expect(installer.data.dir).toBe(name)
165+
expect(installer.data.branch).toBe('swiftwasm')
166+
})
130167
})

__tests__/installer/windows.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ describe('windows toolchain installation verification', () => {
1919
dir: 'swift-5.8-RELEASE',
2020
platform: 'windows10',
2121
branch: 'swift-5.8-release',
22-
windows: true
22+
windows: true,
23+
preventCaching: false
2324
}
2425
const visualStudio = VisualStudio.createFromJSON({
2526
installationPath: path.join('C:', 'Visual Studio'),
@@ -61,7 +62,7 @@ describe('windows toolchain installation verification', () => {
6162
it('tests download without caching', async () => {
6263
const installer = new WindowsToolchainInstaller(toolchain)
6364
expect(installer['version']).toStrictEqual(parseSemVer('5.8'))
64-
expect(installer['baseUrl']).toBe(
65+
expect(installer['baseUrl'].href).toBe(
6566
'https://download.swift.org/swift-5.8-release/windows10/swift-5.8-RELEASE'
6667
)
6768

__tests__/installer/xcode.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ describe('macOS toolchain installation verification', () => {
1616
name: 'Xcode Swift 5.8.1',
1717
date: new Date('2023-05-31T18:30:00.000Z'),
1818
download: 'swift-5.8.1-RELEASE-osx.pkg',
19-
symbols: 'swift-5.8.1-RELEASE-osx-symbols.pkg',
19+
debug_info: 'swift-5.8.1-RELEASE-osx-symbols.pkg',
2020
dir: 'swift-5.8.1-RELEASE',
2121
xcode: '14.3.1',
2222
platform: 'xcode',
2323
branch: 'swift-5.8.1-release',
24-
xcodePath: '/Applications/Xcode_14.3.1.app'
24+
xcodePath: '/Applications/Xcode_14.3.1.app',
25+
preventCaching: false
2526
}
2627

2728
beforeEach(() => {
@@ -56,7 +57,7 @@ describe('macOS toolchain installation verification', () => {
5657
it('tests download', async () => {
5758
const installer = new XcodeToolchainInstaller(toolchain)
5859
expect(installer['version']).toStrictEqual(parseSemVer('5.8.1'))
59-
expect(installer['baseUrl']).toBe(
60+
expect(installer['baseUrl'].href).toBe(
6061
'https://download.swift.org/swift-5.8.1-release/xcode/swift-5.8.1-RELEASE'
6162
)
6263

__tests__/main.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ describe('setup-swift run validation', () => {
2020
dir: 'swift-5.8-RELEASE',
2121
docker: '5.8-jammy',
2222
platform: 'ubuntu2204',
23-
branch: 'swift-5.8-release'
23+
branch: 'swift-5.8-release',
24+
preventCaching: false
2425
}
2526

2627
it('tests dry run', async () => {

__tests__/snapshot/linux.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os from 'os'
2+
import {posix} from 'path'
23
// @ts-ignore
34
import {__setos as setos} from 'getos'
45
import {ToolchainVersion} from '../../src/version'
@@ -30,6 +31,7 @@ describe('fetch linux tool data based on options', () => {
3031
'swift-4.2.4-RELEASE-ubuntu18.04.tar.gz.sig'
3132
)
3233
expect(lTool.docker).toBeUndefined()
34+
expect(lTool.preventCaching).toBe(false)
3335
})
3436

3537
it('fetches ubuntu 18.04 latest swift 5.0 tool', async () => {
@@ -46,6 +48,7 @@ describe('fetch linux tool data based on options', () => {
4648
'swift-5.0.3-RELEASE-ubuntu18.04.tar.gz.sig'
4749
)
4850
expect(lTool.docker).toBe('5.0.3-bionic')
51+
expect(lTool.preventCaching).toBe(false)
4952
})
5053

5154
it('fetches ubuntu 18.04 latest swift 5.5.0 tool', async () => {
@@ -62,6 +65,7 @@ describe('fetch linux tool data based on options', () => {
6265
'swift-5.5-RELEASE-ubuntu18.04.tar.gz.sig'
6366
)
6467
expect(lTool.docker).toBe('5.5-bionic')
68+
expect(lTool.preventCaching).toBe(false)
6569
})
6670

6771
it('fetches ubuntu 20.04 arm64 latest swift 5.6.0 tool', async () => {
@@ -79,6 +83,7 @@ describe('fetch linux tool data based on options', () => {
7983
'swift-5.6-RELEASE-ubuntu20.04-aarch64.tar.gz.sig'
8084
)
8185
expect(lTool.docker).toBe('5.6-focal')
86+
expect(lTool.preventCaching).toBe(false)
8287
})
8388

8489
it('fetches ubuntu 18.04 latest swift 5.5 tool', async () => {
@@ -95,6 +100,7 @@ describe('fetch linux tool data based on options', () => {
95100
'swift-5.5.3-RELEASE-ubuntu18.04.tar.gz.sig'
96101
)
97102
expect(lTool.docker).toBe('5.5.3-bionic')
103+
expect(lTool.preventCaching).toBe(false)
98104
})
99105

100106
it('fetches ubuntu 18.04 latest swift 5.5 tool including dev snapshot', async () => {
@@ -111,6 +117,7 @@ describe('fetch linux tool data based on options', () => {
111117
'swift-5.5.3-RELEASE-ubuntu18.04.tar.gz.sig'
112118
)
113119
expect(lTool.docker).toBe('5.5.3-bionic')
120+
expect(lTool.preventCaching).toBe(false)
114121
})
115122

116123
it('fetches ubuntu 18.04 latest swift tool', async () => {
@@ -124,6 +131,7 @@ describe('fetch linux tool data based on options', () => {
124131
expect(lTool.platform).toBeTruthy()
125132
expect(lTool.branch).toBeTruthy()
126133
expect(lTool.download_signature).toBeTruthy()
134+
expect(lTool.preventCaching).toBe(false)
127135
})
128136

129137
it('fetches ubuntu 18.04 latest swift tool including dev snapshot', async () => {
@@ -138,6 +146,7 @@ describe('fetch linux tool data based on options', () => {
138146
expect(lTool.branch).toBeTruthy()
139147
expect(lTool.download_signature).toBeTruthy()
140148
expect(lTool.docker).toBeTruthy()
149+
expect(lTool.preventCaching).toBe(false)
141150
})
142151

143152
it('handles swift tool version not present by returning undefined', async () => {
@@ -163,6 +172,7 @@ describe('fetch linux tool data based on options', () => {
163172
'swift-5.6.1-RELEASE-ubuntu20.04.tar.gz.sig'
164173
)
165174
expect(lTool.docker).toBe('5.6.1-focal')
175+
expect(lTool.preventCaching).toBe(false)
166176
})
167177

168178
it('fetches ubuntu 20.04 latest swift 5.2 tool', async () => {
@@ -180,6 +190,7 @@ describe('fetch linux tool data based on options', () => {
180190
'swift-5.2.5-RELEASE-ubuntu20.04.tar.gz.sig'
181191
)
182192
expect(lTool.docker).toBe('5.2.5-focal')
193+
expect(lTool.preventCaching).toBe(false)
183194
})
184195

185196
it('fetches centos 7 latest swift tool', async () => {
@@ -194,6 +205,7 @@ describe('fetch linux tool data based on options', () => {
194205
expect(lTool.branch).toBeTruthy()
195206
expect(lTool.download_signature).toBeTruthy()
196207
expect(lTool.docker).toBeTruthy()
208+
expect(lTool.preventCaching).toBe(false)
197209
})
198210

199211
it('fetches ubuntu 22.04 named swift tool', async () => {
@@ -213,6 +225,7 @@ describe('fetch linux tool data based on options', () => {
213225
expect(lTool.download_signature).toBe(
214226
'swift-DEVELOPMENT-SNAPSHOT-2023-09-02-a-ubuntu22.04.tar.gz.sig'
215227
)
228+
expect(lTool.preventCaching).toBe(false)
216229
})
217230

218231
it('fetches ubuntu 22.04 named versioned swift tool', async () => {
@@ -232,6 +245,7 @@ describe('fetch linux tool data based on options', () => {
232245
expect(lTool.download_signature).toBe(
233246
'swift-5.9-DEVELOPMENT-SNAPSHOT-2023-09-01-a-ubuntu22.04.tar.gz.sig'
234247
)
248+
expect(lTool.preventCaching).toBe(false)
235249
})
236250

237251
it('fetches ubuntu 18.04 latest swift 5.5 tools', async () => {
@@ -271,4 +285,24 @@ describe('fetch linux tool data based on options', () => {
271285
const tools = await Platform.toolchains(ver5_2)
272286
expect(tools.length).toBe(2)
273287
})
288+
289+
it('fetches ubuntu 22.04 custom swift tools', async () => {
290+
setos({os: 'linux', dist: 'Ubuntu', release: '22.04'})
291+
jest.spyOn(os, 'arch').mockReturnValue('x64')
292+
const swiftwasm = 'https://github.com/swiftwasm/swift/releases/download'
293+
const name = 'swift-wasm-5.10-SNAPSHOT-2024-03-30-a'
294+
const resource = `${name}-ubuntu22.04_x86_64.tar.gz`
295+
const toolchainUrl = `${swiftwasm}/${name}/${resource}`
296+
const cVer = ToolchainVersion.create(toolchainUrl, false)
297+
const tools = await Platform.toolchains(cVer)
298+
expect(tools.length).toBe(1)
299+
const tool = tools[0]
300+
expect(tool.baseUrl?.href).toBe(posix.dirname(toolchainUrl))
301+
expect(tool.preventCaching).toBe(true)
302+
expect(tool.name).toBe('Swift Custom Snapshot')
303+
expect(tool.platform).toBe('ubuntu2204')
304+
expect(tool.download).toBe(resource)
305+
expect(tool.dir).toBe(name)
306+
expect(tool.branch).toBe('swiftwasm')
307+
})
274308
})

0 commit comments

Comments
 (0)