From 70eb4e573c41612a87fc52e8fb7b7d1a56d14e9c Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 27 May 2021 00:25:31 -0300 Subject: [PATCH] feat: support downloading goreleaser pro (#284) --- README.md | 28 ++++++++++------- __tests__/github.test.ts | 22 +++++++++++--- __tests__/installer.test.ts | 14 +++++++-- __tests__/pro.test.ts | 10 +++++++ dist/index.js | 60 +++++++++++++++++++++++++++---------- src/github.ts | 28 ++++++++++++----- src/installer.ts | 15 ++++++---- src/main.ts | 3 +- src/pro.ts | 7 +++++ 9 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 __tests__/pro.test.ts create mode 100644 src/pro.ts diff --git a/README.md b/README.md index af3bb099..95d59304 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,14 @@ jobs: name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 with: + # either 'goreleaser' (default) or 'goreleaser-pro' + distribution: goreleaser version: latest args: release --rm-dist env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution + # GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} ``` > **IMPORTANT**: note the `fetch-depth: 0` input in `Checkout` step. It is required for the changelog to work correctly. @@ -165,12 +169,13 @@ steps: Following inputs can be used as `step.with` keys -| Name | Type | Default | Description | -|------------------|---------|-----------|-------------------------------------------| -| `version`**¹** | String | `latest` | GoReleaser version | -| `args` | String | | Arguments to pass to GoReleaser | -| `workdir` | String | `.` | Working directory (below repository root) | -| `install-only` | Bool | `false` | Just install GoReleaser | +| Name | Type | Default | Description | +|------------------|---------|--------------|------------------------------------------------------------------| +| `distribution` | String | `goreleaser` | GoReleaser distribution, either `goreleaser` or `goreleaser-pro` | +| `version`**¹** | String | `latest` | GoReleaser version | +| `args` | String | | Arguments to pass to GoReleaser | +| `workdir` | String | `.` | Working directory (below repository root) | +| `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`. @@ -178,17 +183,18 @@ Following inputs can be used as `step.with` keys Following environment variables can be used as `step.env` keys -| Name | Description | -|----------------|---------------------------------------| -| `GITHUB_TOKEN` | [GITHUB_TOKEN](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token) as provided by `secrets` | +| Name | Description | +|------------------|---------------------------------------| +| `GITHUB_TOKEN` | [GITHUB_TOKEN](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token) as provided by `secrets` | +| `GORELEASER_KEY` | Your [GoReleaser Pro](https://goreleaser.com/pro) License Key, in case you are using the `goreleaser-pro` distribution | ## Limitation `GITHUB_TOKEN` permissions [are limited to the repository](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#about-the-github_token-secret) -that contains your workflow. +that contains your workflow. If you need to push the homebrew tap to another repository, you must therefore create a custom [Personal Access Token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) -with `repo` permissions and [add it as a secret in the repository](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets). If you create a +with `repo` permissions and [add it as a secret in the repository](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets). If you create a secret named `GH_PAT`, the step will look like this: ```yaml diff --git a/__tests__/github.test.ts b/__tests__/github.test.ts index c8d3ea72..9ef10f16 100644 --- a/__tests__/github.test.ts +++ b/__tests__/github.test.ts @@ -2,19 +2,33 @@ import * as github from '../src/github'; describe('github', () => { it('returns latest GoReleaser GitHub release', async () => { - const release = await github.getRelease('latest'); + const release = await github.getRelease('goreleaser', 'latest'); expect(release).not.toBeNull(); expect(release?.tag_name).not.toEqual(''); - console.log(`tag_name: ${release?.tag_name}`); }); it('returns v0.117.0 GoReleaser GitHub release', async () => { - const release = await github.getRelease('v0.117.0'); + const release = await github.getRelease('goreleaser', 'v0.117.0'); expect(release).not.toBeNull(); expect(release?.tag_name).toEqual('v0.117.0'); }); it('returns v0.132.1 GoReleaser GitHub release', async () => { - const release = await github.getRelease('~> 0.132'); + const release = await github.getRelease('goreleaser', '~> 0.132'); expect(release).not.toBeNull(); expect(release?.tag_name).toEqual('v0.132.1'); }); + it('returns latest GoReleaser Pro GitHub release', async () => { + const release = await github.getRelease('goreleaser-pro', 'latest'); + expect(release).not.toBeNull(); + expect(release?.tag_name).not.toEqual(''); + }); + it('returns v0.166.0-pro GoReleaser Pro GitHub release', async () => { + const release = await github.getRelease('goreleaser-pro', 'v0.166.0-pro'); + expect(release).not.toBeNull(); + expect(release?.tag_name).toEqual('v0.166.0-pro'); + }); + it('returns v0.166.0-pro GoReleaser Pro GitHub release when using semver', async () => { + const release = await github.getRelease('goreleaser-pro', '~> 0.166'); + expect(release).not.toBeNull(); + expect(release?.tag_name).toEqual('v0.166.0-pro'); + }); }); diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index ff8d236b..b2c55718 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -3,12 +3,22 @@ import * as installer from '../src/installer'; describe('installer', () => { it('acquires v0.117.0 version of GoReleaser', async () => { - const goreleaser = await installer.getGoReleaser('v0.117.0'); + const goreleaser = await installer.getGoReleaser('goreleaser', 'v0.117.0'); expect(fs.existsSync(goreleaser)).toBe(true); }, 100000); it('acquires latest version of GoReleaser', async () => { - const goreleaser = await installer.getGoReleaser('latest'); + const goreleaser = await installer.getGoReleaser('goreleaser', 'latest'); + expect(fs.existsSync(goreleaser)).toBe(true); + }, 100000); + + it('acquires v0.166.0-pro version of GoReleaser Pro', async () => { + const goreleaser = await installer.getGoReleaser('goreleaser-pro', 'v0.166.0-pro'); + expect(fs.existsSync(goreleaser)).toBe(true); + }, 100000); + + it('acquires latest version of GoReleaser Pro', async () => { + const goreleaser = await installer.getGoReleaser('goreleaser-pro', 'latest'); expect(fs.existsSync(goreleaser)).toBe(true); }, 100000); }); diff --git a/__tests__/pro.test.ts b/__tests__/pro.test.ts new file mode 100644 index 00000000..9883b32d --- /dev/null +++ b/__tests__/pro.test.ts @@ -0,0 +1,10 @@ +import * as pro from '../src/pro'; + +describe('pro', () => { + it('suffixes pro distribution', async () => { + expect(pro.suffix('goreleaser-pro')).toEqual('-pro'); + }); + it('does not suffix oss distribution', async () => { + expect(pro.suffix('goreleaser')).toEqual(''); + }); +}); diff --git a/dist/index.js b/dist/index.js index 60549b55..1fed5dfd 100644 --- a/dist/index.js +++ b/dist/index.js @@ -190,23 +190,30 @@ exports.getRelease = void 0; const httpm = __importStar(__webpack_require__(925)); const core = __importStar(__webpack_require__(186)); const semver = __importStar(__webpack_require__(911)); -exports.getRelease = (version) => __awaiter(void 0, void 0, void 0, function* () { - const resolvedVersion = (yield resolveVersion(version)) || version; - const url = `https://github.com/goreleaser/goreleaser/releases/${resolvedVersion}`; +const pro = __importStar(__webpack_require__(989)); +exports.getRelease = (distribution, version) => __awaiter(void 0, void 0, void 0, function* () { + const resolvedVersion = (yield resolveVersion(distribution, version)) || version; + const url = `https://github.com/goreleaser/${distribution}/releases/${resolvedVersion}`; const http = new httpm.HttpClient('goreleaser-action'); return (yield http.getJson(url)).result; }); -const resolveVersion = (version) => __awaiter(void 0, void 0, void 0, function* () { - const allTags = yield getAllTags(); +const resolveVersion = (distribution, version) => __awaiter(void 0, void 0, void 0, function* () { + const allTags = yield getAllTags(distribution); if (!allTags) { throw new Error(`Cannot find GoReleaser tags`); } core.debug(`Found ${allTags.length} tags in total`); - return semver.maxSatisfying(allTags, version); + if (version === 'latest' || !pro.isPro(distribution)) { + return semver.maxSatisfying(allTags, version); + } + const cleanTags = allTags.map(tag => cleanTag(tag)); + const cleanVersion = cleanTag(version); + return semver.maxSatisfying(cleanTags, cleanVersion) + pro.suffix(distribution); }); -const getAllTags = () => __awaiter(void 0, void 0, void 0, function* () { +const getAllTags = (distribution) => __awaiter(void 0, void 0, void 0, function* () { const http = new httpm.HttpClient('goreleaser-action'); - const url = `https://goreleaser.com/static/releases.json`; + const suffix = pro.suffix(distribution); + const url = `https://goreleaser.com/static/releases${suffix}.json`; const getTags = http.getJson(url); return getTags.then(response => { if (response.result == null) { @@ -215,6 +222,9 @@ const getAllTags = () => __awaiter(void 0, void 0, void 0, function* () { return response.result.map(obj => obj.tag_name); }); }); +const cleanTag = (tag) => { + return tag.replace(/-pro$/, ''); +}; //# sourceMappingURL=github.js.map /***/ }), @@ -258,19 +268,20 @@ const os = __importStar(__webpack_require__(87)); const path = __importStar(__webpack_require__(622)); const util = __importStar(__webpack_require__(669)); const github = __importStar(__webpack_require__(928)); +const pro = __importStar(__webpack_require__(989)); const core = __importStar(__webpack_require__(186)); const tc = __importStar(__webpack_require__(784)); const osPlat = os.platform(); const osArch = os.arch(); -function getGoReleaser(version) { +function getGoReleaser(distribution, version) { return __awaiter(this, void 0, void 0, function* () { - const release = yield github.getRelease(version); + const release = yield github.getRelease(distribution, version); if (!release) { throw new Error(`Cannot find GoReleaser ${version} release`); } core.info(`✅ GoReleaser version found: ${release.tag_name}`); - const filename = getFilename(); - const downloadUrl = util.format('https://github.com/goreleaser/goreleaser/releases/download/%s/%s', release.tag_name, filename); + const filename = getFilename(distribution); + const downloadUrl = util.format('https://github.com/goreleaser/%s/releases/download/%s/%s', distribution, release.tag_name, filename); core.info(`⬇️ Downloading ${downloadUrl}...`); const downloadPath = yield tc.downloadTool(downloadUrl); core.debug(`Downloaded to ${downloadPath}`); @@ -291,11 +302,12 @@ function getGoReleaser(version) { }); } exports.getGoReleaser = getGoReleaser; -const getFilename = () => { +const getFilename = (distribution) => { const platform = osPlat == 'win32' ? 'Windows' : osPlat == 'darwin' ? 'Darwin' : 'Linux'; const arch = osArch == 'x64' ? 'x86_64' : 'i386'; const ext = osPlat == 'win32' ? 'zip' : 'tar.gz'; - return util.format('goreleaser_%s_%s.%s', platform, arch, ext); + const suffix = pro.suffix(distribution); + return util.format('goreleaser%s_%s_%s.%s', suffix, platform, arch, ext); }; //# sourceMappingURL=installer.js.map @@ -343,11 +355,12 @@ const path_1 = __webpack_require__(622); function run() { return __awaiter(this, void 0, void 0, function* () { try { + const distribution = core.getInput('distribution') || 'goreleaser'; const version = core.getInput('version') || 'latest'; const args = core.getInput('args'); const workdir = core.getInput('workdir') || '.'; const isInstallOnly = /^true$/i.test(core.getInput('install-only')); - const goreleaser = yield installer.getGoReleaser(version); + const goreleaser = yield installer.getGoReleaser(distribution, version); core.info(`✅ GoReleaser installed successfully`); if (isInstallOnly) { const goreleaserDir = path_1.dirname(goreleaser); @@ -393,6 +406,23 @@ run(); /***/ }), +/***/ 989: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isPro = exports.suffix = void 0; +exports.suffix = (distribution) => { + return exports.isPro(distribution) ? '-pro' : ''; +}; +exports.isPro = (distribution) => { + return distribution === 'goreleaser-pro'; +}; +//# sourceMappingURL=pro.js.map + +/***/ }), + /***/ 241: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { diff --git a/src/github.ts b/src/github.ts index bde249f7..ed3c3d4f 100644 --- a/src/github.ts +++ b/src/github.ts @@ -1,36 +1,44 @@ import * as httpm from '@actions/http-client'; import * as core from '@actions/core'; import * as semver from 'semver'; +import * as pro from './pro'; export interface GitHubRelease { id: number; tag_name: string; } -export const getRelease = async (version: string): Promise => { - const resolvedVersion: string = (await resolveVersion(version)) || version; - const url: string = `https://github.com/goreleaser/goreleaser/releases/${resolvedVersion}`; +export const getRelease = async (distribution: string, version: string): Promise => { + const resolvedVersion: string = (await resolveVersion(distribution, version)) || version; + const url: string = `https://github.com/goreleaser/${distribution}/releases/${resolvedVersion}`; const http: httpm.HttpClient = new httpm.HttpClient('goreleaser-action'); return (await http.getJson(url)).result; }; -const resolveVersion = async (version: string): Promise => { - const allTags: Array | null = await getAllTags(); +const resolveVersion = async (distribution: string, version: string): Promise => { + const allTags: Array | null = await getAllTags(distribution); if (!allTags) { throw new Error(`Cannot find GoReleaser tags`); } core.debug(`Found ${allTags.length} tags in total`); - return semver.maxSatisfying(allTags, version); + if (version === 'latest' || !pro.isPro(distribution)) { + return semver.maxSatisfying(allTags, version); + } + + const cleanTags: Array = allTags.map(tag => cleanTag(tag)); + const cleanVersion: string = cleanTag(version); + return semver.maxSatisfying(cleanTags, cleanVersion) + pro.suffix(distribution); }; interface GitHubTag { tag_name: string; } -const getAllTags = async (): Promise> => { +const getAllTags = async (distribution: string): Promise> => { const http: httpm.HttpClient = new httpm.HttpClient('goreleaser-action'); - const url: string = `https://goreleaser.com/static/releases.json`; + const suffix: string = pro.suffix(distribution); + const url: string = `https://goreleaser.com/static/releases${suffix}.json`; const getTags = http.getJson>(url); return getTags.then(response => { @@ -41,3 +49,7 @@ const getAllTags = async (): Promise> => { return response.result.map(obj => obj.tag_name); }); }; + +const cleanTag = (tag: string): string => { + return tag.replace(/-pro$/, ''); +}; diff --git a/src/installer.ts b/src/installer.ts index 6ff5e01b..1f90adbc 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -2,22 +2,24 @@ import * as os from 'os'; import * as path from 'path'; import * as util from 'util'; import * as github from './github'; +import * as pro from './pro'; import * as core from '@actions/core'; import * as tc from '@actions/tool-cache'; const osPlat: string = os.platform(); const osArch: string = os.arch(); -export async function getGoReleaser(version: string): Promise { - const release: github.GitHubRelease | null = await github.getRelease(version); +export async function getGoReleaser(distribution: string, version: string): Promise { + const release: github.GitHubRelease | null = await github.getRelease(distribution, version); if (!release) { throw new Error(`Cannot find GoReleaser ${version} release`); } core.info(`✅ GoReleaser version found: ${release.tag_name}`); - const filename = getFilename(); + const filename = getFilename(distribution); const downloadUrl = util.format( - 'https://github.com/goreleaser/goreleaser/releases/download/%s/%s', + 'https://github.com/goreleaser/%s/releases/download/%s/%s', + distribution, release.tag_name, filename ); @@ -44,9 +46,10 @@ export async function getGoReleaser(version: string): Promise { return exePath; } -const getFilename = (): string => { +const getFilename = (distribution: string): string => { const platform: string = osPlat == 'win32' ? 'Windows' : osPlat == 'darwin' ? 'Darwin' : 'Linux'; const arch: string = osArch == 'x64' ? 'x86_64' : 'i386'; const ext: string = osPlat == 'win32' ? 'zip' : 'tar.gz'; - return util.format('goreleaser_%s_%s.%s', platform, arch, ext); + const suffix: string = pro.suffix(distribution); + return util.format('goreleaser%s_%s_%s.%s', suffix, platform, arch, ext); }; diff --git a/src/main.ts b/src/main.ts index ed47cd9e..074a5684 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,11 +6,12 @@ import {dirname} from 'path'; async function run(): Promise { try { + const distribution = core.getInput('distribution') || 'goreleaser'; const version = core.getInput('version') || 'latest'; const args = core.getInput('args'); const workdir = core.getInput('workdir') || '.'; const isInstallOnly = /^true$/i.test(core.getInput('install-only')); - const goreleaser = await installer.getGoReleaser(version); + const goreleaser = await installer.getGoReleaser(distribution, version); core.info(`✅ GoReleaser installed successfully`); if (isInstallOnly) { diff --git a/src/pro.ts b/src/pro.ts new file mode 100644 index 00000000..46f25fc7 --- /dev/null +++ b/src/pro.ts @@ -0,0 +1,7 @@ +export const suffix = (distribution: string): string => { + return isPro(distribution) ? '-pro' : ''; +}; + +export const isPro = (distribution: string): boolean => { + return distribution === 'goreleaser-pro'; +};