mirror of
https://github.com/goreleaser/goreleaser-action
synced 2026-08-29 20:38:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a80836c5c | ||
|
|
a71152e827 | ||
|
|
4c6ab561ad | ||
|
|
4f96abf297 | ||
|
|
15fa2a96d4 |
@@ -242,6 +242,8 @@ jobs:
|
|||||||
install-only: true
|
install-only: true
|
||||||
distribution: ${{ matrix.distribution }}
|
distribution: ${{ matrix.distribution }}
|
||||||
version: nightly
|
version: nightly
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: Check
|
name: Check
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Test
|
name: Test
|
||||||
run: npm test
|
run: npm test
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: Upload coverage
|
name: Upload coverage
|
||||||
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ checksums file against the GoReleaser release workflow's OIDC identity. If
|
|||||||
> versions the cosign step is silently skipped — only the `checksums.txt`
|
> versions the cosign step is silently skipped — only the `checksums.txt`
|
||||||
> SHA-256 verification runs.
|
> SHA-256 verification runs.
|
||||||
|
|
||||||
|
> **Note**: when `version: nightly` is used, the action resolves the
|
||||||
|
> latest immutable `vX.Y.Z-<sha>-nightly` release from the GitHub
|
||||||
|
> Releases API. Pass `GITHUB_TOKEN` to the action step (as in the example
|
||||||
|
> above) to avoid unauthenticated API rate limits.
|
||||||
|
|
||||||
To enable signature verification, install cosign before running the action:
|
To enable signature verification, install cosign before running the action:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -222,11 +227,28 @@ Following inputs can be used as `step.with` keys
|
|||||||
|------------------|---------|--------------|------------------------------------------------------------------|
|
|------------------|---------|--------------|------------------------------------------------------------------|
|
||||||
| `distribution` | String | `goreleaser` | GoReleaser distribution, either `goreleaser` or `goreleaser-pro` |
|
| `distribution` | String | `goreleaser` | GoReleaser distribution, either `goreleaser` or `goreleaser-pro` |
|
||||||
| `version`**¹** | String | `~> v2` | GoReleaser version |
|
| `version`**¹** | String | `~> v2` | GoReleaser version |
|
||||||
|
| `version-file`**²** | String | | Read the GoReleaser version from a file (see below) |
|
||||||
| `args` | String | | Arguments to pass to GoReleaser |
|
| `args` | String | | Arguments to pass to GoReleaser |
|
||||||
| `workdir` | String | `.` | Working directory (below repository root) |
|
| `workdir` | String | `.` | Working directory (below repository root) |
|
||||||
| `install-only` | Bool | `false` | Just install GoReleaser |
|
| `install-only` | Bool | `false` | Just install GoReleaser |
|
||||||
|
|
||||||
> **¹** Can be a fixed version like `v0.117.0` or a max satisfying semver one like `~> 0.132`. In this case this will return `v0.132.1`.
|
> **¹** Can be a fixed version like `v0.117.0` or a max satisfying semver one like `~> 0.132`. In this case this will return `v0.132.1`.
|
||||||
|
>
|
||||||
|
> **²** Path to a file containing the GoReleaser version. Resolved relative
|
||||||
|
> to `workdir`. Currently only [`.tool-versions`](https://asdf-vm.com/manage/configuration.html#tool-versions)
|
||||||
|
> (asdf/mise) format is supported. When set, this takes precedence over `version`.
|
||||||
|
>
|
||||||
|
> ```yaml
|
||||||
|
> # .tool-versions
|
||||||
|
> goreleaser 2.13.0
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> ```yaml
|
||||||
|
> - uses: goreleaser/goreleaser-action@v7
|
||||||
|
> with:
|
||||||
|
> version-file: .tool-versions
|
||||||
|
> args: release --clean
|
||||||
|
> ```
|
||||||
|
|
||||||
### outputs
|
### outputs
|
||||||
|
|
||||||
|
|||||||
@@ -56,16 +56,16 @@ describe('getRelease', () => {
|
|||||||
expect(release?.tag_name).not.toEqual('');
|
expect(release?.tag_name).not.toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns nightly GoReleaser GitHub release', async () => {
|
it('resolves nightly to a <version>-<sha>-nightly release for OSS GoReleaser', async () => {
|
||||||
const release = await github.getRelease('goreleaser', 'nightly');
|
const release = await github.getRelease('goreleaser', 'nightly');
|
||||||
expect(release).not.toBeNull();
|
expect(release).not.toBeNull();
|
||||||
expect(release?.tag_name).not.toEqual('');
|
expect(release.tag_name).toMatch(github.nightlyTagRegex);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns nightly GoReleaser Pro GitHub release', async () => {
|
it('resolves nightly to a <version>-<sha>-nightly release for GoReleaser Pro', async () => {
|
||||||
const release = await github.getRelease('goreleaser-pro', 'nightly');
|
const release = await github.getRelease('goreleaser-pro', 'nightly');
|
||||||
expect(release).not.toBeNull();
|
expect(release).not.toBeNull();
|
||||||
expect(release?.tag_name).not.toEqual('');
|
expect(release.tag_name).toMatch(github.nightlyTagRegex);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns v0.182.0 GoReleaser Pro GitHub release', async () => {
|
it('returns v0.182.0 GoReleaser Pro GitHub release', async () => {
|
||||||
|
|||||||
@@ -16,11 +16,38 @@ describe('install', () => {
|
|||||||
expect(fs.existsSync(bin)).toBe(true);
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
|
// The following pinned versions exercise install across release eras to
|
||||||
|
// guard against regressions in checksum handling and the cosign skip path:
|
||||||
|
// - v0.182.0 : pre-checksums-signing era
|
||||||
|
// - v1.26.2 : cosign v2 detached `.sig` only
|
||||||
|
// - v2.12.4 : last release before sigstore bundles (cosign skipped)
|
||||||
|
// - v2.13.0 : first release with cosign v3 sigstore bundle
|
||||||
|
// - v2.15.3 : recent release with sigstore bundle
|
||||||
|
it('acquires v0.182.0 (pre-signing) version of GoReleaser', async () => {
|
||||||
|
const bin = await goreleaser.install('goreleaser', 'v0.182.0');
|
||||||
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('acquires v1.26.2 (cosign v2 .sig) version of GoReleaser', async () => {
|
||||||
|
const bin = await goreleaser.install('goreleaser', 'v1.26.2');
|
||||||
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('acquires v2.12.4 (last pre-sigstore-bundle) version of GoReleaser', async () => {
|
||||||
|
const bin = await goreleaser.install('goreleaser', 'v2.12.4');
|
||||||
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
it('acquires v2.13.0 (minimum cosign-verifiable) version of GoReleaser', async () => {
|
it('acquires v2.13.0 (minimum cosign-verifiable) version of GoReleaser', async () => {
|
||||||
const bin = await goreleaser.install('goreleaser', 'v2.13.0');
|
const bin = await goreleaser.install('goreleaser', 'v2.13.0');
|
||||||
expect(fs.existsSync(bin)).toBe(true);
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
|
it('acquires v2.15.3 (recent sigstore-bundle) version of GoReleaser', async () => {
|
||||||
|
const bin = await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
it('acquires latest v2 version of GoReleaser Pro', async () => {
|
it('acquires latest v2 version of GoReleaser Pro', async () => {
|
||||||
const bin = await goreleaser.install('goreleaser-pro', '~> v2');
|
const bin = await goreleaser.install('goreleaser-pro', '~> v2');
|
||||||
expect(fs.existsSync(bin)).toBe(true);
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
@@ -77,14 +104,14 @@ describe('getCertificateIdentity', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses nightly-oss.yml@refs/heads/main for OSS nightly', () => {
|
it('uses nightly-oss.yml@refs/heads/main for OSS nightly tag', () => {
|
||||||
expect(goreleaser.getCertificateIdentity('goreleaser', 'nightly')).toEqual(
|
expect(goreleaser.getCertificateIdentity('goreleaser', 'v2.16.0-abc1234-nightly')).toEqual(
|
||||||
'https://github.com/goreleaser/goreleaser/.github/workflows/nightly-oss.yml@refs/heads/main'
|
'https://github.com/goreleaser/goreleaser/.github/workflows/nightly-oss.yml@refs/heads/main'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses nightly-pro.yml@refs/heads/main for Pro nightly', () => {
|
it('uses nightly-pro.yml@refs/heads/main for Pro nightly tag', () => {
|
||||||
expect(goreleaser.getCertificateIdentity('goreleaser-pro', 'nightly')).toEqual(
|
expect(goreleaser.getCertificateIdentity('goreleaser-pro', 'v2.16.0-eaeb08c50-nightly')).toEqual(
|
||||||
'https://github.com/goreleaser/goreleaser-pro-internal/.github/workflows/nightly-pro.yml@refs/heads/main'
|
'https://github.com/goreleaser/goreleaser-pro-internal/.github/workflows/nightly-pro.yml@refs/heads/main'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -112,6 +139,14 @@ describe('verifyChecksum', () => {
|
|||||||
expect(fs.existsSync(bin)).toBe(true);
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
|
it('installs a pre-v2.13 release (no sigstore bundle) without failing when cosign is present', async () => {
|
||||||
|
// v2.12.x is the last release that did NOT publish checksums.txt.sigstore.json.
|
||||||
|
// The action must still install it cleanly: checksum verified, cosign step skipped.
|
||||||
|
await requireCosign();
|
||||||
|
const bin = await goreleaser.install('goreleaser', 'v2.12.4');
|
||||||
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
it('throws on checksum mismatch', async () => {
|
it('throws on checksum mismatch', async () => {
|
||||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gha-'));
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gha-'));
|
||||||
const archive = path.join(dir, 'fake.tar.gz');
|
const archive = path.join(dir, 'fake.tar.gz');
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import {describe, expect, it, beforeEach, afterEach} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as os from 'os';
|
||||||
|
import * as path from 'path';
|
||||||
|
import {getRequestedVersion} from '../src/version';
|
||||||
|
import {Inputs} from '../src/context';
|
||||||
|
|
||||||
|
const baseInputs = (overrides: Partial<Inputs>): Inputs => ({
|
||||||
|
distribution: 'goreleaser',
|
||||||
|
version: '~> v2',
|
||||||
|
versionFile: '',
|
||||||
|
args: '',
|
||||||
|
workdir: '.',
|
||||||
|
installOnly: false,
|
||||||
|
...overrides
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRequestedVersion', () => {
|
||||||
|
let tmpDir: string;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'goreleaser-version-'));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fs.rmSync(tmpDir, {recursive: true, force: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
const writeToolVersions = (content: string, name = '.tool-versions'): void => {
|
||||||
|
fs.writeFileSync(path.join(tmpDir, name), content);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('without version-file', () => {
|
||||||
|
it('returns the version input as-is', () => {
|
||||||
|
expect(getRequestedVersion(baseInputs({version: 'v1.2.3'}))).toBe('v1.2.3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the default version when none is provided', () => {
|
||||||
|
expect(getRequestedVersion(baseInputs({version: '~> v2'}))).toBe('~> v2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with .tool-versions', () => {
|
||||||
|
it('parses an unprefixed version and adds the v prefix', () => {
|
||||||
|
writeToolVersions('goreleaser 1.2.3\n');
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toBe('v1.2.3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps an existing v prefix without doubling it', () => {
|
||||||
|
writeToolVersions('goreleaser v1.2.3\n');
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toBe('v1.2.3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('takes precedence over the version input', () => {
|
||||||
|
writeToolVersions('goreleaser 1.2.3\n');
|
||||||
|
expect(getRequestedVersion(baseInputs({version: 'v9.9.9', versionFile: '.tool-versions', workdir: tmpDir}))).toBe(
|
||||||
|
'v1.2.3'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignores other tools and picks goreleaser', () => {
|
||||||
|
writeToolVersions(['nodejs 20.10.0', 'goreleaser 2.13.0', 'python 3.12.1', ''].join('\n'));
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toBe('v2.13.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('skips full-line and inline comments', () => {
|
||||||
|
writeToolVersions(['# pinned for CI', 'goreleaser 2.13.0 # minimum cosign-verifiable', ''].join('\n'));
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toBe('v2.13.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves "latest"', () => {
|
||||||
|
writeToolVersions('goreleaser latest\n');
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toBe('latest');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses only the first version when multiple fallbacks are listed', () => {
|
||||||
|
// asdf supports listing fallback versions; we install the first match.
|
||||||
|
writeToolVersions('goreleaser 2.13.0 2.12.4\n');
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toBe('v2.13.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts an absolute path and ignores workdir', () => {
|
||||||
|
const abs = path.join(tmpDir, '.tool-versions');
|
||||||
|
fs.writeFileSync(abs, 'goreleaser 2.13.0\n');
|
||||||
|
expect(getRequestedVersion(baseInputs({versionFile: abs, workdir: '/nonexistent'}))).toBe('v2.13.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when the file does not exist', () => {
|
||||||
|
expect(() => getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toThrow(
|
||||||
|
/version-file not found/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when the file has no goreleaser entry', () => {
|
||||||
|
writeToolVersions(['nodejs 20.10.0', 'python 3.12.1', ''].join('\n'));
|
||||||
|
expect(() => getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toThrow(
|
||||||
|
/No goreleaser entry/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when the goreleaser entry has no version', () => {
|
||||||
|
writeToolVersions('goreleaser\n');
|
||||||
|
expect(() => getRequestedVersion(baseInputs({versionFile: '.tool-versions', workdir: tmpDir}))).toThrow(
|
||||||
|
/No version specified for goreleaser/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with an unsupported file', () => {
|
||||||
|
it('throws a clear error', () => {
|
||||||
|
fs.writeFileSync(path.join(tmpDir, '.go-version'), '1.2.3\n');
|
||||||
|
expect(() => getRequestedVersion(baseInputs({versionFile: '.go-version', workdir: tmpDir}))).toThrow(
|
||||||
|
/Unsupported version-file/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -15,6 +15,12 @@ inputs:
|
|||||||
description: 'GoReleaser version'
|
description: 'GoReleaser version'
|
||||||
default: '~> v2'
|
default: '~> v2'
|
||||||
required: false
|
required: false
|
||||||
|
version-file:
|
||||||
|
description: |
|
||||||
|
Read the GoReleaser version from a file. Path is resolved relative to
|
||||||
|
`workdir`. Currently only `.tool-versions` (asdf/mise) is supported.
|
||||||
|
When set, takes precedence over `version`.
|
||||||
|
required: false
|
||||||
args:
|
args:
|
||||||
description: 'Arguments to pass to GoReleaser'
|
description: 'Arguments to pass to GoReleaser'
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
+2
-2
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@ export const osArch: string = os.arch();
|
|||||||
export interface Inputs {
|
export interface Inputs {
|
||||||
distribution: string;
|
distribution: string;
|
||||||
version: string;
|
version: string;
|
||||||
|
versionFile: string;
|
||||||
args: string;
|
args: string;
|
||||||
workdir: string;
|
workdir: string;
|
||||||
installOnly: boolean;
|
installOnly: boolean;
|
||||||
@@ -16,6 +17,7 @@ export async function getInputs(): Promise<Inputs> {
|
|||||||
return {
|
return {
|
||||||
distribution: core.getInput('distribution') || 'goreleaser',
|
distribution: core.getInput('distribution') || 'goreleaser',
|
||||||
version: core.getInput('version') || '~> v2',
|
version: core.getInput('version') || '~> v2',
|
||||||
|
versionFile: core.getInput('version-file'),
|
||||||
args: core.getInput('args'),
|
args: core.getInput('args'),
|
||||||
workdir: core.getInput('workdir') || '.',
|
workdir: core.getInput('workdir') || '.',
|
||||||
installOnly: core.getBooleanInput('install-only')
|
installOnly: core.getBooleanInput('install-only')
|
||||||
|
|||||||
+41
-1
@@ -30,6 +30,13 @@ export interface GitHubRelease {
|
|||||||
tag_name: string;
|
tag_name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Matches the new-style nightly release tag pattern: vX.Y.Z-<sha>-nightly
|
||||||
|
export const nightlyTagRegex = /^v\d+\.\d+\.\d+-[0-9a-f]+-nightly$/i;
|
||||||
|
|
||||||
|
export const isNightlyTag = (tag: string): boolean => {
|
||||||
|
return nightlyTagRegex.test(tag);
|
||||||
|
};
|
||||||
|
|
||||||
export const getRelease = async (distribution: string, version: string): Promise<GitHubRelease> => {
|
export const getRelease = async (distribution: string, version: string): Promise<GitHubRelease> => {
|
||||||
if (version === 'latest') {
|
if (version === 'latest') {
|
||||||
core.warning("You are using 'latest' as default version. Will lock to '~> v2'.");
|
core.warning("You are using 'latest' as default version. Will lock to '~> v2'.");
|
||||||
@@ -40,7 +47,7 @@ export const getRelease = async (distribution: string, version: string): Promise
|
|||||||
|
|
||||||
export const getReleaseTag = async (distribution: string, version: string): Promise<GitHubRelease> => {
|
export const getReleaseTag = async (distribution: string, version: string): Promise<GitHubRelease> => {
|
||||||
if (version === 'nightly') {
|
if (version === 'nightly') {
|
||||||
return {tag_name: version};
|
return resolveNightly(distribution);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If version is a specific version (not a range), skip the JSON check
|
// If version is a specific version (not a range), skip the JSON check
|
||||||
@@ -81,6 +88,39 @@ export const getReleaseTag = async (distribution: string, version: string): Prom
|
|||||||
throw new Error(`Cannot find GoReleaser release ${version} in ${url}`);
|
throw new Error(`Cannot find GoReleaser release ${version} in ${url}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// resolveNightly looks up the latest immutable nightly release of the form
|
||||||
|
// `vX.Y.Z-<sha>-nightly` on the GitHub releases of the given distribution.
|
||||||
|
const resolveNightly = async (distribution: string): Promise<GitHubRelease> => {
|
||||||
|
const url = `https://api.github.com/repos/goreleaser/${distribution}/releases?per_page=100`;
|
||||||
|
core.debug(`Resolving latest nightly release from ${url}`);
|
||||||
|
|
||||||
|
const releases = await withRetry(async () => {
|
||||||
|
const http: httpm.HttpClient = new httpm.HttpClient('goreleaser-action');
|
||||||
|
const headers: {[name: string]: string} = {
|
||||||
|
Accept: 'application/vnd.github+json',
|
||||||
|
'X-GitHub-Api-Version': '2022-11-28'
|
||||||
|
};
|
||||||
|
const token = process.env.GITHUB_TOKEN;
|
||||||
|
if (token) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
const resp: httpm.HttpClientResponse = await http.get(url, headers);
|
||||||
|
const body = await resp.readBody();
|
||||||
|
const statusCode = resp.message.statusCode || 500;
|
||||||
|
if (statusCode >= 400) {
|
||||||
|
throw new Error(`Failed to list releases from ${url} with status code ${statusCode}: ${body}`);
|
||||||
|
}
|
||||||
|
return <Array<GitHubRelease>>JSON.parse(body);
|
||||||
|
});
|
||||||
|
|
||||||
|
const match = releases.find(r => nightlyTagRegex.test(r.tag_name));
|
||||||
|
if (!match) {
|
||||||
|
throw new Error(`No '<version>-<sha>-nightly' release found in ${url}`);
|
||||||
|
}
|
||||||
|
core.info(`Resolved nightly to ${match.tag_name}`);
|
||||||
|
return match;
|
||||||
|
};
|
||||||
|
|
||||||
const resolveVersion = async (distribution: string, version: string): Promise<string | null> => {
|
const resolveVersion = async (distribution: string, version: string): Promise<string | null> => {
|
||||||
const allTags: Array<string> | null = await getAllTags(distribution);
|
const allTags: Array<string> | null = await getAllTags(distribution);
|
||||||
if (!allTags) {
|
if (!allTags) {
|
||||||
|
|||||||
+1
-1
@@ -120,7 +120,7 @@ async function verifyCosignSignature(
|
|||||||
|
|
||||||
export const getCertificateIdentity = (distribution: string, tag: string): string => {
|
export const getCertificateIdentity = (distribution: string, tag: string): string => {
|
||||||
const pro = isPro(distribution);
|
const pro = isPro(distribution);
|
||||||
if (tag === 'nightly') {
|
if (github.isNightlyTag(tag)) {
|
||||||
const workflow = pro ? 'nightly-pro.yml' : 'nightly-oss.yml';
|
const workflow = pro ? 'nightly-pro.yml' : 'nightly-oss.yml';
|
||||||
const repo = pro ? 'goreleaser-pro-internal' : 'goreleaser';
|
const repo = pro ? 'goreleaser-pro-internal' : 'goreleaser';
|
||||||
return `https://github.com/goreleaser/${repo}/.github/workflows/${workflow}@refs/heads/main`;
|
return `https://github.com/goreleaser/${repo}/.github/workflows/${workflow}@refs/heads/main`;
|
||||||
|
|||||||
+4
-2
@@ -4,14 +4,16 @@ import yargs from 'yargs';
|
|||||||
import type {Arguments} from 'yargs';
|
import type {Arguments} from 'yargs';
|
||||||
import * as context from './context';
|
import * as context from './context';
|
||||||
import * as goreleaser from './goreleaser';
|
import * as goreleaser from './goreleaser';
|
||||||
|
import {getRequestedVersion} from './version';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const inputs: context.Inputs = await context.getInputs();
|
const inputs: context.Inputs = await context.getInputs();
|
||||||
const bin = await goreleaser.install(inputs.distribution, inputs.version);
|
const version = getRequestedVersion(inputs);
|
||||||
core.info(`GoReleaser ${inputs.version} installed successfully`);
|
const bin = await goreleaser.install(inputs.distribution, version);
|
||||||
|
core.info(`GoReleaser ${version} installed successfully`);
|
||||||
|
|
||||||
if (inputs.installOnly) {
|
if (inputs.installOnly) {
|
||||||
const goreleaserDir = path.dirname(bin);
|
const goreleaserDir = path.dirname(bin);
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import {Inputs} from './context';
|
||||||
|
|
||||||
|
// Resolves the GoReleaser version to install.
|
||||||
|
//
|
||||||
|
// When `version-file` is set, it is read from disk and parsed; the resolved
|
||||||
|
// value takes precedence over the `version` input. Otherwise, `version` is
|
||||||
|
// returned as-is (it always has a default — see context.getInputs).
|
||||||
|
export function getRequestedVersion(inputs: Inputs): string {
|
||||||
|
if (!inputs.versionFile) {
|
||||||
|
return inputs.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = path.isAbsolute(inputs.versionFile)
|
||||||
|
? inputs.versionFile
|
||||||
|
: path.join(inputs.workdir || '.', inputs.versionFile);
|
||||||
|
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
throw new Error(`version-file not found: ${filePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const basename = path.basename(filePath);
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
|
||||||
|
switch (basename) {
|
||||||
|
case '.tool-versions':
|
||||||
|
return parseToolVersions(content, filePath);
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported version-file: ${filePath} (only .tool-versions is supported)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses a single `goreleaser <version>` entry out of a `.tool-versions` file
|
||||||
|
// (asdf/mise format). Full-line `#` comments and inline `# ...` suffixes are
|
||||||
|
// stripped. When a tool lists multiple fallback versions only the first is
|
||||||
|
// used. Bare semvers are returned with a leading `v`; constraint expressions
|
||||||
|
// (`~> v2`, `latest`, ...) are returned as-is.
|
||||||
|
function parseToolVersions(content: string, filePath: string): string {
|
||||||
|
for (const rawLine of content.split('\n')) {
|
||||||
|
const line = rawLine.replace(/#.*$/, '').trim();
|
||||||
|
if (!line) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const tokens = line.split(/\s+/);
|
||||||
|
if (tokens[0] !== 'goreleaser') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const version = tokens[1];
|
||||||
|
if (!version) {
|
||||||
|
throw new Error(`No version specified for goreleaser in ${filePath}`);
|
||||||
|
}
|
||||||
|
return /^\d/.test(version) ? `v${version}` : version;
|
||||||
|
}
|
||||||
|
throw new Error(`No goreleaser entry found in ${filePath}`);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user