Skip to content

Commit 1ff5e89

Browse files
authored
feat: build from source (#12)
* refactor * fix * impl * fix * debug * fix * fix
1 parent 44cd3f0 commit 1ff5e89

File tree

5 files changed

+143
-63
lines changed

5 files changed

+143
-63
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ jobs:
2727

2828
test-default:
2929
strategy:
30+
fail-fast: false
3031
matrix:
3132
os:
3233
- ubuntu-latest
34+
- ubuntu-24.04-arm
3335
- macos-latest
36+
- macos-13
3437
- windows-latest
3538
runs-on: ${{ matrix.os }}
3639
steps:
@@ -40,10 +43,13 @@ jobs:
4043

4144
test-locked:
4245
strategy:
46+
fail-fast: false
4347
matrix:
4448
os:
4549
- ubuntu-latest
50+
- ubuntu-24.04-arm
4651
- macos-latest
52+
- macos-13
4753
- windows-latest
4854
version:
4955
- "24.12.23"
@@ -65,10 +71,13 @@ jobs:
6571
6672
test-range:
6773
strategy:
74+
fail-fast: false
6875
matrix:
6976
os:
7077
- ubuntu-latest
78+
- ubuntu-24.04-arm
7179
- macos-latest
80+
- macos-13
7281
- windows-latest
7382
version:
7483
- ["24.*", "24.12.23"]

deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
],
66
"imports": {
77
"@actions/core": "npm:@actions/core@^1.11.1",
8+
"@actions/exec": "npm:@actions/exec@^1.1.1",
89
"@actions/tool-cache": "npm:@actions/tool-cache@^2.0.2",
910
"@deno/dnt": "jsr:@deno/dnt@^0.41.3",
1011
"@std/semver": "jsr:@std/semver@^1.0.3",

deno.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/main.js

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19430,7 +19430,7 @@ var require_exec = __commonJS({
1943019430
exports2.getExecOutput = exports2.exec = void 0;
1943119431
var string_decoder_1 = require("string_decoder");
1943219432
var tr = __importStar2(require_toolrunner());
19433-
function exec(commandLine, args, options) {
19433+
function exec2(commandLine, args, options) {
1943419434
return __awaiter(this, void 0, void 0, function* () {
1943519435
const commandArgs = tr.argStringToArray(commandLine);
1943619436
if (commandArgs.length === 0) {
@@ -19442,7 +19442,7 @@ var require_exec = __commonJS({
1944219442
return runner.exec();
1944319443
});
1944419444
}
19445-
exports2.exec = exec;
19445+
exports2.exec = exec2;
1944619446
function getExecOutput(commandLine, args, options) {
1944719447
var _a, _b;
1944819448
return __awaiter(this, void 0, void 0, function* () {
@@ -19465,7 +19465,7 @@ var require_exec = __commonJS({
1946519465
}
1946619466
};
1946719467
const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
19468-
const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
19468+
const exitCode = yield exec2(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
1946919469
stdout += stdoutDecoder.end();
1947019470
stderr += stderrDecoder.end();
1947119471
return {
@@ -19543,12 +19543,12 @@ var require_platform = __commonJS({
1954319543
Object.defineProperty(exports2, "__esModule", { value: true });
1954419544
exports2.getDetails = exports2.isLinux = exports2.isMacOS = exports2.isWindows = exports2.arch = exports2.platform = void 0;
1954519545
var os_1 = __importDefault(require("os"));
19546-
var exec = __importStar2(require_exec());
19546+
var exec2 = __importStar2(require_exec());
1954719547
var getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
19548-
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', void 0, {
19548+
const { stdout: version } = yield exec2.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', void 0, {
1954919549
silent: true
1955019550
});
19551-
const { stdout: name } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', void 0, {
19551+
const { stdout: name } = yield exec2.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', void 0, {
1955219552
silent: true
1955319553
});
1955419554
return {
@@ -19558,7 +19558,7 @@ var require_platform = __commonJS({
1955819558
});
1955919559
var getMacOsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
1956019560
var _a, _b, _c, _d;
19561-
const { stdout } = yield exec.getExecOutput("sw_vers", void 0, {
19561+
const { stdout } = yield exec2.getExecOutput("sw_vers", void 0, {
1956219562
silent: true
1956319563
});
1956419564
const version = (_b = (_a = stdout.match(/ProductVersion:\s*(.+)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : "";
@@ -19569,7 +19569,7 @@ var require_platform = __commonJS({
1956919569
};
1957019570
});
1957119571
var getLinuxInfo = () => __awaiter(void 0, void 0, void 0, function* () {
19572-
const { stdout } = yield exec.getExecOutput("lsb_release", ["-i", "-r", "-s"], {
19572+
const { stdout } = yield exec2.getExecOutput("lsb_release", ["-i", "-r", "-s"], {
1957319573
silent: true
1957419574
});
1957519575
const [name, version] = stdout.trim().split("\n");
@@ -31492,6 +31492,7 @@ var __importStar = exports && exports.__importStar || function(mod) {
3149231492
Object.defineProperty(exports, "__esModule", { value: true });
3149331493
require_dnt_polyfills();
3149431494
var core = __importStar(require_core());
31495+
var exec = __importStar(require_exec());
3149531496
var tc = __importStar(require_tool_cache());
3149631497
var semver = __importStar(require_mod());
3149731498
var octokit_1 = (init_dist_bundle14(), __toCommonJS(dist_bundle_exports3));
@@ -31531,40 +31532,67 @@ async function resolveVersion(gh, version) {
3153131532
}
3153231533
throw new Error(`Invalid version: ${version}`);
3153331534
}
31534-
async function getDownloadUrl(gh, version) {
31535+
async function downloadFlatc(gh, version) {
31536+
const platformDetails = await core.platform.getDetails();
31537+
core.info(JSON.stringify(platformDetails));
3153531538
const platformMap = {
31536-
linux: /Linux\.flatc\.binary\.g\+\+-\d+\.zip/,
31537-
darwin: /Mac\.flatc\.binary\.zip/,
31538-
win32: /Windows\.flatc\.binary\.zip/
31539+
"linux-x64": /Linux\.flatc\.binary\.g\+\+-\d+\.zip/,
31540+
"darwin-arm64": /Mac\.flatc\.binary\.zip/,
31541+
"darwin-x64": /MacIntel\.flatc\.binary\.zip/,
31542+
"win32-x64": /Windows\.flatc\.binary\.zip/
3153931543
};
31540-
const fileRegex = platformMap[core.platform.platform];
31541-
if (!fileRegex) {
31542-
throw new Error(`Unsupported platform: ${core.platform.platform}`);
31543-
}
31544+
const key = `${platformDetails.platform}-${platformDetails.arch}`;
31545+
const fileRegex = platformMap[key];
3154431546
const resp = await gh.rest.repos.getReleaseByTag({
3154531547
owner: "google",
3154631548
repo: "flatbuffers",
3154731549
tag: `v${version}`
3154831550
});
31549-
for (const asset of resp.data.assets) {
31550-
if (fileRegex.test(asset.name)) {
31551-
return asset.browser_download_url;
31552-
}
31551+
if (fileRegex) {
31552+
let url = null;
31553+
for (const asset of resp.data.assets) {
31554+
if (fileRegex.test(asset.name)) {
31555+
url = asset.browser_download_url;
31556+
}
31557+
}
31558+
if (!url) {
31559+
throw new Error("No matching asset found for platform");
31560+
}
31561+
core.info(`Downloading URL: ${url}`);
31562+
const downloadPath = await tc.downloadTool(url);
31563+
core.info(`Downloaded to: ${downloadPath}`);
31564+
const extractPath = await tc.extractZip(downloadPath);
31565+
core.info(`Extracted to: ${extractPath}`);
31566+
return await tc.cacheDir(extractPath, "flatc", version);
31567+
} else {
31568+
const url = resp.data.tarball_url;
31569+
if (!url) {
31570+
throw new Error("No tarball found for platform");
31571+
}
31572+
core.info(`Downloading URL: ${url}`);
31573+
const downloadPath = await tc.downloadTool(url);
31574+
core.info(`Downloaded to: ${downloadPath}`);
31575+
const extractPath = await tc.extractTar(downloadPath);
31576+
core.info(`Extracted to: ${extractPath}`);
31577+
const sourcePath = extractPath + "/" + (await ls(extractPath)).trim();
31578+
core.info("Building flatc from source");
31579+
await exec.exec("cmake", ["-G", "Unix Makefiles"], { cwd: sourcePath });
31580+
await exec.exec("make", ["-j"], { cwd: sourcePath });
31581+
core.info("Built flatc from source");
31582+
return await tc.cacheDir(sourcePath, "flatc", version);
3155331583
}
31554-
throw new Error("No matching asset found for platform");
3155531584
}
31556-
async function downloadFlatc(version, url) {
31557-
let cachedPath = tc.find("flatc", version);
31558-
if (cachedPath) {
31559-
return cachedPath;
31560-
}
31561-
core.info(`Downloading URL: ${url}`);
31562-
const downloadPath = await tc.downloadTool(url);
31563-
core.info(`Downloaded to: ${downloadPath}`);
31564-
const extractPath = await tc.extractZip(downloadPath);
31565-
core.info(`Extracted to: ${extractPath}`);
31566-
cachedPath = await tc.cacheDir(extractPath, "flatc", version);
31567-
return cachedPath;
31585+
async function ls(path) {
31586+
let stdout = "";
31587+
const options = {
31588+
listeners: {
31589+
stdout: (data) => {
31590+
stdout += data.toString();
31591+
}
31592+
}
31593+
};
31594+
await exec.exec("ls", [path], options);
31595+
return stdout;
3156831596
}
3156931597
async function main() {
3157031598
const githubToken = core.getInput("github-token") ?? void 0;
@@ -31573,8 +31601,10 @@ async function main() {
3157331601
core.info(`Input version: ${inputVersion}`);
3157431602
const version = await resolveVersion(gh, inputVersion);
3157531603
core.info(`Resolved version: ${version}`);
31576-
const url = await getDownloadUrl(gh, version);
31577-
const cachedPath = await downloadFlatc(version, url);
31604+
let cachedPath = tc.find("flatc", version);
31605+
if (!cachedPath) {
31606+
cachedPath = await downloadFlatc(gh, version);
31607+
}
3157831608
core.info(`Cached at: ${cachedPath}`);
3157931609
core.addPath(cachedPath);
3158031610
core.info("Added cached path to environment variables");

src/main.ts

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import * as core from "@actions/core";
2+
import * as exec from "@actions/exec";
23
import * as tc from "@actions/tool-cache";
34
import * as semver from "@std/semver";
45
import { Octokit } from "octokit";
6+
import type { Buffer } from "node:buffer";
57

68
async function resolveVersion(gh: Octokit, version: string): Promise<string> {
79
if (version === "*") {
@@ -43,47 +45,81 @@ async function resolveVersion(gh: Octokit, version: string): Promise<string> {
4345
throw new Error(`Invalid version: ${version}`);
4446
}
4547

46-
async function getDownloadUrl(gh: Octokit, version: string): Promise<string> {
48+
async function downloadFlatc(gh: Octokit, version: string): Promise<string> {
49+
// https://github.com/actions/toolkit/tree/main/packages/core#platform-helper
50+
const platformDetails = await core.platform.getDetails();
51+
core.info(JSON.stringify(platformDetails));
52+
4753
const platformMap: Record<string, RegExp | undefined> = {
48-
linux: /Linux\.flatc\.binary\.g\+\+-\d+\.zip/,
49-
darwin: /Mac\.flatc\.binary\.zip/,
50-
win32: /Windows\.flatc\.binary\.zip/,
54+
"linux-x64": /Linux\.flatc\.binary\.g\+\+-\d+\.zip/,
55+
"darwin-arm64": /Mac\.flatc\.binary\.zip/,
56+
"darwin-x64": /MacIntel\.flatc\.binary\.zip/,
57+
"win32-x64": /Windows\.flatc\.binary\.zip/,
5158
};
5259

53-
const fileRegex = platformMap[core.platform.platform];
54-
if (!fileRegex) {
55-
throw new Error(`Unsupported platform: ${core.platform.platform}`);
56-
}
60+
const key = `${platformDetails.platform}-${platformDetails.arch}`;
61+
const fileRegex = platformMap[key];
5762

5863
const resp = await gh.rest.repos.getReleaseByTag({
5964
owner: "google",
6065
repo: "flatbuffers",
6166
tag: `v${version}`,
6267
});
6368

64-
for (const asset of resp.data.assets) {
65-
if (fileRegex.test(asset.name)) {
66-
return asset.browser_download_url;
69+
if (fileRegex) {
70+
let url: string | null = null;
71+
for (const asset of resp.data.assets) {
72+
if (fileRegex.test(asset.name)) {
73+
url = asset.browser_download_url;
74+
}
75+
}
76+
if (!url) {
77+
throw new Error("No matching asset found for platform");
6778
}
68-
}
69-
throw new Error("No matching asset found for platform");
70-
}
7179

72-
async function downloadFlatc(version: string, url: string): Promise<string> {
73-
let cachedPath = tc.find("flatc", version);
74-
if (cachedPath) {
75-
return cachedPath;
76-
}
80+
core.info(`Downloading URL: ${url}`);
81+
const downloadPath = await tc.downloadTool(url);
82+
core.info(`Downloaded to: ${downloadPath}`);
7783

78-
core.info(`Downloading URL: ${url}`);
79-
const downloadPath = await tc.downloadTool(url);
80-
core.info(`Downloaded to: ${downloadPath}`);
84+
const extractPath = await tc.extractZip(downloadPath);
85+
core.info(`Extracted to: ${extractPath}`);
86+
87+
return await tc.cacheDir(extractPath, "flatc", version);
88+
} else {
89+
const url = resp.data.tarball_url;
90+
if (!url) {
91+
throw new Error("No tarball found for platform");
92+
}
8193

82-
const extractPath = await tc.extractZip(downloadPath);
83-
core.info(`Extracted to: ${extractPath}`);
94+
core.info(`Downloading URL: ${url}`);
95+
const downloadPath = await tc.downloadTool(url);
96+
core.info(`Downloaded to: ${downloadPath}`);
8497

85-
cachedPath = await tc.cacheDir(extractPath, "flatc", version);
86-
return cachedPath;
98+
const extractPath = await tc.extractTar(downloadPath);
99+
core.info(`Extracted to: ${extractPath}`);
100+
101+
const sourcePath = extractPath + "/" + (await ls(extractPath)).trim();
102+
103+
core.info("Building flatc from source");
104+
await exec.exec("cmake", ["-G", "Unix Makefiles"], { cwd: sourcePath });
105+
await exec.exec("make", ["-j"], { cwd: sourcePath });
106+
core.info("Built flatc from source");
107+
108+
return await tc.cacheDir(sourcePath, "flatc", version);
109+
}
110+
}
111+
112+
async function ls(path: string): Promise<string> {
113+
let stdout = "";
114+
const options = {
115+
listeners: {
116+
stdout: (data: Buffer) => {
117+
stdout += data.toString();
118+
},
119+
},
120+
};
121+
await exec.exec("ls", [path], options);
122+
return stdout;
87123
}
88124

89125
async function main() {
@@ -96,8 +132,10 @@ async function main() {
96132
const version = await resolveVersion(gh, inputVersion);
97133
core.info(`Resolved version: ${version}`);
98134

99-
const url = await getDownloadUrl(gh, version);
100-
const cachedPath = await downloadFlatc(version, url);
135+
let cachedPath = tc.find("flatc", version);
136+
if (!cachedPath) {
137+
cachedPath = await downloadFlatc(gh, version);
138+
}
101139
core.info(`Cached at: ${cachedPath}`);
102140

103141
core.addPath(cachedPath);

0 commit comments

Comments
 (0)