From 5401155036604317641e279b8a20e8bf96b2a9ff Mon Sep 17 00:00:00 2001 From: Stephen Cefali Date: Wed, 11 Nov 2020 08:52:21 -0800 Subject: [PATCH] feat: multiple project options (#30) --- __tests__/main.test.ts | 25 +++++++++++++++++++++++++ action.yml | 3 +++ package.json | 2 +- src/main.ts | 15 +++++++++++++-- src/sentry-cli.d.ts | 3 ++- src/validate.ts | 23 ++++++++++++++++++----- yarn.lock | 8 ++++---- 7 files changed, 66 insertions(+), 13 deletions(-) diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index a2b0e4e..4b08a40 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -7,6 +7,7 @@ import { getStartedAt, getVersion, getSetCommitsOption, + getProjects, } from '../src/validate'; describe('validate', () => { @@ -135,6 +136,30 @@ describe('validate', () => { expect(() => getSetCommitsOption()).toThrow(errorMessage); }); }); + describe('getProjects', () => { + afterEach(() => { + delete process.env['SENTRY_PROJECT']; + delete process.env['INPUT_PROJECTS']; + }); + it('read from env variable', () => { + process.env['SENTRY_PROJECT'] = 'my-proj'; + expect(getProjects()).toEqual(['my-proj']); + }); + it('read from option', () => { + process.env['INPUT_PROJECTS'] = 'my-proj1 my-proj2'; + expect(getProjects()).toEqual(['my-proj1', 'my-proj2']); + }); + it('option overwites env variable', () => { + process.env['SENTRY_PROJECT'] = 'my-proj'; + process.env['INPUT_PROJECTS'] = 'my-proj1 my-proj2'; + expect(getProjects()).toEqual(['my-proj1', 'my-proj2']); + }); + it('throws error if no project', () => { + expect(() => getProjects()).toThrowError( + 'Environment variable SENTRY_PROJECT is missing a project slug and no projects are specified with the "projects" option' + ); + }); + }); }); // shows how the runner will run a javascript action with env / stdout protocol diff --git a/action.yml b/action.yml index a6a5926..ff250d6 100644 --- a/action.yml +++ b/action.yml @@ -23,6 +23,9 @@ inputs: set_commits: description: 'Specify whether to set commits for the release. Either "auto" or "skip".' required: false + projects: + description: 'Space-separated list of projects. Defaults to the env variable "SENTRY_PROJECT" if not provided.' + required: false runs: using: 'docker' image: 'docker://sentryintegrations/sentry-github-action-release:latest' diff --git a/package.json b/package.json index f1537b2..dc2b0ac 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "license": "MIT", "dependencies": { "@actions/core": "^1.2.4", - "@sentry/cli": "^1.55.0", + "@sentry/cli": "^1.59.0", "@sentry/types": "^5.17.0" }, "devDependencies": { diff --git a/src/main.ts b/src/main.ts index b7e5aed..7f6301a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,11 +13,12 @@ import * as validate from './validate'; const shouldFinalize = validate.getShouldFinalize(); const deployStartedAtOption = validate.getStartedAt(); const setCommitsOption = validate.getSetCommitsOption(); + const projects = validate.getProjects(); const version = await validate.getVersion(); core.debug(`Version is ${version}`); - await cli.new(version); + await cli.new(version, {projects}); if (setCommitsOption !== 'skip') { core.debug(`Setting commits with option '${setCommitsOption}'`); @@ -26,7 +27,17 @@ import * as validate from './validate'; if (sourcemaps) { core.debug(`Adding sourcemaps`); - await cli.uploadSourceMaps(version, {include: sourcemaps}); + await Promise.all( + projects.map(async project => { + // upload source maps can only do one project at a time + const localProjects: [string] = [project]; + const sourceMapOptions = { + include: sourcemaps, + projects: localProjects, + }; + return cli.uploadSourceMaps(version, sourceMapOptions); + }) + ); } core.debug(`Adding deploy to release`); diff --git a/src/sentry-cli.d.ts b/src/sentry-cli.d.ts index 0f68acc..6c39166 100644 --- a/src/sentry-cli.d.ts +++ b/src/sentry-cli.d.ts @@ -1,7 +1,7 @@ declare module '@sentry/cli' { export class Releases { constructor(configFile?: string, options?: {silent?: boolean}); - new(release: string): Promise; + new(release: string, options?: {projects: string[]}): Promise; setCommits( release: string, options: { @@ -27,6 +27,7 @@ declare module '@sentry/cli' { urlPrefix?: string; urlSuffix?: string; ext?: string[]; + projects?: [string]; //only one project allowed (for now) } ): Promise; listDeploys(release: string): Promise; diff --git a/src/validate.ts b/src/validate.ts index 70204ee..3b8e492 100644 --- a/src/validate.ts +++ b/src/validate.ts @@ -131,14 +131,27 @@ export const checkEnvironmentVariables = (): void => { 'Environment variable SENTRY_ORG is missing an organization slug' ); } - if (!process.env['SENTRY_PROJECT']) { - throw Error( - 'Environment variable SENTRY_PROJECT is missing a project slug' - ); - } if (!process.env['SENTRY_AUTH_TOKEN']) { throw Error( 'Environment variable SENTRY_AUTH_TOKEN is missing an auth token' ); } }; + +export const getProjects = (): string[] => { + const projectsOption = core.getInput('projects') || ''; + const projects = projectsOption + .split(' ') + .map(proj => proj.trim()) + .filter(proj => !!proj); + if (projects.length > 0) { + return projects; + } + const project = process.env['SENTRY_PROJECT']; + if (!project) { + throw Error( + 'Environment variable SENTRY_PROJECT is missing a project slug and no projects are specified with the "projects" option' + ); + } + return [project]; +}; diff --git a/yarn.lock b/yarn.lock index 226a8a2..89ff9a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -469,10 +469,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@sentry/cli@^1.55.0": - version "1.55.0" - resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.55.0.tgz#0da95cd9491e11da52b15796bded72480f69591b" - integrity sha512-LOpM69Kvfaossq92wgP8cg3+0XBc9lg76udH4OdmpSZhtavS/qxWedBsnTicaT//7rQUNZBUnTPOpmCYnpGEIA== +"@sentry/cli@^1.59.0": + version "1.59.0" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.59.0.tgz#8154c6426a105c6c8a2437db085837aff8e29834" + integrity sha512-9nK4uVHW7HIbOwFZNvHRWFJcD+bqjW3kMWK2UUMqQWse0Lf3xM+2o+REGGkk0S69+E4elSiukVjUPTI5aijNlA== dependencies: https-proxy-agent "^5.0.0" mkdirp "^0.5.5"