Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a "Prepare release" workflow for classic buildpacks #184

Merged
merged 4 commits into from
Jan 26, 2024
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
101 changes: 101 additions & 0 deletions .github/workflows/_classic-buildpack-prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: _classic-buildpack-prepare-release

on:
workflow_call:
inputs:
custom_update_command:
description: An additional command to run before changes are committed, which can make use of the env vars EXISTING_VERSION and NEW_VERSION.
type: string
required: false

defaults:
run:
# Setting an explicit bash shell ensures GitHub Actions enables pipefail mode too,
# rather than only error on exit (improving failure UX when pipes are used). See:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
shell: bash

jobs:
prepare-release:
name: Prepare Release
runs-on: pub-hk-ubuntu-22.04-small
steps:
# We use our GitHub App's access token instead of GITHUB_TOKEN since otherwise other
# workflows (such as CI) won't automatically run on any PRs opened by this workflow:
# https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
- name: Generate access token for Linguist GitHub App
uses: heroku/use-app-token-action@main
id: generate-token
with:
app_id: ${{ vars.LINGUIST_GH_APP_ID }}
# Note: The calling workflow must enable secrets inheritance for this variable to be accessible:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsecretsinherit
private_key: ${{ secrets.LINGUIST_GH_PRIVATE_KEY }}

- name: Checkout
uses: actions/checkout@v4
with:
# We always want the version bump/changelog and resultant PR to target main, not the branch of the workflow_dispatch.
ref: main
# Tags are not fetched by default, but we need them to determine the existing buildpack version.
fetch-tags: true
# Force a full clone, otherwise fetch-tags doesn't actually fetch any tags:
# https://github.com/actions/checkout/issues/1471
fetch-depth: 0
token: ${{ steps.generate-token.outputs.app_token }}

- name: Determine existing tagged version
id: existing-version
run: echo "version=$(git tag --list 'v*' --sort '-version:refname' | head --lines 1 | tr --delete 'v')" >> "${GITHUB_OUTPUT}"

- name: Calculate new version
id: new-version
run: echo "version=$(( ${{ steps.existing-version.outputs.version }} + 1 ))" >> "${GITHUB_OUTPUT}"

- name: Update changelog
run: |
EXISTING_VERSION='${{ steps.existing-version.outputs.version }}'
NEW_VERSION='${{ steps.new-version.outputs.version }}'
DATE_TODAY="$(date --utc --iso-8601)"
UNRELEASED_URL="https://github.com/${{ github.repository }}/compare/v${NEW_VERSION}...main"
NEW_VERSION_URL="https://github.com/${{ github.repository }}/compare/v${EXISTING_VERSION}...v${NEW_VERSION}"

sed --in-place --regexp-extended \
--expression "s~(^## \[Unreleased\])$~\1\n\n\n## [v${NEW_VERSION}] - ${DATE_TODAY}~" \
--expression "s~(^\[unreleased\]:) .*$~\1 ${UNRELEASED_URL}\n[v${NEW_VERSION}]: ${NEW_VERSION_URL}~" \
CHANGELOG.md

- name: Run custom update command
if: inputs.custom_update_command != ''
run: ${{ inputs.custom_update_command }}
env:
EXISTING_VERSION: ${{ steps.existing-version.outputs.version }}
NEW_VERSION: ${{ steps.new-version.outputs.version }}

- name: Generate list of unreleased commits
id: unreleased-commits
run: echo "commits=$(git log --topo-order --reverse --format='- %s' v${{ steps.existing-version.outputs.version }}...main)" >> "${GITHUB_OUTPUT}"

- name: Create pull request
id: pr
uses: peter-evans/create-pull-request@v5.0.2
with:
token: ${{ steps.generate-token.outputs.app_token }}
title: Prepare release v${{ steps.new-version.outputs.version }}
body: |
Commits since the last release:
${{ steps.unreleased-commits.outputs.commits }}

For the full diff, see the compare view:
https://github.com/${{ github.repository }}/compare/v${{ steps.existing-version.outputs.version }}...main
commit-message: Prepare release v${{ steps.new-version.outputs.version }}
branch: prepare-release
delete-branch: true
committer: ${{ vars.LINGUIST_GH_APP_USERNAME }} <${{ vars.LINGUIST_GH_APP_EMAIL }}>
author: ${{ vars.LINGUIST_GH_APP_USERNAME }} <${{ vars.LINGUIST_GH_APP_EMAIL }}>

- name: Enable pull request auto-merge
if: steps.pr.outputs.pull-request-operation == 'created'
run: gh pr merge --auto --squash "${{ steps.pr.outputs.pull-request-number }}"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.app_token }}
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,43 @@ jobs:
| `docker_hub_user` | The username to login to Docker Hub with | true |
| `docker_hub_token` | The token to login to Docker Hub with | true |

### Classic Buildpack - Prepare Release

Prepares a "classic" buildpack release by:
- updating the changelog
- opening a PR against the repository with the modified files

You can pin to:
- the [latest release](https://github.com/heroku/languages-github-actions/releases/latest) version with `@latest`
- a [specific release](https://github.com/heroku/languages-github-actions/releases) version with `@v{major}.{minor}.{patch}`
- the development version with `@main`

#### Example Usage

```yaml
name: Prepare Buildpack Release

on:
workflow_dispatch:

jobs:
prepare-release:
uses: heroku/languages-github-actions/.github/workflows/_classic-buildpack-prepare-release.yml@latest
secrets: inherit
```

#### Inputs

| Name | Description | Required | Default |
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------|----------|---------|
| `custom_update_command` | An additional command to run before changes are committed, which can make use of the env vars EXISTING_VERSION and NEW_VERSION | false | |

In addition, the workflow requires that the `LINGUIST_*` env vars are available (which are set as organization variables).

#### Secrets

The workflow requires that `inherit` mode be enabled, so that it can access the `LINGUIST_GH_PRIVATE_KEY` organization secret.

## Actions

### Install Languages CLI
Expand Down