diff --git a/.github/release-please-config.json b/.github/release-please-config.json index d316166..0a38fad 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -23,6 +23,10 @@ "actions/semconv/pull-request": { "component": "semconv-pull-request", "initial-version": "0.0.1" + }, + "actions/release-please": { + "component": "release-please", + "initial-version": "0.0.1" } }, "plugins": [ diff --git a/.github/release-please-manifest.json b/.github/release-please-manifest.json index d1eae3b..3ef0f52 100644 --- a/.github/release-please-manifest.json +++ b/.github/release-please-manifest.json @@ -1,3 +1,4 @@ { - "actions/semconv/pull-request": "0.0.1" + "actions/semconv/pull-request": "0.0.1", + "actions/release-please": "0.0.1" } diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 3611326..7a5d4a5 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -15,10 +15,11 @@ jobs: contents: write pull-requests: write steps: - # The PAT rather than github.token, so the release pull request and the - # tag it produces trigger the workflows that react to them. - - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + # The repository releases itself with the action it ships. + - uses: ./actions/release-please with: token: ${{ secrets.GH_PAT_RELEASE_PLEASE_ACTION }} - config-file: .github/release-please-config.json - manifest-file: .github/release-please-manifest.json diff --git a/actions/release-please/README.md b/actions/release-please/README.md new file mode 100644 index 0000000..6ff612d --- /dev/null +++ b/actions/release-please/README.md @@ -0,0 +1,106 @@ +# release-please + +Cuts releases with [release-please][release-please] from the configuration +every repository shares. + +## Usage + +```yaml +name: Release Please + +on: + push: + branches: [main] + +permissions: {} + +jobs: + release-please: + name: Release Please + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@ + with: + persist-credentials: false + - uses: TrogonStack/github-actions/actions/release-please@ + with: + token: ${{ secrets.GH_PAT_RELEASE_PLEASE_ACTION }} +``` + +The token must be the organization's personal access token rather than +`github.token`, because a tag pushed with `github.token` does not trigger the +workflows that react to a release. + +## Configuration + +The configuration is a file in your repository, because release-please fetches +it from the branch over the API rather than from the checkout. Where it lives +is fixed: + +``` +.github/release-please-config.json +.github/release-please-manifest.json +``` + +Those paths are not inputs. One location for every repository is the reason +this action exists; a knob invites back the drift it was built to remove. + +Start a repository from this configuration and change only `packages`: + +```json +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "simple", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "include-component-in-tag": true, + "include-v-in-tag": true, + "tag-separator": "@", + "separate-pull-requests": true, + "changelog-sections": [ + { "type": "feat", "section": "Features", "hidden": false }, + { "type": "fix", "section": "Bug Fixes", "hidden": false } + ], + "packages": { + ".": { "component": "your-component", "initial-version": "0.0.1" } + }, + "plugins": [{ "type": "sentence-case" }], + "draft": false, + "draft-pull-request": false, + "prerelease": false, + "signoff": "SHT Bot <61149376+sht-bot@users.noreply.github.com>" +} +``` + +The matching manifest starts every package at the sentinel: + +```json +{ ".": "0.0.0" } +``` + +`0.0.0` means "never released" to release-please, which is what makes it honour +`initial-version`. Any other starting value is read as a real previous release +and gets bumped instead, so the first tag skips the version you asked for. + +## Outputs + +`releases_created`, `paths_released`, `prs_created` and `prs` are the ones a +monorepo reads. `release_created`, `tag_name`, `sha`, `major`, `minor`, +`patch`, `html_url` and `upload_url` are set only when the repository releases +a single package. + +Release-please also sets per path outputs named after the path itself. A +composite action cannot forward a name it does not know in advance, so a +monorepo that needs them should read the `paths_released` array instead. + +## Inputs + +| Input | Default | Description | +| --- | --- | --- | +| `token` | required | Opens the release pull request and pushes the tag. | + +[release-please]: https://github.com/googleapis/release-please diff --git a/actions/release-please/action.yml b/actions/release-please/action.yml new file mode 100644 index 0000000..027fd0d --- /dev/null +++ b/actions/release-please/action.yml @@ -0,0 +1,64 @@ +name: Release Please +description: >- + Cuts releases with release-please from the configuration every repository + shares. +author: TrogonStack + +inputs: + token: + description: >- + Token used to open the release pull request and push the tag. A personal + access token rather than github.token, so the tag it produces triggers + the workflows that react to it. + required: true + +outputs: + releases_created: + description: Whether any release was created. + value: ${{ steps.release-please.outputs.releases_created }} + paths_released: + description: JSON array of the paths released, which is what a monorepo reads. + value: ${{ steps.release-please.outputs.paths_released }} + prs_created: + description: Whether any release pull request was created. + value: ${{ steps.release-please.outputs.prs_created }} + prs: + description: JSON array of the release pull requests opened or updated. + value: ${{ steps.release-please.outputs.prs }} + release_created: + description: Whether a release was created. Single package repositories only. + value: ${{ steps.release-please.outputs.release_created }} + tag_name: + description: The tag pushed. Single package repositories only. + value: ${{ steps.release-please.outputs.tag_name }} + sha: + description: The commit the release points at. Single package repositories only. + value: ${{ steps.release-please.outputs.sha }} + major: + description: Major version released. Single package repositories only. + value: ${{ steps.release-please.outputs.major }} + minor: + description: Minor version released. Single package repositories only. + value: ${{ steps.release-please.outputs.minor }} + patch: + description: Patch version released. Single package repositories only. + value: ${{ steps.release-please.outputs.patch }} + html_url: + description: URL of the release. Single package repositories only. + value: ${{ steps.release-please.outputs.html_url }} + upload_url: + description: Release asset upload URL. Single package repositories only. + value: ${{ steps.release-please.outputs.upload_url }} + +runs: + using: composite + steps: + - name: Release Please + id: release-please + uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 + with: + token: ${{ inputs.token }} + # These paths are deliberately not inputs: one location for every + # repository is the reason this action exists. + config-file: .github/release-please-config.json + manifest-file: .github/release-please-manifest.json