Skip to content

Create GitHub Actions for Publishing Release Notes

Tiffany Forkner edited this page Apr 2, 2025 · 8 revisions

Important

All of the files in this section should be created in the main branch.

Create GitHub Actions Composite Action for Creating a Release Note Post

Create the file .github/actions/create-release-note-post/action.yml that will get the release information from the GitHub API and then use that information to make a new release note post.

name: Create Release Note Post
description: retrieves the release data from the API and creates a release post
inputs:
  tag:  # tag for release
    description: 'The tag of the release to create a post for'
    required: true
  token:
    description: 'GitHub Token'
    required: true
outputs:
  filename:
    description: "The name of the post file created"
    value: ${{ steps.filename.outputs.filename }}
runs:
  using: "composite"
  steps:
    - name: Get Release Info
      uses: octokit/[email protected]
      id: get-release
      with:
        route: /repos/${{ github.repository }}/releases/tags/${{ inputs.tag }}
      env:
        GITHUB_TOKEN: ${{ inputs.token }}
    - name: Format Published At Date
      shell: bash
      run: |
        published_at=$(echo ${{ fromJson(steps.get-release.outputs.data).published_at }}| cut -d "T" -f 1)
        echo "PUB_DATE=$published_at" >> "$GITHUB_ENV"
    - name: Create Filename
      id: filename
      shell: bash
      run: |
        # Normalize the tag name to replace the `.` with `-`
        tag_name=$(echo "${{ inputs.tag }}" | sed "s/\./-/g")
        name="$PUB_DATE-$tag_name"
        echo "post_name=$name" >> "$GITHUB_OUTPUT"
        echo "filename=$name.md" >> "$GITHUB_OUTPUT"
    - name: Create Post File
      shell: bash
      run: |
        cat <<EOF > ${{ steps.filename.outputs.filename }}
        ---
        title: ${{ fromJson(steps.get-release.outputs.data).name }}
        tag: ${{ inputs.tag }}
        category: release
        date: $PUB_DATE
        created_at: ${{ fromJson(steps.get-release.outputs.data).created_at }}
        published_at: ${{ fromJson(steps.get-release.outputs.data).published_at }}
        author: ${{ fromJson(steps.get-release.outputs.data).author.login }}
        author_avatar: ${{ fromJson(steps.get-release.outputs.data).author.avatar_url }}
        author_url: ${{ fromJson(steps.get-release.outputs.data).author.html_url }}
        html_url: ${{ fromJson(steps.get-release.outputs.data).html_url }}
        prerelease: ${{ fromJson(steps.get-release.outputs.data).prerelease }}
        ---

        ${{ fromJson(steps.get-release.outputs.data).body }}
        EOF

Create GitHub Actions Workflow for Publishing a Single Release Note

Create the file .github/workflows/release-notes.yml that will be triggered on release or manually on a specified tag. It uses the create-release-note-post action from above to create the release note post for the current release or specified tag and uploads that artifact. Then it calls the push-to-gh-pages workflow and pushes that file to the gh-pages branch.

name: Publish Release Notes

on:
  workflow_dispatch:
    inputs:
      TAG:
        type: string
        required: true
  release:
    types: [prereleased, released]

# this action needs the same permissions as the Push to GitHub Pages action because it is calling it
permissions:
  contents: write
  actions: read

jobs:
  generate-post:
    name: Generate Release Post
    runs-on: ubuntu-latest
    env:
      TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.TAG }}
    outputs:
      tag: ${{ env.TAG }}
      artifact_id: ${{ steps.post.outputs.filename }}
    steps:
      - uses: actions/checkout@v4
      - id: post
        uses: ./.github/actions/create-release-note-post
        with:
          tag: ${{ env.TAG }}
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Upload Release Note
        uses: actions/upload-artifact@v4
        with:
          name: ${{ steps.post.outputs.filename }}
          path: ${{ steps.post.outputs.filename }}
          retention-days: 30

  publish:
    needs: [generate-post]
    uses: ./.github/workflows/push-to-gh-pages.yml
    with:
      FILE_1_ARTIFACT_ID: ${{ needs.generate-post.outputs.artifact_id }}
      FILE_1_DEPLOY_TO: _posts/releases/
      COMMIT_MSG: "adding release ${{ needs.generate-post.outputs.tag }} to the release notes"
      URL_PATH: releases/
    secrets: inherit # allow called workflow to use GitHub secrets

Create GitHub Actions Workflow for Publishing Multiple Release Notes

Create the file .github/workflows/process-multiple-releases.yml that will retrieve a list of tags, create a release note post for each tag, and then push all of the notes to the gh-pages branch at once. The workflow input allows for paging through the list of tags by specifying PER_PAGE, which is the number of tags per query (max 100), and PAGE, which is the subset of tags to start with (PER_PAGE * PAGE = the initial index of the tag to start with).

name: Publish Multiple Release Notes

on:
  workflow_dispatch:
    inputs:
      PER_PAGE:
        type: number
        required: false
        default: 30
      PAGE:
        type: number
        required: false
        default: 1

# this action needs the same permissions as the Push to GitHub Pages action because it is calling it
permissions:
  contents: write
  actions: read

jobs:
  get-all-tags:
    name: Get All Tags
    runs-on: ubuntu-latest
    outputs:
      tags: ${{ steps.tag-names.outputs.tags }}
    steps:
      - name: Get Tags
        uses: octokit/[email protected]
        id: get-tags
        with:
          route: /repos/${{ github.repository }}/tags?per_page=${{ inputs.PER_PAGE <= 100 && inputs.PER_PAGE || 30 }}&page=${{ inputs.PAGE }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Get Tag Names
        id: tag-names
        run: |
          TAGS=$(echo '${{ steps.get-tags.outputs.data }}' | jq -c '[.[].name]' )
          echo $TAGS
          echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
          if [[ $TAGS == "[]" ]]; then
            echo "Nothing to process" >> "$GITHUB_STEP_SUMMARY"
          fi

  create-posts:
    needs: get-all-tags
    if: needs.get-all-tags.outputs.tags != '[]'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        tag: ${{ fromJson(needs.get-all-tags.outputs.tags) }}
    steps:
      - uses: actions/checkout@v4
      - id: post
        uses: ./.github/actions/create-release-note-post
        with:
          tag: ${{ matrix.tag }}
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Upload Release Note
        uses: actions/upload-artifact@v4
        with:
          name: release-note-${{ steps.post.outputs.filename }}
          path: ${{ steps.post.outputs.filename }}
          retention-days: 30

  push-to-pages:
    needs: [get-all-tags, create-posts]
    if: needs.get-all-tags.outputs.tags != '[]'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/create-github-app-token@v1
        id: app-token
        with:
          app-id: ${{ vars.APP_ID }}
          private-key: ${{ secrets.PRIVATE_KEY }}
      - name: Get GitHub App User ID
        id: get-user-id
        run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
        env:
          GH_TOKEN: ${{ steps.app-token.outputs.token }}
      - run: |
          git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]'
          git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com'
      - name: Checkout GitHub Pages Branch
        uses: actions/checkout@v4
        with:
          ref: gh-pages
          token: ${{ steps.app-token.outputs.token }}
      - name: Download Release Notes
        uses: actions/download-artifact@v4
        with:
          path: _posts/releases/
          pattern: release-note-*
          merge-multiple: true
      - name: Push to GitHub Pages Branch
        run: |
          git add -A
          if [[ -z $(git status --porcelain) ]]; then
            # if there were not changes, do nothing
            echo "Release was already added" >> "$GITHUB_STEP_SUMMARY"
          else
            git commit -am "Adding release notes for the following tags: ${{ needs.get-all-tags.outputs.tags }}"
            git pull origin gh-pages --rebase -s recursive -X ours
            git push
            echo "New URL: https://fearlesssolutions.github.io/publish-playwright/releases" >> "$GITHUB_STEP_SUMMARY"
          fi

Congratulations, you are finished! 🎉

Clone this wiki locally