From 407dc9ed549769bc35efb51d924a162239926438 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 31 Jan 2023 13:58:16 +0000 Subject: [PATCH] ci: Setup gitflow process --- .github/workflows/build.yml | 19 +++---- .github/workflows/codeql-analysis.yml | 4 +- .../workflows/enforce-license-compliance.yml | 4 +- .github/workflows/gitflow-sync-develop.yml | 50 +++++++++++++++++ .github/workflows/gitflow-sync-master.yml | 52 ++++++++++++++++++ .github/workflows/release.yml | 1 + CONTRIBUTING.md | 23 ++------ docs/assets/gitflow-chart.png | Bin 0 -> 37473 bytes docs/gitflow.md | 13 +++++ docs/publishing-a-release.md | 26 +++++++++ 10 files changed, 161 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/gitflow-sync-develop.yml create mode 100644 .github/workflows/gitflow-sync-master.yml create mode 100644 docs/assets/gitflow-chart.png create mode 100644 docs/gitflow.md create mode 100644 docs/publishing-a-release.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78b4172a9348..eee097753523 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: 'Build & Test' on: push: branches: - - master + - develop - release/** pull_request: workflow_dispatch: @@ -42,11 +42,11 @@ env: # GH will use the first restore-key it finds that matches # So it will start by looking for one from the same branch, else take the newest one it can find elsewhere - # We want to prefer the cache from the current master branch, if we don't find any on the current branch + # We want to prefer the cache from the current develop branch, if we don't find any on the current branch NX_CACHE_RESTORE_KEYS: | nx-Linux-${{ github.ref }}-${{ github.event.inputs.commit || github.sha }} nx-Linux-${{ github.ref }} - nx-Linux-refs/heads/master + nx-Linux-refs/heads/develop nx-Linux jobs: @@ -134,7 +134,7 @@ jobs: changed_browser_integration: ${{ steps.changed.outputs.browser_integration }} changed_any_code: ${{ steps.changed.outputs.any_code }} # Note: These next three have to be checked as strings ('true'/'false')! - is_master: ${{ github.ref == 'refs/heads/master' }} + is_develop: ${{ github.ref == 'refs/heads/develop' }} is_release: ${{ startsWith(github.ref, 'refs/heads/release/') }} force_skip_cache: ${{ github.event_name == 'pull_request' && contains(steps.pr-labels.outputs.labels, ' ci-skip-cache ') }} @@ -202,7 +202,7 @@ jobs: - name: NX cache uses: actions/cache@v3 # Disable cache when: - # - on master + # - on develop # - on release branches # - when PR has `ci-skip-cache` label if: | @@ -211,9 +211,9 @@ jobs: with: path: node_modules/.cache/nx key: nx-Linux-${{ github.ref }}-${{ env.HEAD_COMMIT }} - # On master branch, we want to _store_ the cache (so it can be used by other branches), but never _restore_ from it + # On develop branch, we want to _store_ the cache (so it can be used by other branches), but never _restore_ from it restore-keys: - ${{needs.job_get_metadata.outputs.is_master == 'false' && env.NX_CACHE_RESTORE_KEYS || 'nx-never-restore'}} + ${{needs.job_get_metadata.outputs.is_develop == 'false' && env.NX_CACHE_RESTORE_KEYS || 'nx-never-restore'}} - name: Build packages # Under normal circumstances, using the git SHA as a cache key, there shouldn't ever be a cache hit on the built @@ -272,8 +272,7 @@ jobs: needs: [job_get_metadata, job_build] timeout-minutes: 15 runs-on: ubuntu-20.04 - # Size Check will error out outside of the context of a PR or master branch - if: github.event_name == 'pull_request' || needs.job_get_metadata.outputs.is_master == 'true' + if: github.event_name == 'pull_request' || needs.job_get_metadata.outputs.is_develop == 'true' steps: - name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }}) uses: actions/checkout@v3 @@ -283,7 +282,6 @@ jobs: uses: actions/setup-node@v3 with: # The size limit action runs `yarn` and `yarn build` when this job is executed on - # `master`. We can't change this without making changes to the action, so we'll # use Node 14 for now. node-version: '14' - name: Check dependency cache @@ -301,6 +299,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} skip_step: build + main_branch: develop job_lint: name: Lint diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a092bf4b9e20..0f6954bc53eb 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,10 @@ name: 'CodeQL' on: push: - branches: [master] + branches: [develop] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [develop] paths-ignore: # When _only_ changing .md files, no need to run CodeQL analysis - '**/*.md' diff --git a/.github/workflows/enforce-license-compliance.yml b/.github/workflows/enforce-license-compliance.yml index 6fe5628f0d27..176758b840a3 100644 --- a/.github/workflows/enforce-license-compliance.yml +++ b/.github/workflows/enforce-license-compliance.yml @@ -2,9 +2,9 @@ name: Enforce License Compliance on: push: - branches: [master, main, release/*] + branches: [master, develop, release/*] pull_request: - branches: [master, main] + branches: [master, develop] jobs: enforce-license-compliance: diff --git a/.github/workflows/gitflow-sync-develop.yml b/.github/workflows/gitflow-sync-develop.yml new file mode 100644 index 000000000000..1931f3f13251 --- /dev/null +++ b/.github/workflows/gitflow-sync-develop.yml @@ -0,0 +1,50 @@ +name: Gitflow - Sync master into develop +on: + push: + branches: + - master + paths: + # When the version is updated on master (but nothing else) + - 'lerna.json' + - '!**/*.js' + - '!**/*.ts' + workflow_dispatch: + +env: + DEV_BRANCH: develop + +jobs: + main: + name: Create PR master->develop + runs-on: ubuntu-20.04 + permissions: + pull-requests: write + steps: + - name: git checkout + uses: actions/checkout@v3 + + # https://github.com/marketplace/actions/github-pull-request-action + - name: Create Pull Request + id: open-pr + uses: repo-sync/pull-request@v2 + with: + destination_branch: ${{ env.DEV_BRANCH }} + pr_title: '[Gitflow] Merge ${{ github.ref_name }} into ${{ env.DEV_BRANCH }}' + pr_body: 'Merge ${{ github.ref_name }} branch into ${{ env.DEV_BRANCH }}' + + # https://github.com/marketplace/actions/enable-pull-request-automerge + - name: Enable automerge for PR + if: steps.open-pr.outputs.pr_number != '' + uses: peter-evans/enable-pull-request-automerge@v2 + with: + pull-request-number: ${{ steps.open-pr.outputs.pr_number }} + merge-method: merge + + # https://github.com/marketplace/actions/auto-approve + - name: Auto approve PR + uses: hmarr/auto-approve-action@v3 + with: + pull-request-number: ${{ steps.open-pr.outputs.pr_number }} + review-message: 'Auto approved automated PR' + # TODO: Use the token of some user here?? + # github-token: ${{ secrets.SOME_USERS_PAT }} diff --git a/.github/workflows/gitflow-sync-master.yml b/.github/workflows/gitflow-sync-master.yml new file mode 100644 index 000000000000..a953e19b62a8 --- /dev/null +++ b/.github/workflows/gitflow-sync-master.yml @@ -0,0 +1,52 @@ +name: Gitflow - Sync develop into master +on: + push: + branches: + - develop + paths: + # We want to trigger this when ONLY the changlog is changed on develop, but nothing else + - 'CHANGELOG.md' + - '!packages' + - '!**/*.js' + - '!**/*.json' + - '!**/*.ts' + workflow_dispatch: + +env: + MAIN_BRANCH: master + +jobs: + main: + name: Create PR develop->master + runs-on: ubuntu-20.04 + permissions: + pull-requests: write + steps: + - name: git checkout + uses: actions/checkout@v3 + + # https://github.com/marketplace/actions/github-pull-request-action + - name: Create Pull Request + id: open-pr + uses: repo-sync/pull-request@v2 + with: + destination_branch: ${{ env.MAIN_BRANCH }} + pr_title: '[Gitflow] Merge ${{ github.ref_name }} into ${{ env.MAIN_BRANCH }}' + pr_body: 'Merge ${{ github.ref_name }} branch into ${{ env.MAIN_BRANCH }}' + + # https://github.com/marketplace/actions/enable-pull-request-automerge + - name: Enable automerge for PR + if: steps.open-pr.outputs.pr_number != '' + uses: peter-evans/enable-pull-request-automerge@v2 + with: + pull-request-number: ${{ steps.open-pr.outputs.pr_number }} + merge-method: merge + + # https://github.com/marketplace/actions/auto-approve + - name: Auto approve PR + uses: hmarr/auto-approve-action@v3 + with: + pull-request-number: ${{ steps.open-pr.outputs.pr_number }} + review-message: 'Auto approved automated PR' + # TODO: Use the token of some user here?? + # github-token: ${{ secrets.SOME_USERS_PAT }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c63255322933..38e875baf9fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,7 @@ on: merge_target: description: Target branch to merge into. Uses the default branch as a fallback (optional) required: false + default: master jobs: release: runs-on: ubuntu-20.04 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 059f2b33c752..a7cd962e3020 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -130,25 +130,14 @@ This means that all commits on the branch will be squashed into a single commit, * Make sure to rebase the branch on `master` before squashing it * Make sure to update the commit message of the squashed branch to follow the commit guidelines - including the PR number -## Publishing a Release +### Gitflow -_These steps are only relevant to Sentry employees when preparing and publishing a new SDK release._ +We use [Gitflow](https://docs.github.com/en/get-started/quickstart/github-flow) as a branching model. -**If you want to release a new SDK for the first time, be sure to follow the [New SDK Release Checklist](./docs/new-sdk-release-checklist.md)** +For more details, [see our Gitflow docs](./docs/gitflow.md). -1. Determine what version will be released (we use [semver](https://semver.org)). -2. Update [`CHANGELOG.md`](https://github.com/getsentry/sentry-javascript/edit/master/CHANGELOG.md) to add an entry for the next release number and a list of changes since the last release. (See details below.) -3. Run the [Prepare Release](https://github.com/getsentry/sentry-javascript/actions/workflows/release.yml) workflow. -4. A new issue should appear in https://github.com/getsentry/publish/issues. -5. Ask a member of the [@getsentry/releases team](https://github.com/orgs/getsentry/teams/releases/members) to approve the release. +## Publishing a Release -### Updating the Changelog +_These steps are only relevant to Sentry employees when preparing and publishing a new SDK release._ -1. Create a new branch. -2. Run `git log --format="- %s"` and copy everything since the last release. -3. Create a new section in the changelog, deciding based on the changes whether it should be a minor bump or a patch release. -4. Paste in the logs you copied earlier. -5. Delete any which aren't user-facing changes. -6. Alphabetize the rest. -7. If any of the PRs are from external contributors, include underneath the commits `Work in this release contributed by . Thank you for your contributions!`. If there's only one external PR, don't forget to remove the final `s`. If there are three or more, use an Oxford comma. (It's in the Sentry styleguide!) -8. Commit, push, and open a PR with the title `meta: Update changelog for `. +[See the docs for publishing a release](./docs/publishing-a-release.md) diff --git a/docs/assets/gitflow-chart.png b/docs/assets/gitflow-chart.png new file mode 100644 index 0000000000000000000000000000000000000000..b5050c1df66f921d940e1d223a276f7a5ac68e03 GIT binary patch literal 37473 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 `master` +3. Run the [Prepare Release](https://github.com/getsentry/sentry-javascript/actions/workflows/release.yml) workflow. + a. Wait for this until the sync to `master` is completed. +4. A new issue should appear in https://github.com/getsentry/publish/issues. +5. Ask a member of the [@getsentry/releases team](https://github.com/orgs/getsentry/teams/releases/members) to approve the release. + a. Once the release is completed, a sync from `master` ->` develop` will be automatically triggered + +## Updating the Changelog + +1. Create a new branch. +2. Run `git log --format="- %s"` and copy everything since the last release. +3. Create a new section in the changelog, deciding based on the changes whether it should be a minor bump or a patch release. +4. Paste in the logs you copied earlier. +5. Delete any which aren't user-facing changes. +6. Alphabetize the rest. +7. If any of the PRs are from external contributors, include underneath the commits `Work in this release contributed by . Thank you for your contributions!`. If there's only one external PR, don't forget to remove the final `s`. If there are three or more, use an Oxford comma. (It's in the Sentry styleguide!) +8. Commit, push, and open a PR with the title `meta: Update changelog for ` against `develop` branch.