diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7b463a36..a076d924 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -143,6 +143,8 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
+ permissions:
+ contents: read
name: Test current action
steps:
- uses: actions/checkout@v4
@@ -160,6 +162,8 @@ jobs:
test-runs-on-container:
needs: docker-build
runs-on: ubuntu-latest
+ permissions:
+ contents: read
container:
image: node:20.19.2
@@ -183,6 +187,8 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Mock a release
+ permissions:
+ contents: read
steps:
- uses: actions/checkout@v4
with:
@@ -202,6 +208,8 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Mock a release in a different working directory
+ permissions:
+ contents: read
steps:
- name: Checkout directory we'll be running from
uses: actions/checkout@v4
@@ -231,6 +239,8 @@ jobs:
node-version: ['20.x', '22.x']
runs-on: ${{ matrix.os }}
name: Test Node version preserved on ${{ matrix.os }} with Node ${{ matrix.node-version }}
+ permissions:
+ contents: read
steps:
- uses: actions/checkout@v4
with:
@@ -266,4 +276,33 @@ jobs:
echo "ERROR: Node version changed from ${{ steps.node_before.outputs.VERSION }} to $VERSION_AFTER"
exit 1
fi
+
echo "SUCCESS: Node version preserved"
+
+ test-manual-commit-range:
+ needs: docker-build
+
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ runs-on: ${{ matrix.os }}
+ name: Test manual commit range
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Create a release with manual commit range
+ uses: ./
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ SENTRY_LOG_LEVEL: debug
+ MOCK: true
+ with:
+ environment: production
+ set_commits: manual
+ repo: getsentry/action-release
+ commit: ${{ github.sha }}
+ previous_commit: ${{ github.sha }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf3638f9..f8bfbfe7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 3.4.0
+
+- feat: Add support for setting manual commit range (#291) by @andreiborza
+
+Work in this release was contributed by @trevorkwhite. Thank you for your contribution!
+
## 3.3.0
### Various fixes & improvements
@@ -7,6 +13,8 @@
- chore: pin cache action (#290) by @saibotk
- chore: Set docker tag for master [skip ci] (ae1d1cd5) by @getsantry[bot]
+Work in this release was contributed by @saibotk. Thank you for your contribution!
+
## 3.2.0
### Various fixes & improvements
diff --git a/README.md b/README.md
index 658ee538..8451d861 100644
--- a/README.md
+++ b/README.md
@@ -58,66 +58,78 @@ Adding the following to your workflow will create a new Sentry release and tell
#### Environment Variables
-|name|description|default|
-|---|---|---|
-|`SENTRY_AUTH_TOKEN`|**[Required]** Authentication token for Sentry. See [installation](#create-a-sentry-internal-integration).|-|
-|`SENTRY_ORG`|**[Required]** The slug of the organization name in Sentry.|-|
-|`SENTRY_PROJECT`|The slug of the project name in Sentry. One of `SENTRY_PROJECT` or `projects` is required.|-|
-|`SENTRY_URL`|The URL used to connect to Sentry. (Only required for [Self-Hosted Sentry](https://develop.sentry.dev/self-hosted/))|`https://sentry.io/`|
+| name | description | default |
+| ------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------- |
+| `SENTRY_AUTH_TOKEN` | **[Required]** Authentication token for Sentry. See [installation](#create-a-sentry-internal-integration). | - |
+| `SENTRY_ORG` | **[Required]** The slug of the organization name in Sentry. | - |
+| `SENTRY_PROJECT` | The slug of the project name in Sentry. One of `SENTRY_PROJECT` or `projects` is required. | - |
+| `SENTRY_URL` | The URL used to connect to Sentry. (Only required for [Self-Hosted Sentry](https://develop.sentry.dev/self-hosted/)) | `https://sentry.io/` |
#### Parameters
-| name | description |default|
-|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|
-| `environment` | Set the environment for this release. E.g. "production" or "staging". Omit to skip adding deploy to release. |-|
-| `sourcemaps` | Space-separated list of paths to JavaScript sourcemaps. Omit to skip uploading sourcemaps. |-|
-| `inject` | Injects Debug IDs into source files and source maps to ensure proper un-minifcation of your stacktraces. Does nothing if `sourcemaps` was not set. |`true`|
-| `finalize` | When false, omit marking the release as finalized and released. |`true`|
-| `ignore_missing` | When the flag is set and the previous release commit was not found in the repository, will create a release with the default commits count instead of failing the command. |`false`|
-| `ignore_empty` | When the flag is set, command will not fail and just exit silently if no new commits for a given release have been found. |`false`|
-| `dist` | Unique identifier for the distribution, used to further segment your release. Usually your build number. |-|
-| `started_at` | Unix timestamp of the release start date. Omit for current time. |-|
-| `release` | Identifier that uniquely identifies the releases. Should match the `release` property in your Sentry SDK init call if one was set._Note: the `refs/tags/` prefix is automatically stripped when `version` is `github.ref`._ |${{ github.sha }}|
-| `version` | Deprecated: Use `release` instead. |${{ github.sha }}|
-| `release_prefix` | Value prepended to auto-generated version. For example "v". |-|
-| `version_prefix` | Deprecated: Use `release_prefix` instead. |-|
-| `set_commits` | Specify whether to set commits for the release. Either "auto" or "skip". |"auto"|
-| `projects` | Space-separated list of paths of projects. When omitted, falls back to the environment variable `SENTRY_PROJECT` to determine the project. |-|
-| `url_prefix` | Adds a prefix to source map urls after stripping them. |-|
-| `strip_common_prefix` | Will remove a common prefix from uploaded filenames. Useful for removing a path that is build-machine-specific. |`false`|
-| `working_directory` | Directory to collect sentry release information from. Useful when collecting information from a non-standard checkout directory. |-|
-| `disable_telemetry` | The action sends telemetry data and crash reports to Sentry. This helps us improve the action. You can turn this off by setting this flag. |`false`|
-| `disable_safe_directory` | The action needs access to the repo it runs in. For that we need to configure git to mark the repo as a safe directory. You can turn this off by setting this flag. |`false`|
-
+| name | description | default |
+| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
+| `environment` | Set the environment for this release. E.g. "production" or "staging". Omit to skip adding deploy to release. | - |
+| `sourcemaps` | Space-separated list of paths to JavaScript sourcemaps. Omit to skip uploading sourcemaps. | - |
+| `inject` | Injects Debug IDs into source files and source maps to ensure proper un-minifcation of your stacktraces. Does nothing if `sourcemaps` was not set. | `true` |
+| `finalize` | When false, omit marking the release as finalized and released. | `true` |
+| `ignore_missing` | When the flag is set and the previous release commit was not found in the repository, will create a release with the default commits count instead of failing the command. | `false` |
+| `ignore_empty` | When the flag is set, command will not fail and just exit silently if no new commits for a given release have been found. | `false` |
+| `dist` | Unique identifier for the distribution, used to further segment your release. Usually your build number. | - |
+| `started_at` | Unix timestamp of the release start date. Omit for current time. | - |
+| `release` | Identifier that uniquely identifies the releases. Should match the `release` property in your Sentry SDK init call if one was set. _Note: the `refs/tags/` prefix is automatically stripped when `version` is `github.ref`._ | ${{ github.sha }} |
+| `version` | Deprecated: Use `release` instead. | ${{ github.sha }} |
+| `release_prefix` | Value prepended to auto-generated version. For example "v". | - |
+| `version_prefix` | Deprecated: Use `release_prefix` instead. | - |
+| `set_commits` | Specify whether to set commits for the release. When "manual", you need to provide the repository, commit, and previous commit. One of "auto", "skip" or "manual". | "auto" |
+| `repo` | The repository to set commits for in "repo-owner/repo-name" format. Only used when `set_commits` is "manual". | - |
+| `commit` | The commit SHA of the current release you are creating. Only used when `set_commits` is "manual". | - |
+| `previous_commit` | The commit SHA of the previous release. Required when `set_commits` is "manual". | - |
+| `projects` | Space-separated list of paths of projects. When omitted, falls back to the environment variable `SENTRY_PROJECT` to determine the project. | - |
+| `url_prefix` | Adds a prefix to source map urls after stripping them. | - |
+| `strip_common_prefix` | Will remove a common prefix from uploaded filenames. Useful for removing a path that is build-machine-specific. | `false` |
+| `working_directory` | Directory to collect sentry release information from. Useful when collecting information from a non-standard checkout directory. | - |
+| `disable_telemetry` | The action sends telemetry data and crash reports to Sentry. This helps us improve the action. You can turn this off by setting this flag. | `false` |
+| `disable_safe_directory` | The action needs access to the repo it runs in. For that we need to configure git to mark the repo as a safe directory. You can turn this off by setting this flag. | `false` |
### Examples
- Create a new Sentry release for the `production` environment, inject Debug IDs into JavaScript source files and source maps and upload them from the `./dist` directory.
- ```yaml
- - uses: getsentry/action-release@v3
- with:
- environment: 'production'
- sourcemaps: './dist'
- ```
+ ```yaml
+ - uses: getsentry/action-release@v3
+ with:
+ environment: 'production'
+ sourcemaps: './dist'
+ ```
- Create a new Sentry release for the `production` environment of your project at version `v1.0.1`.
- ```yaml
- - uses: getsentry/action-release@v3
- with:
- environment: 'production'
- release: 'v1.0.1'
- ```
+ ```yaml
+ - uses: getsentry/action-release@v3
+ with:
+ environment: 'production'
+ release: 'v1.0.1'
+ ```
- Create a new Sentry release for [Self-Hosted Sentry](https://develop.sentry.dev/self-hosted/)
- ```yaml
- - uses: getsentry/action-release@v3
- env:
- SENTRY_URL: https://sentry.example.com/
- ```
+ ```yaml
+ - uses: getsentry/action-release@v3
+ env:
+ SENTRY_URL: https://sentry.example.com/
+ ```
+
+- Manually specify the commit range for the release.
+ ```yaml
+ - uses: getsentry/action-release@v3
+ with:
+ set_commits: manual
+ repo: your-org/your-repo
+ commit: ${{ github.sha }}
+ previous_commit:
+ ```
## Contributing
@@ -135,36 +147,36 @@ Suggestions and issues can be posted on the repository's
- Forgetting to include the required environment variables
(`SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, and `SENTRY_PROJECT`), yields an error that looks like:
- ```text
- Environment variable SENTRY_ORG is missing an organization slug
- ```
+ ```text
+ Environment variable SENTRY_ORG is missing an organization slug
+ ```
- Building and running this action locally on an unsupported environment yields an error that looks like:
- ```text
- Syntax error: end of file unexpected (expecting ")")
- ```
+ ```text
+ Syntax error: end of file unexpected (expecting ")")
+ ```
- When adding the action, make sure to first check out your repo with `actions/checkout@v4`.
-Otherwise, it could fail at the `propose-version` step with the message:
+ Otherwise, it could fail at the `propose-version` step with the message:
- ```text
- error: Could not automatically determine release name
- ```
+ ```text
+ error: Could not automatically determine release name
+ ```
- In `actions/checkout@v4` the default fetch depth is 1. If you're getting the error message:
- ```text
- error: Could not find the SHA of the previous release in the git history. Increase your git clone depth.
- ```
+ ```text
+ error: Could not find the SHA of the previous release in the git history. Increase your git clone depth.
+ ```
- you can fetch all history for all branches and tags by setting the `fetch-depth` to zero like so:
+ you can fetch all history for all branches and tags by setting the `fetch-depth` to zero like so:
- ```yaml
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- ```
+ ```yaml
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ```
- Not finding the repository
@@ -176,12 +188,12 @@ Otherwise, it could fail at the `propose-version` step with the message:
Ensure you use `actions/checkout` before running the action
```yaml
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - uses: getsentry/action-release@v3
- with:
- environment: 'production'
- release: 'v1.0.1'
- ```
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - uses: getsentry/action-release@v3
+ with:
+ environment: 'production'
+ release: 'v1.0.1'
+ ```
diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts
index fb6abdc2..aa59ae77 100644
--- a/__tests__/main.test.ts
+++ b/__tests__/main.test.ts
@@ -11,6 +11,7 @@ import {
getProjects,
getUrlPrefixOption,
getWorkingDirectory,
+ getSetCommitsManualOptions,
} from '../src/options';
describe('options', () => {
@@ -196,13 +197,37 @@ describe('options', () => {
process.env['INPUT_SET_COMMITS'] = 'skip';
expect(getSetCommitsOption()).toBe('skip');
});
+ it('manual', () => {
+ process.env['INPUT_SET_COMMITS'] = 'manual';
+ expect(getSetCommitsOption()).toBe('manual');
+ });
it('bad option', () => {
- const errorMessage = 'set_commits must be "auto" or "skip"';
+ const errorMessage = 'set_commits must be "auto", "skip" or "manual"';
process.env['INPUT_SET_COMMITS'] = 'bad';
expect(() => getSetCommitsOption()).toThrow(errorMessage);
});
});
+ describe('getSetCommitsManualOptions', () => {
+ afterEach(() => {
+ delete process.env['INPUT_SET_COMMITS'];
+ delete process.env['INPUT_REPO'];
+ delete process.env['INPUT_COMMIT'];
+ delete process.env['INPUT_PREVIOUS_COMMIT'];
+ });
+ it('manual', () => {
+ process.env['INPUT_SET_COMMITS'] = 'manual';
+ process.env['INPUT_REPO'] = 'repo';
+ process.env['INPUT_COMMIT'] = 'commit';
+ process.env['INPUT_PREVIOUS_COMMIT'] = 'previous-commit';
+ expect(getSetCommitsManualOptions()).toEqual({
+ repo: 'repo',
+ commit: 'commit',
+ previousCommit: 'previous-commit',
+ });
+ });
+ });
+
describe('getProjects', () => {
afterEach(() => {
delete process.env['SENTRY_PROJECT'];
diff --git a/action.yml b/action.yml
index 94b93e3b..b10ce2e9 100644
--- a/action.yml
+++ b/action.yml
@@ -76,7 +76,23 @@ inputs:
set_commits:
description: |-
Specify whether to set commits for the release.
- One of: "auto", "skip"
+ When "manual", you need to provide the repository, commit, and previous commit.
+ One of: "auto", "skip", "manual"
+ required: false
+ repo:
+ description: |-
+ The repository to set commits for in "repo-owner/repo-name" format.
+ Only used when "set_commits" is "manual".
+ required: false
+ commit:
+ description: |-
+ The commit SHA of the current release you are creating.
+ Only used when "set_commits" is "manual".
+ required: false
+ previous_commit:
+ description: |-
+ The commit SHA of the previous release.
+ Required when "set_commits" is "manual".
required: false
projects:
description: |-
@@ -142,13 +158,16 @@ runs:
INPUT_VERSION_PREFIX: ${{ inputs.version_prefix }}
INPUT_RELEASE_PREFIX: ${{ inputs.release_prefix }}
INPUT_SET_COMMITS: ${{ inputs.set_commits }}
+ INPUT_REPO: ${{ inputs.repo }}
+ INPUT_COMMIT: ${{ inputs.commit }}
+ INPUT_PREVIOUS_COMMIT: ${{ inputs.previous_commit }}
INPUT_PROJECTS: ${{ inputs.projects }}
INPUT_URL_PREFIX: ${{ inputs.url_prefix }}
INPUT_STRIP_COMMON_PREFIX: ${{ inputs.strip_common_prefix }}
INPUT_WORKING_DIRECTORY: ${{ inputs.working_directory }}
INPUT_DISABLE_TELEMETRY: ${{ inputs.disable_telemetry }}
INPUT_DISABLE_SAFE_DIRECTORY: ${{ inputs.disable_safe_directory }}
- uses: docker://ghcr.io/getsentry/action-release-image:master
+ uses: docker://ghcr.io/getsentry/action-release-image:ab-add-manual-commit-range
# For actions running on macos or windows runners, we use a composite
# action approach which allows us to install the arch specific sentry-cli
@@ -204,6 +223,9 @@ runs:
INPUT_VERSION_PREFIX: ${{ inputs.version_prefix }}
INPUT_RELEASE_PREFIX: ${{ inputs.release_prefix }}
INPUT_SET_COMMITS: ${{ inputs.set_commits }}
+ INPUT_REPO: ${{ inputs.repo }}
+ INPUT_COMMIT: ${{ inputs.commit }}
+ INPUT_PREVIOUS_COMMIT: ${{ inputs.previous_commit }}
INPUT_PROJECTS: ${{ inputs.projects }}
INPUT_URL_PREFIX: ${{ inputs.url_prefix }}
INPUT_STRIP_COMMON_PREFIX: ${{ inputs.strip_common_prefix }}
diff --git a/dist/index.js b/dist/index.js
index 03f976d3..102c0ce7 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -122752,11 +122752,21 @@ const telemetry_1 = __nccwpck_require__(12417);
if (setCommitsOption !== 'skip') {
yield (0, telemetry_1.traceStep)('set-commits', () => __awaiter(void 0, void 0, void 0, function* () {
core.debug(`Setting commits with option '${setCommitsOption}'`);
- yield (0, cli_1.getCLI)().setCommits(release, {
- auto: true,
- ignoreMissing,
- ignoreEmpty,
- });
+ if (setCommitsOption === 'auto') {
+ yield (0, cli_1.getCLI)().setCommits(release, {
+ auto: true,
+ ignoreMissing,
+ ignoreEmpty,
+ });
+ }
+ else if (setCommitsOption === 'manual') {
+ const { repo, commit, previousCommit } = options.getSetCommitsManualOptions();
+ if (!repo || !commit) {
+ throw new Error('Options `repo` and `commit` are required when `set_commits` is `manual`');
+ }
+ yield (0, cli_1.getCLI)().setCommits(release, Object.assign({ auto: false, repo,
+ commit }, (previousCommit && { previousCommit })));
+ }
}));
}
Sentry.setTag('sourcemaps', sourcemaps.length > 0);
@@ -122860,7 +122870,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.getWorkingDirectory = exports.getUrlPrefixOption = exports.getProjects = exports.checkEnvironmentVariables = exports.getSetCommitsOption = exports.getBooleanOption = exports.getDist = exports.getSourcemaps = exports.getStartedAt = exports.getEnvironment = exports.getRelease = void 0;
+exports.getWorkingDirectory = exports.getUrlPrefixOption = exports.getProjects = exports.checkEnvironmentVariables = exports.getSetCommitsManualOptions = exports.getSetCommitsOption = exports.getBooleanOption = exports.getDist = exports.getSourcemaps = exports.getStartedAt = exports.getEnvironment = exports.getRelease = void 0;
const core = __importStar(__nccwpck_require__(42186));
const path_1 = __importDefault(__nccwpck_require__(71017));
const cli_1 = __nccwpck_require__(56733);
@@ -122993,11 +123003,20 @@ const getSetCommitsOption = () => {
return 'auto';
case 'skip':
return 'skip';
+ case 'manual':
+ return 'manual';
default:
- throw Error('set_commits must be "auto" or "skip"');
+ throw Error('set_commits must be "auto", "skip" or "manual"');
}
};
exports.getSetCommitsOption = getSetCommitsOption;
+const getSetCommitsManualOptions = () => {
+ const repo = core.getInput('repo');
+ const commit = core.getInput('commit');
+ const previousCommit = core.getInput('previous_commit');
+ return { repo, commit, previousCommit };
+};
+exports.getSetCommitsManualOptions = getSetCommitsManualOptions;
/**
* Check for required environment variables.
*/
diff --git a/src/main.ts b/src/main.ts
index daff77ce..0bf8ac44 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -50,11 +50,27 @@ withTelemetry(
if (setCommitsOption !== 'skip') {
await traceStep('set-commits', async () => {
core.debug(`Setting commits with option '${setCommitsOption}'`);
- await getCLI().setCommits(release, {
- auto: true,
- ignoreMissing,
- ignoreEmpty,
- });
+
+ if (setCommitsOption === 'auto') {
+ await getCLI().setCommits(release, {
+ auto: true,
+ ignoreMissing,
+ ignoreEmpty,
+ });
+ } else if (setCommitsOption === 'manual') {
+ const { repo, commit, previousCommit } = options.getSetCommitsManualOptions();
+
+ if (!repo || !commit) {
+ throw new Error('Options `repo` and `commit` are required when `set_commits` is `manual`');
+ }
+
+ await getCLI().setCommits(release, {
+ auto: false,
+ repo,
+ commit,
+ ...(previousCommit && { previousCommit }),
+ });
+ }
});
}
diff --git a/src/options.ts b/src/options.ts
index a1afad80..77d23f36 100644
--- a/src/options.ts
+++ b/src/options.ts
@@ -127,7 +127,7 @@ export const getBooleanOption = (input: string, defaultValue: boolean): boolean
throw Error(`${input} is not a boolean`);
};
-export const getSetCommitsOption = (): 'auto' | 'skip' => {
+export const getSetCommitsOption = (): 'auto' | 'skip' | 'manual' => {
let setCommitOption = core.getInput('set_commits');
// default to auto
if (!setCommitOption) {
@@ -140,11 +140,20 @@ export const getSetCommitsOption = (): 'auto' | 'skip' => {
return 'auto';
case 'skip':
return 'skip';
+ case 'manual':
+ return 'manual';
default:
- throw Error('set_commits must be "auto" or "skip"');
+ throw Error('set_commits must be "auto", "skip" or "manual"');
}
};
+export const getSetCommitsManualOptions = (): { repo: string; commit: string; previousCommit: string } => {
+ const repo = core.getInput('repo');
+ const commit = core.getInput('commit');
+ const previousCommit = core.getInput('previous_commit');
+
+ return { repo, commit, previousCommit };
+};
/**
* Check for required environment variables.
*/