From 8367a8bba3c234b059bd8b20982d951b46f5783e Mon Sep 17 00:00:00 2001 From: josefaidt Date: Mon, 14 Nov 2022 17:44:37 -0800 Subject: [PATCH 1/6] feat(actions): add reusable actions, release cleanup --- .../cleanup-discarded-release/action.yaml | 29 +++++++++ .../extract-version-from-branch/action.yaml | 22 +++++++ .../workflows/cleanup-discarded-release.yaml | 26 ++++++++ .github/workflows/create-release.yml | 64 ++++++++++++++++--- .github/workflows/release.yml | 9 +-- 5 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 .github/actions/cleanup-discarded-release/action.yaml create mode 100644 .github/actions/extract-version-from-branch/action.yaml create mode 100644 .github/workflows/cleanup-discarded-release.yaml diff --git a/.github/actions/cleanup-discarded-release/action.yaml b/.github/actions/cleanup-discarded-release/action.yaml new file mode 100644 index 00000000..ff6c07da --- /dev/null +++ b/.github/actions/cleanup-discarded-release/action.yaml @@ -0,0 +1,29 @@ +# used to extract the version from a release branch +# "release/1.0.0-next.0" -> "1.0.0-next.0" +name: cleanup-discarded-release +description: Cleans up discarded release artifacts such as branch and draft release +inputs: + github-token: + description: GitHub token needed for ops + default: ${{ github.token }} + required: true + version: + description: version of the discarded release (e.g. v1.0.0-next.0) + required: true + branch: + description: branch name (e.g. head_ref) + required: true +runs: + using: 'composite' + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: true + - name: delete-release-branch + run: git push origin --quiet --delete ${{ inputs.branch }} && echo 'deleted branch' || true + shell: bash + - name: delete-release-draft + run: gh release delete ${{ inputs.version }} && echo 'deleted release' || true + shell: bash + env: + GH_TOKEN: ${{ inputs.github-token }} diff --git a/.github/actions/extract-version-from-branch/action.yaml b/.github/actions/extract-version-from-branch/action.yaml new file mode 100644 index 00000000..d82bc310 --- /dev/null +++ b/.github/actions/extract-version-from-branch/action.yaml @@ -0,0 +1,22 @@ +# used to extract the version from a release branch +# "release/1.0.0-next.0" -> "1.0.0-next.0" +name: extract-version-from-branch +description: Extracts version from a branch name +inputs: + branch: + description: branch name (e.g. head_ref) + required: true +outputs: + version: + description: extracted version + value: ${{ steps.version.outputs.result }} +runs: + using: 'composite' + steps: + - name: extract-version + id: version + shell: bash + run: | + branch=${{ inputs.branch }} + version=${branch#release/} + echo "version=$version" >> $GITHUB_OUTPUT diff --git a/.github/workflows/cleanup-discarded-release.yaml b/.github/workflows/cleanup-discarded-release.yaml new file mode 100644 index 00000000..a0b06682 --- /dev/null +++ b/.github/workflows/cleanup-discarded-release.yaml @@ -0,0 +1,26 @@ +name: cleanup-discarded-release +on: + pull_request: + branches: + - main + types: + - closed +jobs: + cleanup: + runs-on: ubuntu-latest + if: | + github.event.pull_request.head.repo.full_name == github.repository && + startsWith(github.event.pull_request.head.ref, 'release/') + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false + - id: version + uses: ./.github/actions/extract-version-from-branch + with: + branch: ${{ github.head_ref }} + - uses: ./.github/actions/cleanup-discarded-release + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.head_ref }} + version: ${{ steps.version.outputs.version }} diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 96c2edbd..1519e736 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -16,6 +16,11 @@ on: required: true jobs: create-release: + permissions: + # needed to create release PR + pull-requests: write + # needed to create draft release + contents: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -26,14 +31,23 @@ jobs: run: | git config --global user.name "GitHub Actions" git config --global user.email noreply@github.com + - name: is-prerelease + id: is-prerelease + run: | + is=false + if [[ ${{ github.event.inputs.type }} == pre* ]] + then + is=true + fi + echo "is-prerelease=$is" >> $GITHUB_OUTPUT - name: set-version id: version run: | - if [[ ${{ github.event.inputs.type }} != pre* ]] + if [[ ${{ steps.is-prerelease.outputs.is-prerelease }} == true ]] then - version=$(pnpm version ${{ github.event.inputs.type }} --no-git-tag-version) + version=$(pnpm version ${{ github.event.inputs.type }} --no-git-tag-version --preid next) else - version=$(pnpm version ${{ github.event.inputs.type }} --preid next --no-git-tag-version) + version=$(pnpm version ${{ github.event.inputs.type }} --no-git-tag-version) fi echo "version=$version" >> $GITHUB_OUTPUT - run: echo "::debug::version is ${{ steps.version.outputs.version }}" @@ -46,21 +60,51 @@ jobs: # cache: 'pnpm' - id: branch run: echo "name=release/${{ steps.version.outputs.version }}" >> $GITHUB_OUTPUT - - name: Create release branch + - name: create release branch run: git checkout -b ${{ steps.branch.outputs.name }} # this is not required when pnpm is creating the git tag - - name: add and commit changes + - name: add and commit changes to release branch run: | git add package.json git commit -m '[automated] release: ${{ steps.version.outputs.version }}' - - run: git push origin ${{ steps.branch.outputs.name }} - - id: pr + - name: push to release branch + run: git push origin ${{ steps.branch.outputs.name }} + - name: create draft release + id: draft-release + run: | + if [[ ${{ steps.is-prerelease.outputs.is-prerelease }} == true ]] + then + url=$(gh release create ${{ steps.version.outputs.version }} --generate-notes --draft --prerelease) + else + url=$(gh release create ${{ steps.version.outputs.version }} --generate-notes --draft) + fi + echo "url=$url" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # TODO: remove sleep https://github.com/cli/cli/issues/6599#issuecomment-1314562972 + - run: sleep 5 + - name: create pull request + id: pr run: | - url=$(gh pr create --title "release: ${{ steps.version.outputs.version }}" --body "Automated PR created to release a new version of the project") + body_file=body.md + # get URL to this workflow run + run="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + # output intro message to an ephemeral markdown file + echo "_This pull request was automatically created by [GitHub Actions]($run)_" > $body_file + # output the generated release notes to an ephemeral markdown file + gh release view ${{ steps.version.outputs.version }} --json body --jq .body >> $body_file + # get the pull request URL + url=$(gh pr create --title "release: ${{ steps.version.outputs.version }}" --body-file $body_file) echo "link=$url" >> $GITHUB_OUTPUT - env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - run: echo '${{ steps.pr.outputs.link }}' - run: echo ::notice title="created"::${{ steps.pr.outputs.link }} - run: echo ::notice title="type"::${{ github.event.inputs.type }} + - run: echo ::notice title="draft release"::${{ steps.draft-release.outputs.url }} + - name: cleanup + if: failure() + uses: ./.github/actions/cleanup-discarded-release + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ steps.branch.outputs.name }} + version: ${{ steps.version.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 81555b69..28de5c5f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,13 +20,10 @@ jobs: version: ${{ steps.version.outputs.result }} is-prerelease: ${{ contains(steps.version.outputs.result, 'next') }} steps: - - name: extract-version - id: version - uses: actions/github-script@0.2.0 + - id: version + uses: ./.github/actions/extract-version-from-branch with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - return context.payload.pull_request.title.replace(/release\: /, ''); + branch: ${{ github.head_ref }} prerelease: needs: verify-run uses: ./.github/workflows/release-env.yml From f5af6c08febdf48d130ea03e978947c6d40d8072 Mon Sep 17 00:00:00 2001 From: josefaidt Date: Mon, 14 Nov 2022 17:54:21 -0800 Subject: [PATCH 2/6] chore(actions): align usage of yaml file extension --- .github/workflows/{ci.yml => ci.yaml} | 0 .github/workflows/{codeql.yml => codeql.yaml} | 0 .github/workflows/{create-release.yml => create-release.yaml} | 0 .../{issues-pending-author.yml => issues-pending-author.yaml} | 0 .github/workflows/{release-env.yml => release-env.yaml} | 0 .github/workflows/{release.yml => release.yaml} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{ci.yml => ci.yaml} (100%) rename .github/workflows/{codeql.yml => codeql.yaml} (100%) rename .github/workflows/{create-release.yml => create-release.yaml} (100%) rename .github/workflows/{issues-pending-author.yml => issues-pending-author.yaml} (100%) rename .github/workflows/{release-env.yml => release-env.yaml} (100%) rename .github/workflows/{release.yml => release.yaml} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yaml similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/ci.yaml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yaml similarity index 100% rename from .github/workflows/codeql.yml rename to .github/workflows/codeql.yaml diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yaml similarity index 100% rename from .github/workflows/create-release.yml rename to .github/workflows/create-release.yaml diff --git a/.github/workflows/issues-pending-author.yml b/.github/workflows/issues-pending-author.yaml similarity index 100% rename from .github/workflows/issues-pending-author.yml rename to .github/workflows/issues-pending-author.yaml diff --git a/.github/workflows/release-env.yml b/.github/workflows/release-env.yaml similarity index 100% rename from .github/workflows/release-env.yml rename to .github/workflows/release-env.yaml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yaml similarity index 100% rename from .github/workflows/release.yml rename to .github/workflows/release.yaml From f747b862d97d8148e946d66dbfa4350d4ad91091 Mon Sep 17 00:00:00 2001 From: josefaidt Date: Thu, 17 Nov 2022 16:23:03 -0800 Subject: [PATCH 3/6] chore(actions): correct output variable --- .github/actions/extract-version-from-branch/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/extract-version-from-branch/action.yaml b/.github/actions/extract-version-from-branch/action.yaml index d82bc310..1c2d4aff 100644 --- a/.github/actions/extract-version-from-branch/action.yaml +++ b/.github/actions/extract-version-from-branch/action.yaml @@ -9,12 +9,12 @@ inputs: outputs: version: description: extracted version - value: ${{ steps.version.outputs.result }} + value: ${{ steps.extract-version.outputs.version }} runs: using: 'composite' steps: - name: extract-version - id: version + id: extract-version shell: bash run: | branch=${{ inputs.branch }} From 2abae81889640b52f5ccf2efc7981ddec06435e9 Mon Sep 17 00:00:00 2001 From: josefaidt Date: Thu, 17 Nov 2022 16:24:24 -0800 Subject: [PATCH 4/6] chore(actions): improve version extraction job props --- .github/workflows/release.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 28de5c5f..66c286a4 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,10 +17,10 @@ jobs: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/') outputs: - version: ${{ steps.version.outputs.result }} - is-prerelease: ${{ contains(steps.version.outputs.result, 'next') }} + version: ${{ steps.extract-version.outputs.version }} + is-prerelease: ${{ contains(steps.extract-version.outputs.version, 'next') }} steps: - - id: version + - id: extract-version uses: ./.github/actions/extract-version-from-branch with: branch: ${{ github.head_ref }} From e6a8e00d881257de182cfe1e0d4013692022c48a Mon Sep 17 00:00:00 2001 From: josefaidt Date: Thu, 17 Nov 2022 16:30:49 -0800 Subject: [PATCH 5/6] chore: yml -> yaml --- .github/workflows/release.yaml | 4 ++-- CONTRIBUTING.md | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 66c286a4..f659b9fd 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -26,7 +26,7 @@ jobs: branch: ${{ github.head_ref }} prerelease: needs: verify-run - uses: ./.github/workflows/release-env.yml + uses: ./.github/workflows/release-env.yaml secrets: inherit with: env: next @@ -35,7 +35,7 @@ jobs: release: needs: [verify-run, prerelease] if: ${{ fromJSON(needs.verify-run.outputs.is-prerelease) == false }} - uses: ./.github/workflows/release-env.yml + uses: ./.github/workflows/release-env.yaml secrets: inherit with: env: main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8815ea0b..46089e99 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -132,7 +132,7 @@ Go to either the GitHub organization or repository that you wish to recieve rele 3. Under **Payload URL** , paste in the Discord Webhook URL from before with `/github` appended to the end 4. Under **Content type**, select `application/json` 5. Create a **Secret** and store it in `.env` as `GITHUB_RELEASES_WEBHOOK_SECRET` -6. Select **Let me select individual events** then choose `releases` +6. Select **Let me select individual events** then choose `releases` 7. Click **Add Webhook** @@ -146,10 +146,10 @@ Configuring this webhook will remove the Discord `staff` role when members leave You must be the owner of the GitHub organization to perform the following steps. 1. Go to your GitHub organization, and click **Settings** -> **Webhooks** -> **Add Webhook** -2. Under **Payload URL** choose `http:///api/webhooks/github-org-membership` +2. Under **Payload URL** choose `http:///api/webhooks/github-org-membership` 3. Under **Content type**, select `application/json` 4. Create a **Secret** and store in in `.env` as `GITHUB_ORG_WEBHOOK_SECRET` -5. Select **Let me select individual events** then choose `Organizations` +5. Select **Let me select individual events** then choose `Organizations` 6. **Add Webhook** ### Configuring a GitHub App @@ -162,7 +162,7 @@ A GitHub App is required to obtain the permissions necessary for many API calls. 2. Select **New GitHub App** 3. For the homepage URL, put in the homepage of your website 4. Under **Callback URL** put `http:///api/auth/callback/github` -5. Select **Expire user authorization tokens** AND **Request user authorization (OAuth) during installation** +5. Select **Expire user authorization tokens** AND **Request user authorization (OAuth) during installation** 6. Under **Webhook** deselect **Active** 7. Scroll down to **Organization Permissions** and under **Members** select `Read-only` 8. **Create GitHub App** @@ -218,8 +218,8 @@ Now you should be looking at the settings page for your app. ``` 4. Copy this ID and store in `.env` as `GITHUB_INSTALLATION_ID` - - + + ## Deployment For the deployment we will work primarily in the [`cdk`](./cdk) directory, where the [AWS CDK CLI](https://www.npmjs.com/package/aws-cdk) is installed locally to the package. @@ -267,11 +267,11 @@ When `pnpm test` is run from the project root, the newly added test is executed ## Releasing 1. developer creates a PR from their fork -2. maintainers review and add the `run-ci` label to [run the CI pipeline](./.github/workflows/ci.yml) and get the apporpriate status check +2. maintainers review and add the `run-ci` label to [run the CI pipeline](./.github/workflows/ci.yaml) and get the apporpriate status check 3. after PR requirements are met, maintainers merge to `main` -4. maintainers manually run the [`create-release`](./.github/workflows/create-release.yml) action with the desired version release (major, minor, patch, prerelease) +4. maintainers manually run the [`create-release`](./.github/workflows/create-release.yaml) action with the desired version release (major, minor, patch, prerelease) 5. maintainers review and merge the automatically-created PR -6. GitHub Actions run [`release`](./.github/workflows/release.yml) action using the version specified in the PR title +6. GitHub Actions run [`release`](./.github/workflows/release.yaml) action using the version specified in the PR title This process uses one branch, `main`, and relies on the created releases and git tags to showcase the latest source code available in each environment (release -> `main` vs prerelease -> `next`). From 45052019b32ab081ea384725106753a5c0afab27 Mon Sep 17 00:00:00 2001 From: josefaidt Date: Thu, 17 Nov 2022 16:41:07 -0800 Subject: [PATCH 6/6] chore(actions): comments and checkout --- .github/workflows/cleanup-discarded-release.yaml | 5 +++++ .github/workflows/release.yaml | 3 +++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/cleanup-discarded-release.yaml b/.github/workflows/cleanup-discarded-release.yaml index a0b06682..2f97e848 100644 --- a/.github/workflows/cleanup-discarded-release.yaml +++ b/.github/workflows/cleanup-discarded-release.yaml @@ -8,8 +8,13 @@ on: jobs: cleanup: runs-on: ubuntu-latest + # We run cleanup action only if: + # 1. PR comes from internal branch (i.e. not a fork) + # 2. PR is NOT merged + # 3. PR branch name begins with "release/" if: | github.event.pull_request.head.repo.full_name == github.repository && + github.event.pull_request.merged == false && startsWith(github.event.pull_request.head.ref, 'release/') steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f659b9fd..183f09ad 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,6 +20,9 @@ jobs: version: ${{ steps.extract-version.outputs.version }} is-prerelease: ${{ contains(steps.extract-version.outputs.version, 'next') }} steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false - id: extract-version uses: ./.github/actions/extract-version-from-branch with: