Skip to content

Commit

Permalink
feat: added custom toolchains support (#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
soumyamahunt authored Apr 1, 2024
1 parent de12b65 commit dc93ecd
Show file tree
Hide file tree
Showing 33 changed files with 599 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"project": "./tsconfig.json"
"project": [ "./tsconfig.base.json", "./tsconfig.json"]
},
"rules": {
"i18n-text/no-en": "off",
Expand Down
File renamed without changes.
7 changes: 6 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ jobs:
- os: windows-latest
swift: '5.3'
development: false
- os: ubuntu-22.04
swift: ${{ fromJSON(vars.SETUPSWIFT_CUSTOM_TOOLCHAINS).ubuntu2204 }}
development: true
noverify: true

steps:
- name: Checkout repository
Expand Down Expand Up @@ -201,10 +205,11 @@ jobs:
cache-snapshot: ${{ !matrix.development }}

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

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

dry-run:
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ In other words specifying...
- `"4"` will resolve to latest minor and patch version (aka `4.2.4`)
- `"4.0.0"` will resolve to version `4.0`

<details>
<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>

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

> [!IMPORTANT]
> 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.
</details>

### Caveats

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:
Expand Down
41 changes: 39 additions & 2 deletions __tests__/installer/linux.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import os from 'os'
import * as path from 'path'
import {promises as fs} from 'fs'
// @ts-ignore
import {__setos as setos} from 'getos'
import * as core from '@actions/core'
import * as exec from '@actions/exec'
import * as cache from '@actions/cache'
import * as toolCache from '@actions/tool-cache'
import {coerce as parseSemVer} from 'semver'
import {LinuxToolchainInstaller} from '../../src/installer/linux'
import {ToolchainVersion} from '../../src/version'
import {Platform} from '../../src/platform'

describe('linux toolchain installation verification', () => {
const env = process.env
Expand All @@ -17,7 +22,8 @@ describe('linux toolchain installation verification', () => {
dir: 'swift-5.8-RELEASE',
docker: '5.8-jammy',
platform: 'ubuntu2204',
branch: 'swift-5.8-release'
branch: 'swift-5.8-release',
preventCaching: false
}

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

Expand Down Expand Up @@ -127,4 +133,35 @@ describe('linux toolchain installation verification', () => {
const devVersion = await installer.installedSwiftVersion()
expect(devVersion).toBe('5.9-dev')
})

it('tests custom swift tool caching', async () => {
setos({os: 'linux', dist: 'Ubuntu', release: '22.04'})
jest.spyOn(os, 'arch').mockReturnValue('x64')
const swiftwasm = 'https://github.com/swiftwasm/swift/releases/download'
const name = 'swift-wasm-5.10-SNAPSHOT-2024-03-30-a'
const resource = `${name}-ubuntu22.04_x86_64.tar.gz`
const toolchainUrl = `${swiftwasm}/${name}/${resource}`
const cVer = ToolchainVersion.create(toolchainUrl, false)
const download = path.resolve('tool', 'download', 'path')
const extracted = path.resolve('tool', 'extracted', 'path')
const cached = path.resolve('tool', 'cached', 'path')
jest.spyOn(core, 'getBooleanInput').mockReturnValue(true)
jest.spyOn(cache, 'restoreCache').mockResolvedValue(undefined)
jest.spyOn(toolCache, 'find').mockReturnValue('')
jest.spyOn(fs, 'cp').mockResolvedValue()
jest.spyOn(toolCache, 'downloadTool').mockResolvedValue(download)
jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted)
jest.spyOn(toolCache, 'cacheDir').mockResolvedValue(cached)
jest.spyOn(exec, 'exec').mockResolvedValue(0)
const cacheSpy = jest.spyOn(cache, 'saveCache')
const installer = await Platform.install(cVer)
expect(cacheSpy).not.toHaveBeenCalled()
expect(installer.data.baseUrl?.href).toBe(path.posix.dirname(toolchainUrl))
expect(installer.data.preventCaching).toBe(true)
expect(installer.data.name).toBe('Swift Custom Snapshot')
expect(installer.data.platform).toBe('ubuntu2204')
expect(installer.data.download).toBe(resource)
expect(installer.data.dir).toBe(name)
expect(installer.data.branch).toBe('swiftwasm')
})
})
5 changes: 3 additions & 2 deletions __tests__/installer/windows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ describe('windows toolchain installation verification', () => {
dir: 'swift-5.8-RELEASE',
platform: 'windows10',
branch: 'swift-5.8-release',
windows: true
windows: true,
preventCaching: false
}
const visualStudio = VisualStudio.createFromJSON({
installationPath: path.join('C:', 'Visual Studio'),
Expand Down Expand Up @@ -61,7 +62,7 @@ describe('windows toolchain installation verification', () => {
it('tests download without caching', async () => {
const installer = new WindowsToolchainInstaller(toolchain)
expect(installer['version']).toStrictEqual(parseSemVer('5.8'))
expect(installer['baseUrl']).toBe(
expect(installer['baseUrl'].href).toBe(
'https://download.swift.org/swift-5.8-release/windows10/swift-5.8-RELEASE'
)

Expand Down
7 changes: 4 additions & 3 deletions __tests__/installer/xcode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ describe('macOS toolchain installation verification', () => {
name: 'Xcode Swift 5.8.1',
date: new Date('2023-05-31T18:30:00.000Z'),
download: 'swift-5.8.1-RELEASE-osx.pkg',
symbols: 'swift-5.8.1-RELEASE-osx-symbols.pkg',
debug_info: 'swift-5.8.1-RELEASE-osx-symbols.pkg',
dir: 'swift-5.8.1-RELEASE',
xcode: '14.3.1',
platform: 'xcode',
branch: 'swift-5.8.1-release',
xcodePath: '/Applications/Xcode_14.3.1.app'
xcodePath: '/Applications/Xcode_14.3.1.app',
preventCaching: false
}

beforeEach(() => {
Expand Down Expand Up @@ -56,7 +57,7 @@ describe('macOS toolchain installation verification', () => {
it('tests download', async () => {
const installer = new XcodeToolchainInstaller(toolchain)
expect(installer['version']).toStrictEqual(parseSemVer('5.8.1'))
expect(installer['baseUrl']).toBe(
expect(installer['baseUrl'].href).toBe(
'https://download.swift.org/swift-5.8.1-release/xcode/swift-5.8.1-RELEASE'
)

Expand Down
3 changes: 2 additions & 1 deletion __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ describe('setup-swift run validation', () => {
dir: 'swift-5.8-RELEASE',
docker: '5.8-jammy',
platform: 'ubuntu2204',
branch: 'swift-5.8-release'
branch: 'swift-5.8-release',
preventCaching: false
}

it('tests dry run', async () => {
Expand Down
34 changes: 34 additions & 0 deletions __tests__/snapshot/linux.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os from 'os'
import {posix} from 'path'
// @ts-ignore
import {__setos as setos} from 'getos'
import {ToolchainVersion} from '../../src/version'
Expand Down Expand Up @@ -30,6 +31,7 @@ describe('fetch linux tool data based on options', () => {
'swift-4.2.4-RELEASE-ubuntu18.04.tar.gz.sig'
)
expect(lTool.docker).toBeUndefined()
expect(lTool.preventCaching).toBe(false)
})

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

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

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

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

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

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

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

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

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

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

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

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

it('fetches ubuntu 18.04 latest swift 5.5 tools', async () => {
Expand Down Expand Up @@ -271,4 +285,24 @@ describe('fetch linux tool data based on options', () => {
const tools = await Platform.toolchains(ver5_2)
expect(tools.length).toBe(2)
})

it('fetches ubuntu 22.04 custom swift tools', async () => {
setos({os: 'linux', dist: 'Ubuntu', release: '22.04'})
jest.spyOn(os, 'arch').mockReturnValue('x64')
const swiftwasm = 'https://github.com/swiftwasm/swift/releases/download'
const name = 'swift-wasm-5.10-SNAPSHOT-2024-03-30-a'
const resource = `${name}-ubuntu22.04_x86_64.tar.gz`
const toolchainUrl = `${swiftwasm}/${name}/${resource}`
const cVer = ToolchainVersion.create(toolchainUrl, false)
const tools = await Platform.toolchains(cVer)
expect(tools.length).toBe(1)
const tool = tools[0]
expect(tool.baseUrl?.href).toBe(posix.dirname(toolchainUrl))
expect(tool.preventCaching).toBe(true)
expect(tool.name).toBe('Swift Custom Snapshot')
expect(tool.platform).toBe('ubuntu2204')
expect(tool.download).toBe(resource)
expect(tool.dir).toBe(name)
expect(tool.branch).toBe('swiftwasm')
})
})
Loading

0 comments on commit dc93ecd

Please sign in to comment.