Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ Once installed, run it from your AI agent with `/linear-release-setup` (or just
| `version` | No | | Release version identifier (alias: `release_version`) |
| `stage` | No | | Deployment stage such as `staging` or `production` (required for `update`) |
| `include_paths` | No | | Filter commits by file paths (comma-separated globs for monorepos) |
| `include_subjects` | No | | Filter commits whose subject (first line) matches a regular expression. Composes with `include_paths`. |
| `base_ref` | No | | Override the `sync` scan base. Exclusive: scans `<base_ref>..HEAD` |
| `links` | No | | Links to attach to the targeted release, one per line. Each value must be either an absolute URL or `Label=URL`. |
| `documents` | No | | Documents to attach to the targeted release, one per line as `[Title=]path/to/file.md` (title inferred from the filename if omitted). Existing documents with the same title are updated. |
| `release_notes` | No | | Path to a markdown file used as the release notes for this release. |
| `dry_run` | No | `false` | When `true`, scan commits and call read-only Linear APIs but skip the create/update mutations. Logs the action that would have been taken; no release is created or modified. |
| `log_level` | No | | Log verbosity: `quiet` or `verbose`. Omit for default output. |
| `timeout` | No | `60` | Maximum time in seconds to wait for the command to complete |
| `cli_version` | No | `v0.14.0` | Linear Release CLI version to install |
Expand Down Expand Up @@ -155,6 +157,17 @@ Filter commits by file paths to track releases for specific packages, useful for
include_paths: apps/web/**,packages/shared/**
```

### Subject filtering

Use `include_subjects` to only scan commits whose subject (first line) matches a regular expression. Useful when the default commit range pulls in noise — direct pushes without issue links, bot commits, or merge commits you don't want appearing in releases. It composes with `include_paths`: a commit must pass both filters to be scanned.

```yaml
- uses: linear/linear-release-action@v0
with:
access_key: ${{ secrets.LINEAR_ACCESS_KEY }}
include_subjects: "[A-Z]{2,}-[0-9]+"
```

### Scan base override

Use `base_ref` to explicitly choose the exclusive lower bound for `sync`'s commit scan. This is useful when the automatically selected release baseline is not the range you want for a custom branching workflow, first-time onboarding, or migration.
Expand Down Expand Up @@ -205,6 +218,17 @@ Attach release notes and supporting documents generated by your workflow. `relea

File paths are relative to the workflow's working directory. Omit `Title=` to infer the title from the filename (e.g. `docs/CHANGELOG.md` → `CHANGELOG`).

### Dry run

Set `dry_run: true` to preview what the action would do without touching Linear. It scans commits and calls read-only Linear APIs (recent releases, pipeline settings), logs the release it would have created or updated, then stops before any mutation. No release is created or modified, and the action outputs are empty. Works with `sync`, `complete`, and `update`.

```yaml
- uses: linear/linear-release-action@v0
with:
access_key: ${{ secrets.LINEAR_ACCESS_KEY }}
dry_run: true
```

## Versioning

Each release of this action defaults to a specific [Linear Release CLI](https://github.com/linear/linear-release) version. Pinning the action — whether by tag (`@v0`) or commit SHA — also pins the CLI. Set `cli_version` to override.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.14.0
0.14.1
9 changes: 9 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ inputs:
include_paths:
description: Filter commits by file paths using comma-separated globs (e.g., "apps/web/**,packages/**"). Useful for monorepos.
required: false
include_subjects:
description: Filter commits whose subject (first line) matches a regular expression (e.g., "[A-Z]{2,}-[0-9]+"). Composes with include_paths.
required: false
base_ref:
description: "Override the sync scan base. Exclusive: scans <base_ref>..HEAD."
required: false
Expand All @@ -41,6 +44,10 @@ inputs:
release_notes:
description: Path to a markdown file used as the release notes for this release.
required: false
dry_run:
description: 'When "true", scan commits and call read-only Linear APIs but skip the create/update mutations. Logs the action that would have been taken; no release is created or modified.'
required: false
default: "false"
log_level:
description: Log verbosity. Use "quiet" for errors only or "verbose" for detailed progress. Omit for default output.
required: false
Expand Down Expand Up @@ -87,10 +94,12 @@ runs:
INPUT_RELEASE_VERSION: ${{ inputs.release_version }}
INPUT_STAGE: ${{ inputs.stage }}
INPUT_INCLUDE_PATHS: ${{ inputs.include_paths }}
INPUT_INCLUDE_SUBJECTS: ${{ inputs.include_subjects }}
INPUT_BASE_REF: ${{ inputs.base_ref }}
INPUT_LINKS: ${{ inputs.links }}
INPUT_DOCUMENTS: ${{ inputs.documents }}
INPUT_RELEASE_NOTES: ${{ inputs.release_notes }}
INPUT_DRY_RUN: ${{ inputs.dry_run }}
INPUT_LOG_LEVEL: ${{ inputs.log_level }}
INPUT_TIMEOUT: ${{ inputs.timeout }}

Expand Down
10 changes: 10 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ args=()
[[ -n "${INPUT_VERSION:-}" ]] && args+=("--release-version=${INPUT_VERSION}")
[[ -n "${INPUT_STAGE:-}" ]] && args+=("--stage=${INPUT_STAGE}")
[[ -n "${INPUT_INCLUDE_PATHS:-}" ]] && args+=("--include-paths=${INPUT_INCLUDE_PATHS}")
[[ -n "${INPUT_INCLUDE_SUBJECTS:-}" ]] && args+=("--include-subjects=${INPUT_INCLUDE_SUBJECTS}")
[[ -n "${INPUT_BASE_REF:-}" ]] && args+=("--base-ref=${INPUT_BASE_REF}")
if [[ -n "${INPUT_LINKS:-}" ]]; then
while IFS= read -r link || [[ -n "$link" ]]; do
Expand All @@ -65,6 +66,15 @@ fi
[[ -n "${INPUT_RELEASE_NOTES:-}" ]] && args+=("--release-notes-file=${INPUT_RELEASE_NOTES}")
[[ -n "${INPUT_TIMEOUT:-}" ]] && args+=("--timeout=${INPUT_TIMEOUT}")

case "${INPUT_DRY_RUN:-false}" in
true) args+=("--dry-run") ;;
false|"") ;;
*)
echo "::error::Invalid dry_run '${INPUT_DRY_RUN}'. Must be: true or false"
exit 1
;;
esac

if [[ -n "${INPUT_LOG_LEVEL:-}" ]]; then
case "$INPUT_LOG_LEVEL" in
quiet) args+=("--quiet") ;;
Expand Down
Loading