release-app.yml
Create releases using release-please, optionally tag major/minor versions, and support automerge of generated PRs.
References: googleapis/release-please-action · googleapis/release-please
Inputs
| Input | Type | Description | Required | Default |
|---|---|---|---|---|
| ENABLE_PRERELEASE | boolean | Enable prerelease functionality | No | false |
| TAG_MAJOR_AND_MINOR | boolean | Tag major and minor versions | No | false |
| AUTOMERGE_PRERELEASE | boolean | Automatically merge the prerelease PR | No | false |
| AUTOMERGE_RELEASE | boolean | Automatically merge the release PR | No | false |
| PRERELEASE_BRANCH | string | Branch to create the prerelease on | No | develop |
| RELEASE_BRANCH | string | Branch to create the release on | No | main |
| REBASE_PRERELEASE_BRANCH | boolean | Rebase prerelease branch on release after release | No | false |
| RELEASE_CONFIG_FILE | string | Release-please config file for release branch | No | release-please-config.json |
| RELEASE_MANIFEST_FILE | string | Release-please manifest file for release branch | No | .release-please-manifest.json |
| PRERELEASE_CONFIG_FILE | string | Release-please config file for prerelease branch | No | release-please-config-rc.json |
| PRERELEASE_MANIFEST_FILE | string | Release-please manifest file for prerelease branch | No | .release-please-manifest-rc.json |
| RELEASE_ASSET_PATHS | string | Comma-separated list of local file paths to upload as release assets (e.g., dist/app-linux-amd64,dist/app-darwin-amd64) | No | - |
| RELEASE_ARTIFACT_NAMES | string | Artifact name or glob pattern matching one or more artifacts (uploaded by previous jobs via actions/upload-artifact) to download and attach to the release (e.g., my-binaries or my-app-*) | No | - |
| RUNS_ON | string | Runner labels as JSON array (e.g., '["ubuntu-24.04"]' or '["self-hosted", "linux"]') | No | ["ubuntu-24.04"] |
Secrets
| Secret | Description | Required | Default |
|---|---|---|---|
| GH_PAT | GitHub Personal Access Token (required for automerge, see Token setup) | No | - |
Outputs
| Output | Description |
|---|---|
| release-created | Whether a release was created in this run |
| version | Full semver value (e.g., 1.2.3) |
| major-tag | Major version tag (e.g., 1) |
| minor-tag | Minor version tag (e.g., 2) |
| patch-tag | Patch version tag (e.g., 3) |
Permissions
| Scope | Access | Description |
|---|---|---|
| contents | write | Create tags/commits and update manifest files |
| issues | write | Create or update issues opened by release tooling |
| pull-requests | write | Create, update, and optionally merge release PRs |
Token setup
The GH_PAT secret is only required when AUTOMERGE_PRERELEASE or AUTOMERGE_RELEASE is enabled. It must be a GitHub Personal Access Token stored as a repository secret named GH_PAT in the repository that runs this workflow.
The automerge step uses gh pr merge --rebase with either --auto or --admin:
- If the repository has Settings > General > Allow auto-merge enabled, the workflow uses
--auto(the PR merges automatically once all required status checks pass). - Otherwise, it falls back to
--adminwhich force-merges immediately, bypassing branch protection rules.
Fine-grained PAT (recommended)
Create a fine-grained personal access token scoped to the current repository with the following permissions:
| Permission | Access | Reason |
|---|---|---|
| Contents | Read & Write | Push commits (manifest sync, rebase branch) |
| Pull requests | Read & Write | Enable auto-merge on release PRs |
If the repository does not have "Allow auto-merge" enabled, the PAT owner must be a repository admin for the
--adminmerge to succeed.
Classic PAT
Alternatively, create a classic token with the repo scope.
Where to store it
Add the token as a repository secret named GH_PAT:
Settings > Secrets and variables > Actions > New repository secret
Notes
- Set
ENABLE_PRERELEASE: falseto disable all prerelease functionality and work only with release branches. - Config and manifest files are configurable via inputs, with sensible defaults for both release and prerelease workflows.
- On
RELEASE_BRANCH(defaultmain), uses the files specified byRELEASE_CONFIG_FILEandRELEASE_MANIFEST_FILE. - On
PRERELEASE_BRANCH(defaultdevelop), uses the files specified byPRERELEASE_CONFIG_FILEandPRERELEASE_MANIFEST_FILE(only whenENABLE_PRERELEASE: true). - If
TAG_MAJOR_AND_MINOR: true, tagsv<major>andv<major>.<minor>after a release is created. - If
AUTOMERGE_*is enabled and a PAT is provided, attempts to automerge the release PR. - Optionally rebases
PRERELEASE_BRANCHontoRELEASE_BRANCHafter a release whenREBASE_PRERELEASE_BRANCH: true(only whenENABLE_PRERELEASE: true). RELEASE_ASSET_PATHSuploads files that are already present on the runner filesystem.RELEASE_ARTIFACT_NAMESaccepts a name or glob pattern — the matching artifacts are downloaded viaactions/download-artifactbefore being attached to the release; both inputs can be used together.
Configuration
Release-please requires a config file and a manifest file in the repository root. The manifest tracks the current version and is updated automatically on each release.
Release config (release-please-config.json)
Minimal config for a single-package repository using the node release type (adjusts package.json version). See the release-please docs for all available options and release types.
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"packages": {
".": {
"release-type": "node",
"initial-version": "0.0.1",
"include-component-in-tag": false,
"versioning": "prerelease",
"prerelease": false,
"prerelease-type": "",
"extra-files": []
}
}
}Release manifest (.release-please-manifest.json)
Tracks the current version for each package path. Release-please updates this file automatically — set the initial version to your current release.
{
".": "0.0.1"
}Prerelease config (release-please-config-rc.json)
Used when ENABLE_PRERELEASE: true. Identical structure to the release config but adds prerelease-type to control the prerelease identifier appended to the version.
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"release-type": "node",
"prerelease-type": "rc",
"packages": {
".": {
"release-type": "node",
"initial-version": "0.0.1",
"include-component-in-tag": false,
"versioning": "prerelease",
"prerelease": true,
"prerelease-type": "rc",
"extra-files": []
}
}
}Prerelease manifest (.release-please-manifest-rc.json)
{
".": "0.0.1"
}Examples
The examples cover the main release scenarios: a full setup with prerelease support, a release-only flow, and a build that attaches compiled binaries to the GitHub Release.
Simple example
Full two-branch setup with develop for prereleases and main for stable releases. AUTOMERGE_*: true requires a PAT with sufficient permissions to bypass branch protection rules. REBASE_PRERELEASE_BRANCH: true keeps develop rebased onto main automatically after each stable release.
jobs:
release:
uses: this-is-tobi/github-workflows/.github/workflows/release-app.yml@v0
permissions:
contents: write
issues: write
pull-requests: write
with:
ENABLE_PRERELEASE: true
TAG_MAJOR_AND_MINOR: true
AUTOMERGE_PRERELEASE: true
AUTOMERGE_RELEASE: true
REBASE_PRERELEASE_BRANCH: true
# Optional: customize config and manifest files
RELEASE_CONFIG_FILE: custom-release-config.json
PRERELEASE_CONFIG_FILE: custom-prerelease-config.json
secrets:
GH_PAT: ${{ secrets.GH_PAT }}Release-only workflow
Single-branch workflow targeting only main. No prerelease config files are required. TAG_MAJOR_AND_MINOR: true adds convenience aliases (v1, v1.2) to each stable release tag.
jobs:
release:
uses: this-is-tobi/github-workflows/.github/workflows/release-app.yml@v0
permissions:
contents: write
issues: write
pull-requests: write
with:
ENABLE_PRERELEASE: false
TAG_MAJOR_AND_MINOR: true
AUTOMERGE_RELEASE: true
secrets:
GH_PAT: ${{ secrets.GH_PAT }}Attach build artifacts to the release
Two options are available depending on where the artifacts live.
Option 1 — files on the runner filesystem (RELEASE_ASSET_PATHS): use this when the files are produced in the same job (or already present on the runner).
jobs:
release:
uses: this-is-tobi/github-workflows/.github/workflows/release-app.yml@v0
permissions:
contents: write
issues: write
pull-requests: write
with:
ENABLE_PRERELEASE: false
RELEASE_ASSET_PATHS: "dist/my-app-linux-amd64,dist/my-app-darwin-amd64"
secrets:
GH_PAT: ${{ secrets.GH_PAT }}Option 2 — artifacts from a previous job (RELEASE_ARTIFACT_NAMES): accepts a name or glob pattern — matching artifacts uploaded via actions/upload-artifact in the same run are downloaded automatically before being attached to the release.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Build
run: make build
- uses: actions/upload-artifact@v7
with:
name: my-app-binaries
path: dist/
release:
needs: build
uses: this-is-tobi/github-workflows/.github/workflows/release-app.yml@v0
permissions:
contents: write
issues: write
pull-requests: write
with:
ENABLE_PRERELEASE: false
RELEASE_ARTIFACT_NAMES: "my-app-binaries" # or a glob like "my-app-*"
secrets:
GH_PAT: ${{ secrets.GH_PAT }}Both inputs can be combined when some files are local and others come from previous jobs.