Skip to content

Commit d140b66

Browse files
Basic implementation
1 parent ba19012 commit d140b66

10 files changed

+4403
-231
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ jobs:
2222
- uses: actions/checkout@v3
2323
- uses: ./
2424
with:
25-
milliseconds: 1000
25+
swift-version: wasm-RELEASE-5.7.1

action.yml

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
name: 'Wait'
22
description: 'Wait a designated number of milliseconds'
33
inputs:
4-
milliseconds: # id of input
5-
description: 'number of milliseconds to wait'
4+
swift-version:
5+
description: 'Swift version to configure (default: wasm-RELEASE-5.7.1)'
66
required: true
7-
default: '1000'
8-
outputs:
9-
time: # output will be available to future steps
10-
description: 'The current time after waiting'
7+
default: 'wasm-RELEASE-5.7.1'
118
runs:
129
using: 'node16'
1310
main: 'dist/index.js'

dist/index.js

+4,134-168
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/licenses.txt

+55
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.js

+113-13
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,121 @@
1-
const core = require('@actions/core');
2-
const wait = require('./wait');
1+
const fs = require("fs");
2+
const core = require("@actions/core");
3+
const tc = require("@actions/tool-cache");
4+
const os = require("os");
35

4-
5-
// most @actions toolkit packages have async methods
66
async function run() {
7-
try {
8-
const ms = core.getInput('milliseconds');
9-
core.info(`Waiting ${ms} milliseconds ...`);
7+
const version = resolveVersionInput();
8+
validateVersion(version);
9+
const platform = resolveHostPlatform();
10+
const url = toolchainDownloadUrl(version, platform);
11+
core.debug(`Resolved toolchain download URL: ${url}`);
12+
const toolchainPath = await installToolchain(url, version, platform);
13+
core.addPath(`${toolchainPath}/usr/bin`);
14+
}
1015

11-
core.debug((new Date()).toTimeString()); // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true
12-
await wait(parseInt(ms));
13-
core.info((new Date()).toTimeString());
16+
async function installToolchain(url, version, platform) {
17+
const cachePath = tc.find("swiftwasm", version, platform.arch);
18+
if (cachePath) {
19+
core.debug("Toolchain already installed.");
20+
return cachePath;
21+
}
22+
core.debug(`Downloading tool from ${url}`);
23+
const downloadPath = await tc.downloadTool(url);
24+
core.debug(`Installing toolchain from ${downloadPath}`);
25+
let toolchainPath;
26+
switch (platform.pkg) {
27+
case "tar.gz":
28+
toolchainPath = await tc.extractTar(downloadPath);
29+
break;
30+
case "pkg":
31+
toolchainPath = await tc.extractXar(downloadPath);
32+
break;
33+
default:
34+
throw new Error(`Unsupported package type: ${platform.pkg}`);
35+
}
36+
core.debug(`Installed toolchain to ${toolchainPath}`);
37+
const cachedPath = await tc.cacheDir(toolchainPath, "swiftwasm", version, platform.arch);
38+
return cachedPath;
39+
}
1440

15-
core.setOutput('time', new Date().toTimeString());
16-
} catch (error) {
17-
core.setFailed(error.message);
41+
function resolveVersionInput(options = {}) {
42+
const version = core.getInput('swift-version') || options.version;
43+
if (version) {
44+
core.debug(`Using version from input: ${version}`);
45+
return version;
46+
}
47+
if (fs.existsSync(".swift-version")) {
48+
const versionFile = fs.readFileSync('.swift-version', 'utf8').trim();
49+
if (versionFile !== "") {
50+
core.debug(`Using version from .swift-version file: ${versionFile}`);
51+
return versionFile;
52+
}
1853
}
54+
const message = "No Swift version specified. Please specify a version using the 'swift-version' input or a .swift-version file.";
55+
core.error(message);
56+
throw new Error(message);
57+
}
58+
59+
function validateVersion(version) {
60+
if (version === "") {
61+
throw new Error("Empty version specified.");
62+
}
63+
if (!version.startsWith("wasm-")) {
64+
throw new Error(`Invalid version specified: ${version}. Version must start with 'wasm-'. For example: 'wasm-5.7.1-RELEASE'`);
65+
}
66+
}
67+
68+
function resolveHostPlatform() {
69+
function normalizeOS(platform) {
70+
switch (platform) {
71+
case "linux":
72+
return "linux";
73+
case "darwin":
74+
return "macos";
75+
default:
76+
throw new Error(`Unsupported platform: ${platform}`);
77+
}
78+
}
79+
80+
function normalizeArch(arch) {
81+
switch (arch) {
82+
case "arm64":
83+
return "arm64";
84+
case "x64":
85+
return "x86_64";
86+
default:
87+
throw new Error(`Unsupported architecture: ${arch}`);
88+
}
89+
}
90+
91+
function parseOSRelease() {
92+
const osRelease = fs.readFileSync('/etc/os-release', 'utf8');
93+
const lines = osRelease.split(os.EOL);
94+
const osReleaseMap = {};
95+
for (const line of lines) {
96+
const [key, value] = line.split('=');
97+
osReleaseMap[key] = value.replace(/["]/g, "");
98+
}
99+
return osReleaseMap;
100+
}
101+
102+
const platform = normalizeOS(os.platform());
103+
if (platform === "linux") {
104+
const osRelease = parseOSRelease();
105+
if (osRelease.ID === "ubuntu") {
106+
const arch = normalizeArch(os.arch());
107+
return { suffix: `ubuntu${osRelease.VERSION_ID}_${arch}`, pkg: "tar.gz", arch };
108+
}
109+
} else if (platform === "macos") {
110+
const arch = normalizeArch(os.arch());
111+
return { suffix: `macos_${arch}`, pkg: "pkg", arch };
112+
} else {
113+
throw new Error(`Unsupported platform: ${platform}`);
114+
}
115+
}
116+
117+
function toolchainDownloadUrl(version, platform) {
118+
`https://github.com/swiftwasm/swift/releases/download/swift-${version}/swift-${version}-${platform.suffix}.${platform.pkg}`;
19119
}
20120

21121
run();

index.test.js

+2-23
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
const wait = require('./wait');
2-
const process = require('process');
3-
const cp = require('child_process');
4-
const path = require('path');
5-
6-
test('throws invalid number', async () => {
7-
await expect(wait('foo')).rejects.toThrow('milliseconds not a number');
8-
});
9-
10-
test('wait 500 ms', async () => {
11-
const start = new Date();
12-
await wait(500);
13-
const end = new Date();
14-
var delta = Math.abs(end - start);
15-
expect(delta).toBeGreaterThanOrEqual(500);
16-
});
17-
18-
// shows how the runner will run a javascript action with env / stdout protocol
19-
test('test runs', () => {
20-
process.env['INPUT_MILLISECONDS'] = 100;
21-
const ip = path.join(__dirname, 'index.js');
22-
const result = cp.execSync(`node ${ip}`, {env: process.env}).toString();
23-
console.log(result);
1+
test('noop', () => {
242
})
3+

package-lock.json

+83-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)