Skip to content

Commit 578ae21

Browse files
committed
feat: add support for GitHub Actions cache
1 parent d9b8ef6 commit 578ae21

File tree

10 files changed

+1635
-31
lines changed

10 files changed

+1635
-31
lines changed

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ inputs:
2626
description: 'Just install GoReleaser'
2727
default: 'false'
2828
required: false
29+
cache-binary:
30+
description: 'Cache binary to GitHub Actions cache backend'
31+
default: 'false'
32+
required: false
2933

3034
outputs:
3135
artifacts:

dist/index.js

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

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/licenses.txt

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

dist/sourcemap-register.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"license": "MIT",
2727
"packageManager": "[email protected]",
2828
"dependencies": {
29+
"@actions/cache": "^4.1.0",
2930
"@actions/core": "^1.11.1",
3031
"@actions/exec": "^1.1.1",
3132
"@actions/http-client": "^2.2.3",

src/context.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface Inputs {
1010
args: string;
1111
workdir: string;
1212
installOnly: boolean;
13+
cacheBinary: boolean;
1314
}
1415

1516
export async function getInputs(): Promise<Inputs> {
@@ -18,6 +19,7 @@ export async function getInputs(): Promise<Inputs> {
1819
version: core.getInput('version') || '~> v2',
1920
args: core.getInput('args'),
2021
workdir: core.getInput('workdir') || '.',
21-
installOnly: core.getBooleanInput('install-only')
22+
installOnly: core.getBooleanInput('install-only'),
23+
cacheBinary: core.getBooleanInput('cache-binary')
2224
};
2325
}

src/goreleaser.ts

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import * as context from './context';
66
import * as github from './github';
77
import * as core from '@actions/core';
88
import * as tc from '@actions/tool-cache';
9+
import * as cache from '@actions/cache';
910

10-
export async function install(distribution: string, version: string): Promise<string> {
11+
export async function install(distribution: string, version: string, cacheBinary?: boolean): Promise<string> {
1112
const release: github.GitHubRelease = await github.getRelease(distribution, version);
13+
const semver: string = release.tag_name.replace(/^v/, '');
1214
const filename = getFilename(distribution);
1315
const downloadUrl = util.format(
1416
'https://github.com/goreleaser/%s/releases/download/%s/%s',
@@ -17,19 +19,34 @@ export async function install(distribution: string, version: string): Promise<st
1719
filename
1820
);
1921

20-
const toolPath: string = tc.find('goreleaser-action', release.tag_name.replace(/^v/, ''), context.osArch);
22+
const toolPath: string = tc.find('goreleaser-action', semver, context.osArch);
2123
if (toolPath) {
2224
core.info(`Found in cache @ ${toolPath}`);
23-
const exePath: string = path.join(toolPath, context.osPlat == 'win32' ? 'goreleaser.exe' : 'goreleaser');
25+
const exePath: string = getExePath(toolPath);
2426
try {
2527
// return path only after confirming it exists and is executable
26-
await fs.promises.access(exePath, fs.constants.F_OK | fs.constants.X_OK)
28+
await fs.promises.access(exePath, fs.constants.F_OK | fs.constants.X_OK);
2729
return exePath;
2830
} catch (err) {
2931
core.warning(`Cached tool directory found but executable is not accessible or not executable: ${err.message}`);
3032
}
3133
}
3234

35+
const goreleaserHome = path.join(process.env.HOME, '.goreleaser');
36+
if (!fs.existsSync(goreleaserHome)) {
37+
fs.mkdirSync(goreleaserHome, {recursive: true});
38+
}
39+
40+
if (cacheBinary && cache.isFeatureAvailable()) {
41+
core.debug(`GitHub actions cache feature available`);
42+
const cacheKey = await cache.restoreCache([getExePath(goreleaserHome)], getCacheKey(semver));
43+
if (cacheKey) {
44+
core.info(`Restored ${cacheKey} from GitHub actions cache`);
45+
const cachePath: string = await tc.cacheDir(goreleaserHome, 'goreleaser-action', semver);
46+
return getExePath(cachePath);
47+
}
48+
}
49+
3350
core.info(`Downloading ${downloadUrl}`);
3451
const downloadPath: string = await tc.downloadTool(downloadUrl);
3552
core.debug(`Downloaded to ${downloadPath}`);
@@ -40,22 +57,23 @@ export async function install(distribution: string, version: string): Promise<st
4057
if (!downloadPath.endsWith('.zip')) {
4158
const newPath = downloadPath + '.zip';
4259
fs.renameSync(downloadPath, newPath);
43-
extPath = await tc.extractZip(newPath);
60+
extPath = await tc.extractZip(newPath, goreleaserHome);
4461
} else {
45-
extPath = await tc.extractZip(downloadPath);
62+
extPath = await tc.extractZip(downloadPath, goreleaserHome);
4663
}
4764
} else {
48-
extPath = await tc.extractTar(downloadPath);
65+
extPath = await tc.extractTar(downloadPath, goreleaserHome);
4966
}
5067
core.debug(`Extracted to ${extPath}`);
5168

52-
const cachePath: string = await tc.cacheDir(extPath, 'goreleaser-action', release.tag_name.replace(/^v/, ''));
69+
const cachePath: string = await tc.cacheDir(extPath, 'goreleaser-action', semver);
5370
core.debug(`Cached to ${cachePath}`);
71+
if (cacheBinary && cache.isFeatureAvailable()) {
72+
core.debug(`Caching to GitHub actions cache`);
73+
await cache.saveCache([getExePath(goreleaserHome)], getCacheKey(semver));
74+
}
5475

55-
const exePath: string = path.join(cachePath, context.osPlat == 'win32' ? 'goreleaser.exe' : 'goreleaser');
56-
core.debug(`Exe path is ${exePath}`);
57-
58-
return exePath;
76+
return getExePath(cachePath);
5977
}
6078

6179
export const distribSuffix = (distribution: string): string => {
@@ -125,3 +143,14 @@ export async function getMetadata(distpath: string): Promise<string | undefined>
125143
}
126144
return content;
127145
}
146+
147+
const getCacheKey = (semver: string): string => {
148+
return util.format('goreleaser-cache-%s', semver);
149+
};
150+
151+
const getExePath = (basePath: string): string => {
152+
const exePath: string = path.join(basePath, context.osPlat == 'win32' ? 'goreleaser.exe' : 'goreleaser');
153+
core.debug(`Exe path is ${exePath}`);
154+
155+
return exePath;
156+
};

src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as exec from '@actions/exec';
99
async function run(): Promise<void> {
1010
try {
1111
const inputs: context.Inputs = await context.getInputs();
12-
const bin = await goreleaser.install(inputs.distribution, inputs.version);
12+
const bin = await goreleaser.install(inputs.distribution, inputs.version, inputs.cacheBinary);
1313
core.info(`GoReleaser ${inputs.version} installed successfully`);
1414

1515
if (inputs.installOnly) {

0 commit comments

Comments
 (0)