From 581ab889f48cfb8380b5bebd5e0381d7c9fd0f2a Mon Sep 17 00:00:00 2001 From: Romain Cascino Date: Tue, 2 Jun 2026 14:17:16 +0200 Subject: [PATCH] Port --dry-run and --include-subjects to the action; release v0.14.1 --- README.md | 24 ++++++++++++++++++++++++ VERSION | 2 +- action.yml | 9 +++++++++ run.sh | 10 ++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b083b7..712beb9 100644 --- a/README.md +++ b/README.md @@ -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 `..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 | @@ -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. @@ -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. diff --git a/VERSION b/VERSION index a803cc2..930e300 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.14.0 +0.14.1 diff --git a/action.yml b/action.yml index fd47485..aac6136 100644 --- a/action.yml +++ b/action.yml @@ -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 ..HEAD." required: false @@ -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 @@ -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 }} diff --git a/run.sh b/run.sh index e6dc993..9c39b0f 100644 --- a/run.sh +++ b/run.sh @@ -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 @@ -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") ;;