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

Protected branch with PR requirement prevents release #175

Closed
Ninerian opened this issue Apr 18, 2019 · 52 comments
Closed

Protected branch with PR requirement prevents release #175

Ninerian opened this issue Apr 18, 2019 · 52 comments

Comments

@Ninerian
Copy link

Ninerian commented Apr 18, 2019

Hello we integrated semantic release in our tool chain, but as we tried to release to master the first time, the branch protection of master prevented the release.

The error message from travis:

[9:32:50 AM] [semantic-release] › ✖  An error occurred while running semantic-release: { Error: Command failed: git push --tags https://[secure]@github.com/**/service.git HEAD:master
remote: error: GH006: Protected branch update failed for refs/heads/master.        
remote: error: At least 1 approving review is required by reviewers with write access.        
To https://github.com/**/service.git
 ! [remote rejected] HEAD -> master (protected branch hook declined)
error: failed to push some refs to 'https://[secure]@github.com/**/service.git'

How could I keep the PR rule and enable semantic release?

@gr2m
Copy link
Member

gr2m commented Apr 18, 2019

Hmm that’s odd, I did not run into it myself. Does the configured GITHUB_TOKEN have write access to the repository? Do you have any custom configuration for semantic-release in your setup?

@diegopamio
Copy link

We are facing exactly the same issue.

@cgadam
Copy link

cgadam commented Apr 18, 2019

@gr2m even though you might have write access for protected branches you need to pass all the required checks (like having a PR and having, 2 approvers, etc) in order to be able to merge to master unless you are admin. We don't want our bot to have such privilege so if instead of committing directly to the repo it would be nice if we could create a PR. That should fix this situation.

@gr2m
Copy link
Member

gr2m commented Apr 19, 2019

semantic-release is not merging or pushing anything by default, it just creates a git tag. I don’t think that is prohibited by the branch protection.

I think what might be possible is that you have configured something which requires the creation of additional commits, hence my question about custom configuration

@cgadam
Copy link

cgadam commented Apr 19, 2019

@gr2m you are right. The one trying to commit is actually the npm plugin that changes the context the package.json with the new version. There is also another plugin that changes the context of the CHANGELOG.md file. It then needs to push that to the release branch (master in this case)

@gr2m
Copy link
Member

gr2m commented Apr 19, 2019

I’m not sure if these features are implemented in this plugin or somewhere else? I’m not sure how where the feature would need to be implemented, but if you want to give it a go I can help review it

@cgadam
Copy link

cgadam commented Apr 19, 2019

@Ninerian, the situation we have which I think it's similar to yours is this one:

  • We have protected branch rules enabled (like having 2 reviewers per each commit and do not commit directly to master if it's not via a PR). The protected branch is, at the same time, the release branch for semantic-release. (i.e: master)

  • We want semantic-release to update files when the new version is calculated. (In our case we do update package.json and CHANGELOG.md file). In order to do this you need to provide a GITHUB_TOKEN with write permissions.

You will still get the issue you described before.

[9:32:50 AM] [semantic-release] › ✖  An error occurred while running semantic-release: { Error: Command failed: git push --tags https://[secure]@github.com/**/service.git HEAD:master
remote: error: GH006: Protected branch update failed for refs/heads/master.        
remote: error: At least 1 approving review is required by reviewers with write access.        
To https://github.com/**/service.git
 ! [remote rejected] HEAD -> master (protected branch hook declined)
error: failed to push some refs to 'https://[secure]@github.com/**/service.git'

In the perfect world, we would be able to tell Github, please bypass this type of checking for specific non-admin users (like a bot) but that's something Github doesn't support so far. I have confirmed it with support:

image

The way we workaround this was by assigning the bot as Owner. By doing this it do has the power to bypass the protected branch rules (because it's considered an admin).

The good thing is that the GITHUB_TOKEN we generated for doing this kind of commit doesn't have any crazy permission like deleting repo or such so we should be OK.

image

Hope this is useful to you too and helps u with semantic-release integration on your protected branch.

@Ninerian
Copy link
Author

Ninerian commented May 8, 2019

After some research I have to admit that I had the wrong package installed. I used semantic-release/git. after changing to this plugin, the release works flawless.

@Ninerian Ninerian closed this as completed May 8, 2019
@good-idea
Copy link

In case others come here with the same issue - I was having this problem, but fixed it by un-checking "Include administrators" in the branch protection rule.

@hashim-sohail
Copy link

After some research I have to admit that I had the wrong package installed. I used semantic-release/git. after changing to this plugin, the release works flawless.

How were you able to fix this issue?

@goloroden
Copy link

@Ninerian Great that you figured out how to solve this 🎉

Can you maybe shed some light on how to combine the @semantic-release/git plugin with branch protection, and on how you solved it?

@hashim-sohail
Copy link

@Ninerian Great that you figured out how to solve this 🎉

Can you maybe shed some light on how to combine the @semantic-release/git plugin with branch protection, and on how you solved it?

I was also able to resolve the protection issue using GIT_CREDENTIALS as my environment variable.

Environment Variables

But instead of using my password i used a Personal Access Token of an admin account with push access to the repos

@goloroden
Copy link

goloroden commented Nov 27, 2019

Hey @hashim-sohail 👋

Thanks for the quick reply!

How do you protect these credentials against malicious PRs who read your environment variables and send them somewhere?

Oh, and have you enabled branch protection? If so, did you setup the token with administrative privileges?

@goloroden
Copy link

PS: I'm asking since https://github.com/semantic-release/semantic-release/blob/f645547f2f30eb59179f1d22da13612ba5090f38/docs/recipes/github-actions.md#pushing-packagejson-changes-to-a-master-branch warns not to use personal access tokens. I'm a little bit puzzled here.

On the one hand, the docs advise you to use a personal access token, on the other hand they tell you not to do as it imposes a security risk...

@hashim-sohail
Copy link

Hey @hashim-sohail 👋

Thanks for the quick reply!
How do you protect these credentials against malicious PRs who read your environment variables and send them somewhere?

We have a different workflow for protected branches, which run only after the PR is merged after review into these branches. The secret is only exposed in these workflows.

Oh, and have you enabled branch protection? If so, did you setup the token with administrative privileges?

Yes, branch protection is active. The token is generated from an admin account. The admin accounts are privileged to push directly to our protected branches.

@hashim-sohail
Copy link

PS: I'm asking since https://github.com/semantic-release/semantic-release/blob/f645547f2f30eb59179f1d22da13612ba5090f38/docs/recipes/github-actions.md#pushing-packagejson-changes-to-a-master-branch warns not to use personal access tokens. I'm a little bit puzzled here.

On the one hand, the docs advise you to use a personal access token, on the other hand they tell you not to do as it imposes a security risk...

I went through that link too. But there is no proper workaround right now to implement this. So had to do with a custom workaround, playing with the secrets

@goloroden
Copy link

Yes, branch protection is active. The token is generated from an admin account. The admin accounts are privileged to push directly to our protected branches.

Great, thanks 👍

I went through that link too. But there is no proper workaround right now to implement this. So had to do with a custom workaround, playing with the secrets

I did some additional research, too, and GitHub Actions mention that secrets are never given to actions that run as result of a PR of a fork. So, everything should be safe 😊

Thanks for your help 👍

@imduchy
Copy link

imduchy commented Feb 21, 2020

@cgadam Could you please clarify for me; by adding a bot as an Owner you mean adding him into a Project Team? And are you talking about the @semantic-release-bot ?

@cgadam
Copy link

cgadam commented Mar 5, 2020

@Duchynko the bot is just an internal github user that authors the commit for semantic-release related modifications.

@0xc0d3r
Copy link

0xc0d3r commented Mar 23, 2020

I'm still getting this error. This is my release config in package.json.

{

"release": {
    "branches": [
      "staging"
    ],
    "plugins": [
      "@semantic-release/commit-analyzer",
      "@semantic-release/release-notes-generator",
      [
        "@semantic-release/changelog",
        {
          "changelogFile": "docs/CHANGELOG.md"
        }
      ],
      "@semantic-release/github",
      "@semantic-release/npm",
      [
        "@semantic-release/git",
        {
          "assets": [
            "dist/**/*.{js,css}",
            "package.json"
          ],
          "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
        }
      ]
    ]
  }

}

We have a bot user and it is responsible to build and publish. I've assigned the owner role to our bot user. Still getting the below error.

[6:33:47 AM] [semantic-release] › ℹ  Running semantic-release version 17.0.4
2020-03-23T06:33:47.262Z semantic-release:config load config from: /home/runner/work/logger/logger/package.json
2020-03-23T06:33:47.266Z semantic-release:config options values: {
  branches: [ 'staging' ],
  repositoryUrl: 'https://github.com/wingspanHQ/logger',
  tagFormat: 'v${version}',
  plugins: [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
    [ '@semantic-release/changelog', [Object] ],
    '@semantic-release/github',
    '@semantic-release/npm',
    [ '@semantic-release/git', [Object] ]
  ],
  _: [],
  debug: true,
  '$0': 'node_modules/.bin/semantic-release'
}
2020-03-23T06:33:47.472Z semantic-release:plugins options for @semantic-release/changelog/verifyConditions: { changelogFile: 'docs/CHANGELOG.md' }
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "@semantic-release/changelog"
2020-03-23T06:33:47.473Z semantic-release:plugins options for @semantic-release/github/verifyConditions: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "@semantic-release/github"
2020-03-23T06:33:47.473Z semantic-release:plugins options for @semantic-release/npm/verifyConditions: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "@semantic-release/npm"
2020-03-23T06:33:47.474Z semantic-release:plugins options for @semantic-release/git/verifyConditions: {
     assets: [ 'dist/**/*.{js,css}', 'package.json' ],
  message: 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}'
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "verifyConditions" from "@semantic-release/git"
}
2020-03-23T06:33:47.474Z semantic-release:plugins options for @semantic-release/commit-analyzer/analyzeCommits: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "analyzeCommits" from "@semantic-release/commit-analyzer"
2020-03-23T06:33:47.475Z semantic-release:plugins options for @semantic-release/release-notes-generator/generateNotes: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "generateNotes" from "@semantic-release/release-notes-generator"
2020-03-23T06:33:47.475Z semantic-release:plugins options for @semantic-release/changelog/prepare: { changelogFile: 'docs/CHANGELOG.md' }
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "prepare" from "@semantic-release/changelog"
2020-03-23T06:33:47.475Z semantic-release:plugins options for @semantic-release/npm/prepare: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "prepare" from "@semantic-release/npm"
2020-03-23T06:33:47.476Z semantic-release:plugins options for @semantic-release/git/prepare: {
  assets: [ 'dist/**/*.{js,css}', 'package.json' ],
  message: 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}'
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "prepare" from "@semantic-release/git"
}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "publish" from "@semantic-release/github"
2020-03-23T06:33:47.476Z semantic-release:plugins options for @semantic-release/github/publish: {}
2020-03-23T06:33:47.476Z semantic-release:plugins options for @semantic-release/npm/publish: {}
2020-03-23T06:33:47.476Z semantic-release:plugins options for @semantic-release/github/addChannel: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "publish" from "@semantic-release/npm"
2020-03-23T06:33:47.477Z semantic-release:plugins options for @semantic-release/npm/addChannel: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "addChannel" from "@semantic-release/github"
2020-03-23T06:33:47.477Z semantic-release:plugins options for @semantic-release/github/success: {}
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "addChannel" from "@semantic-release/npm"
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "success" from "@semantic-release/github"
[6:33:47 AM] [semantic-release] › ✔  Loaded plugin "fail" from "@semantic-release/github"
2020-03-23T06:33:49.020Z semantic-release:get-tags found tags for branch staging: [ { gitTag: 'v1.0.0', version: '1.0.0', channels: [ null ] }, { gitTag: 'v1.1.0', version: '1.1.0', channels: [ null ] }, { gitTag: 'v1.1.1', version: '1.1.1', channels: [ null ] }, { gitTag: 'v1.1.2', version: '1.1.2', channels: [ null ] }, { gitTag: 'v1.1.3', version: '1.1.3', channels: [ null ] }, { gitTag: 'v1.1.4', version: '1.1.4', channels: [ null ] }, { gitTag: 'v1.1.5', version: '1.1.5', channels: [ null ] }, { gitTag: 'v1.2.0', version: '1.2.0', channels: [ null ] }, { gitTag: 'v1.3.0', version: '1.3.0', channels: [ null ] }, { gitTag: 'v1.4.0', version: '1.4.0', channels: [ null ] } ]
[6:33:49 AM] [semantic-release] › ✔  Run automated release from branch staging on repository https://github.com/wingspanHQ/logger
[6:33:49 AM] [semantic-release] › ✔  Allowed to push to the Git repository
[6:33:49 AM] [semantic-release] › ℹ  Start step "verifyConditions" of plugin "@semantic-release/changelog"
[6:33:49 AM] [semantic-release] › ✔  Completed step "verifyConditions" of plugin "@semantic-release/changelog"
[6:33:49 AM] [semantic-release] › ℹ  Start step "verifyConditions" of plugin "@semantic-release/github"
[6:33:49 AM] [semantic-release] [@semantic-release/github] › ℹ  Verify GitHub authentication
[6:33:49 AM] [semantic-release] › ✔  Completed step "verifyConditions" of plugin "@semantic-release/github"
[6:33:49 AM] [semantic-release] › ℹ  Start step "verifyConditions" of plugin "@semantic-release/npm"
[6:33:49 AM] [semantic-release] [@semantic-release/npm] › ℹ  Verify authentication for registry https://npm.pkg.github.com/
[6:33:49 AM] [semantic-release] [@semantic-release/npm] › ℹ  Reading npm config from /home/runner/work/logger/logger/.npmrc
[6:33:49 AM] [semantic-release] › ✔  Completed step "verifyConditions" of plugin "@semantic-release/npm"
[6:33:49 AM] [semantic-release] › ℹ  Start step "verifyConditions" of plugin "@semantic-release/git"
[6:33:49 AM] [semantic-release] › ✔  Completed step "verifyConditions" of plugin "@semantic-release/git"
[6:33:49 AM] [semantic-release] › ℹ  Found git tag v1.4.0 associated with version 1.4.0 on branch staging
2020-03-23T06:33:49.498Z semantic-release:get-commits Use from: ddbf4ec9f13a13950fbf62b5651933df626c3aba

[6:33:49 AM] [semantic-release] › ℹ  Found 6 commits since last release
2020-03-23T06:33:49.511Z semantic-release:get-commits Parsed commits: [ { commit: { long: '8e7f8d8e7ec4260eeee43a6ec059d53bd59e5167', short: '8e7f8d8' }, tree: { long: 'dea2d26366d4b4740c3426d1fa596d79540d6d19', short: 'dea2d26' }, author: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T06:32:41.000Z }, committer: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T06:32:41.000Z }, subject: 'chore: add github_token', body: '', hash: '8e7f8d8e7ec4260eeee43a6ec059d53bd59e5167', committerDate: 2020-03-23T06:32:41.000Z, message: 'chore: add github_token', gitTags: '(HEAD -> staging, origin/staging)' }, { commit: { long: 'b30fa59d4aa3b4eba422eacf482571a5aef7fde7', short: 'b30fa59' }, tree: { long: '77cca5a8a2ed033f5bf717606185961a4a4e9929', short: '77cca5a' }, author: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T06:01:53.000Z }, committer: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T06:01:53.000Z }, subject: 'chore: remove git setup in workflow', body: '', hash: 'b30fa59d4aa3b4eba422eacf482571a5aef7fde7', committerDate: 2020-03-23T06:01:53.000Z, message: 'chore: remove git setup in workflow', gitTags: '' }, { commit: { long: '8126ba1448d8f0301430c56d70a21312becb5c77', short: '8126ba1' }, tree: { long: 'b2ebb5d511ec4fba1dc22839614d1f2ee1a9aa99', short: 'b2ebb5d' }, author: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T05:51:21.000Z }, committer: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T05:51:21.000Z }, subject: 'chore: add git envs', body: '', hash: '8126ba1448d8f0301430c56d70a21312becb5c77', committerDate: 2020-03-23T05:51:21.000Z, message: 'chore: add git envs', gitTags: '' }, { commit: { long: 'faf6aca9da1ced7c59002d393a1b3efc76faf597', short: 'faf6aca' }, tree: { long: 'e49756af42cbc9c01bc4a18dfe1cdd87240620e4', short: 'e49756a' }, author: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T05:41:16.000Z }, committer: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T05:41:16.000Z }, subject: 'chore: remove git_creds env var', body: '', hash: 'faf6aca9da1ced7c59002d393a1b3efc76faf597', committerDate: 2020-03-23T05:41:16.000Z, message: 'chore: remove git_creds env var', gitTags: '' }, { commit: { long: '9dc93f7abd452839091af76daba0d8a89e213196', short: '9dc93f7' }, tree: { long: '13488402daa38d1bedc706be55e8646f8dbebc50', short: '1348840' }, author: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T05:35:37.000Z }, committer: { name: 'Anesh Parvatha', email: 'anesh.parvatha@gmail.com', date: 2020-03-23T05:35:37.000Z }, subject: 'chore(env): add git_creds env variable to secrets', body: '', hash: '9dc93f7abd452839091af76daba0d8a89e213196', committerDate: 2020-03-23T05:35:37.000Z, message: 'chore(env): add git_creds env variable to secrets', gitTags: '' }, { commit: { long: 'd1104e9a706de5c019cda3ffc48909f7e1406496', short: 'd1104e9' }, tree: { long: '746d43d413b67f0d8b80e724095d5168bc256454', short: '746d43d' }, author: { name: 'Gregory Maglio', email: 'gregm@wingspan.app', date: 2020-03-23T03:50:21.000Z }, committer: { name: 'Gregory Maglio', email: 'gregm@wingspan.app', date: 2020-03-23T03:50:21.000Z }, subject: 'fix: kick!', body: '', hash: 'd1104e9a706de5c019cda3ffc48909f7e1406496', committerDate: 2020-03-23T03:50:21.000Z, message: 'fix: kick!', gitTags: '' } ],message: 'chore(env): add git_creds env variable to secrets', gitTags: '' }, { commit: { long: 'd1104e9a706de5c019cda3ffc48909f7e1406496', short: 'd1104e9' }, tree: { long: '746d43d413b67f0d8b80e724095d5168bc256454', short: '746d43d' }, author: { name: 'Gregory Maglio', email: 'gregm@wingspan.app', date: 2020-03-23T03:50:21.000Z }, committer: { name: 'Gregory Maglio', email: 'gregm@wingspan.app', date: 2020-03-23T03:50:21.000Z }, subject: 'fix: kick!', body: '', hash: 'd1104e9a706de5c019cda3ffc48909f7e1406496', committerDate: 2020-03-23T03:50:21.000Z, message: 'fix: kick!', gitTags: '' } ]
[6:33:49 AM] [semantic-release] › ℹ  Start step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analyzing commit: chore: add github_token
2020-03-23T06:33:49.519Z semantic-release:commit-analyzer Analyzing with default rules
2020-03-23T06:33:49.520Z semantic-release:commit-analyzer Analyzing with default rules
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  The commit should not trigger a release
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analyzing commit: chore: remove git setup in workflow
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  The commit should not trigger a release
2020-03-23T06:33:49.521Z semantic-release:commit-analyzer Analyzing with default rules
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analyzing commit: chore: add git envs
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  The commit should not trigger a release
2020-03-23T06:33:49.521Z semantic-release:commit-analyzer Analyzing with default rules
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analyzing commit: chore: remove git_creds env var
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  The commit should not trigger a release
2020-03-23T06:33:49.522Z semantic-release:commit-analyzer Analyzing with default rules
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analyzing commit: chore(env): add git_creds env variable to secrets
2020-03-23T06:33:49.522Z semantic-release:commit-analyzer Analyzing with default rules
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  The commit should not trigger a release
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analyzing commit: fix: kick!
2020-03-23T06:33:49.522Z semantic-release:commit-analyzer The rule { type: 'fix', release: 'patch' } match commit with release type 'patch'
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  The release type for the commit is patch
[6:33:49 AM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ  Analysis of 6 commits complete: patch release
[6:33:49 AM] [semantic-release] › ✔  Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[6:33:49 AM] [semantic-release] › ℹ  The next release version is 1.4.1
[6:33:49 AM] [semantic-release] › ℹ  Start step "generateNotes" of plugin "@semantic-release/release-notes-generator"
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator version: '1.4.1'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator host: undefined
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator owner: 'wingspanHQ'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator repository: 'logger'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator previousTag: 'v1.4.0'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator currentTag: 'v1.4.1'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator host: 'https://github.com'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator linkReferences: undefined
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator issue: 'issues'
2020-03-23T06:33:49.535Z semantic-release:release-notes-generator commit: 'commit'
[6:33:49 AM] [semantic-release] › ✔  Completed step "generateNotes" of plugin "@semantic-release/release-notes-generator"
[6:33:49 AM] [semantic-release] › ℹ  Start step "prepare" of plugin "@semantic-release/changelog"
[6:33:49 AM] [semantic-release] [@semantic-release/changelog] › ℹ  Create /home/runner/work/logger/logger/docs/CHANGELOG.md
[6:33:49 AM] [semantic-release] › ✔  Completed step "prepare" of plugin "@semantic-release/changelog"
[6:33:49 AM] [semantic-release] › ℹ  Start step "prepare" of plugin "@semantic-release/npm"
[6:33:49 AM] [semantic-release] [@semantic-release/npm] › ℹ  Write version 1.4.1 to package.json in /home/runner/work/logger/logger
v1.4.1
[6:33:49 AM] [semantic-release] › ✔  Completed step "prepare" of plugin "@semantic-release/npm"
[6:33:49 AM] [semantic-release] › ℹ  Start step "prepare" of plugin "@semantic-release/git"
[6:33:50 AM] [semantic-release] [@semantic-release/git] › ℹ  Found 1 file(s) to commit
2020-03-23T06:33:50.029Z semantic-release:git add file to git index {
  command: 'git add --force --ignore-errors package.json',
  exitCode: 0,
  stdout: '',
  stderr: '',
  all: undefined,
  failed: [secure],
  timedOut: [secure],
  isCanceled: [secure],
  killed: [secure]
}
2020-03-23T06:33:50.029Z semantic-release:git commited files: [ 'package.json' ]
[6:33:56 AM] [semantic-release] › ✖  Failed step "prepare" of plugin "@semantic-release/git"
[6:33:56 AM] [semantic-release] › ✖  An error occurred while running semantic-release: Error: Command failed with exit code 1: git push --tags https://github.com/wingspanHQ/logger HEAD:staging
remote: error: GH006: Protected branch update failed for refs/heads/staging.        
remote: error: At least 1 approving review is required by reviewers with write access.        
To https://github.com/wingspanHQ/logger
 ! [remote rejected] HEAD -> staging (protected branch hook declined)
error: failed to push some refs to 'https://github.com/wingspanHQ/logger'
    at makeError (/home/runner/work/logger/logger/node_modules/execa/lib/error.js:58:11)
    at handlePromise (/home/runner/work/logger/logger/node_modules/execa/index.js:114:26)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async push (/home/runner/work/logger/logger/node_modules/@semantic-release/git/lib/git.js:51:3)
    at async module.exports (/home/runner/work/logger/logger/node_modules/@semantic-release/git/lib/prepare.js:69:5)
    at async prepare (/home/runner/work/logger/logger/node_modules/@semantic-release/git/index.js:28:3)
    at async validator (/home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/normalize.js:34:24)
   at async /home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/pipeline.js:37:34
    at async /home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/pipeline.js:31:3
    at async Object.pluginsConf.<computed> [as prepare] (/home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/index.js:80:11) {
  shortMessage: 'Command failed with exit code 1: git push --tags https://github.com/wingspanHQ/logger HEAD:staging',
  command: 'git push --tags https://github.com/wingspanHQ/logger HEAD:staging',
  exitCode: 1,
  signal: undefined,
  signalDescription: undefined,
  stdout: '',
  stderr: 'remote: error: GH006: Protected branch update failed for refs/heads/staging.        \n' +
    'remote: error: At least 1 approving review is required by reviewers with write access.        \n' +
    'To https://github.com/wingspanHQ/logger\n' +
    ' ! [remote rejected] HEAD -> staging (protected branch hook declined)\n' +
    "error: failed to push some refs to 'https://github.com/wingspanHQ/logger'",
  failed: true,
  timedOut: [secure],
  isCanceled: [secure],
  killed: [secure],
  pluginName: '@semantic-release/git'
}
Error: Command failed with exit code 1: git push --tags https://github.com/wingspanHQ/logger HEAD:staging
remote: error: GH006: Protected branch update failed for refs/heads/staging.        
remote: error: At least 1 approving review is required by reviewers with write access.        
To https://github.com/wingspanHQ/logger
 ! [remote rejected] HEAD -> staging (protected branch hook declined)
error: failed to push some refs to 'https://github.com/wingspanHQ/logger'
    at makeError (/home/runner/work/logger/logger/node_modules/execa/lib/error.js:58:11)
    at handlePromise (/home/runner/work/logger/logger/node_modules/execa/index.js:114:26)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async push (/home/runner/work/logger/logger/node_modules/@semantic-release/git/lib/git.js:51:3)
    at async module.exports (/home/runner/work/logger/logger/node_modules/@semantic-release/git/lib/prepare.js:69:5)
    at async prepare (/home/runner/work/logger/logger/node_modules/@semantic-release/git/index.js:28:3)
    at async validator (/home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/normalize.js:34:24)
    at async /home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/pipeline.js:37:34
    at async /home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/pipeline.js:31:3
    at async Object.pluginsConf.<computed> [as prepare] (/home/runner/work/logger/logger/node_modules/semantic-release/lib/plugins/index.js:80:11) {
  shortMessage: 'Command failed with exit code 1: git push --tags https://github.com/wingspanHQ/logger HEAD:staging',
  command: 'git push --tags https://github.com/wingspanHQ/logger HEAD:staging',
  exitCode: 1,
  signal: undefined,
  signalDescription: undefined,
  stdout: '',
  stderr: 'remote: error: GH006: Protected branch update failed for refs/heads/staging.        \n' +
    'remote: error: At least 1 approving review is required by reviewers with write access.        \n' +
    'To https://github.com/wingspanHQ/logger\n' +
    ' ! [remote rejected] HEAD -> staging (protected branch hook declined)\n' +
    "error: failed to push some refs to 'https://github.com/wingspanHQ/logger'",
  failed: true,
  timedOut: [secure],
  isCanceled: [secure],
    killed: [secure],
  pluginName: '@semantic-release/git'
}error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
##[error]Process completed with exit code 1.

@pvdlg @cgadam Am I missing something?

@0xc0d3r
Copy link

0xc0d3r commented Mar 24, 2020

export GH_TOKEN=<gh_token_generated_by_semantic-release-cli>
export NPM_TOKEN=<github_personal_access_token> // We are using GPR
export GIT_CREDENTIALS=<url_encoded_username>:<url_encoded_password>
export GIT_AUTHOR_NAME=<author_username>
export GIT_AUTHOR_EMAIL=<author_email>
export GIT_COMMITTER_NAME=<commiter_username>
export GIT_COMMITTER_EMAIL=<committer_email>

CI=true yarn semantic-release --debug

I ran this script locally on my machine and I am able to release the next version and bump the package version automatically using @semantic-release/git plugin.

Why the same configuration is not working on CI? Check my config release config and logs here

release.yml

name: Release
on:
  push:
    branches:
      - staging
      - next
      - beta
      - '*.x' # maintenance releases

jobs:
  release:
    name: release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Setup node
        uses: actions/setup-node@v1
        with:
          always-auth: true
          node-version: 12
      - name: Install npm packages
        run: yarn install
      - name: Build
        run: yarn build
      - name: Semantic Release
        run: yarn semantic-release --debug
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
          GITHUB_TOKEN: ${{ secrets.NPM_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }}
          GIT_AUTHOR_NAME: ${{ secrets. GIT_AUTHOR_NAME }}
          GIT_AUTHOR_EMAIL: ${{ secrets. GIT_AUTHOR_EMAIL }}
          GIT_COMMITTER_NAME: ${{ secrets. GIT_COMMITTER_NAME }}
          GIT_COMMITTER_EMAIL: ${{ secrets. GIT_COMMITTER_EMAIL }}

One more thing I observed is that in my tokens page, the generated token has never used and after I ran the above script locally, it has changed to Last used within last week.

@gr2m @pvdlg Can you support me with this?

@carrmelo
Copy link

carrmelo commented Mar 25, 2020

The way we workaround this was by assigning the bot as Owner. By doing this it do has the power to bypass the protected branch rules (because it's considered an admin).
The good thing is that the GITHUB_TOKEN we generated for doing this kind of commit doesn't have any crazy permission like deleting repo or such so we should be OK.

hey @cgadam, how did you assign the bot as an owner? I have created a token but then the release is done under my name, that is not ideal since our team would like to keep the action done in the github-action[bot] name.

I have tried the plugin and configuration as minimal as the example in the @semantic-release/git but keep on getting the error because of the 2 approval needed... (inlcude administrators options in unticked)

thanks in advance for any help!

@travi
Copy link
Member

travi commented Mar 25, 2020

a "bot" user in this case is simply another github user account that your team uses only for automated tasks like this one. you can then create a token for that account instead of your own. that user account then just needs to have a permission level that is allowed to push to the protected branch.

@0xc0d3r
Copy link

0xc0d3r commented Mar 25, 2020

@travi We did the same as you said but still we are getting the error.

@travi
Copy link
Member

travi commented Mar 25, 2020

that user account then just needs to have a permission level that is allowed to push

@0xc0d3r the above detail is key. do you allow admins to push, even though the branch is restricted. the "include administrators" option would need to be unchecked and the bot user would need to have admin or higher permissions.

@twang817
Copy link

I finally pieced this all together as well, and it was a chore. Let me save the next guy some time:

If you are absolutely allergic to using a PAT for this, we created an org-level Github App specifically for dealing with the limitations of GITHUB_TOKEN. Follow this documentation to create a Github App. Let's call our Github App MyBot

Once you have your GIthub App, configure its permissions. We gave ours a repository-level permissions -- for the purposes of this use-case, I believe Content is what you need.

Next create a Private Key. This will download a PEM file -- don't lose it. Also take note of your App's App ID.

Now install it to your organization. We chose to install it to just the repo that I'm working with, but I see no reason you couldn't install it org-wide if you're okay with the security implications.

Now that we have that set up, we can go to our repo and set up some secrets. I added a MYBOT_APP_ID and MYBOT_PRIVATE KEY. Dump the contents of your App ID and Private Key into those secrets.

Next, we go to branch protection rules. I'm assuming if you're reading this, you're going to have Require a pull request before merging ticked, as well as Require approvals. You may have others (I didn't). Under Allow specified actors to bypass required pull requests, you can now type MyBot and add him to the list of actors that can bypass the rules. Make sure Do not allow bypassing the above settings is not checked below.

We can finally write our workflow

name: Semantic Release

on:
  push:
    branches:
      - master

jobs:
  release:
    runs-on: ubuntu-latest
    concurrency: release

    steps:
      - name: Generate token
        id: generate_token
        uses: tibdex/github-app-token@v1
        with:
          app_id: ${{ secrets.MYBOT_APP_ID }}
          private_key: ${{ secrets.MYBOT_PRIVATE_KEY }}

      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
          token: ${{ steps.generate_token.outputs.token }}

      - name: Semantic Release
        uses: codfish/semantic-release-action@v2
        with:
          additional_packages: |
            [
              'conventional-changelog-conventionalcommits',
              '@semantic-release/changelog',
              '@google/semantic-release-replace-plugin',
              '@semantic-release/git',
              'semantic-release-slack-bot'
            ]
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
          SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}

And, for completeness, my .releaserc (I use the YAML format):

branches: master
plugins:
  - '@semantic-release/commit-analyzer'
  - '@semantic-release/release-notes-generator'
  - '@semantic-release/github'

  # generate changelog CHANGELOG.md
  - '@semantic-release/changelog'

  # update pyproject.toml with newest version
  - - '@google/semantic-release-replace-plugin'
    - replacements:
      - files: [pyproject.toml]
        from: "version = \".*\""
        to: "version = \"${nextRelease.version}\""
        results:
          - file: pyproject.toml
            hasChanged: true
            numMatches: 1
            numReplacements: 1
        countMatches: true

  # commit CHANGELOG.md and pyproject.toml
  - - '@semantic-release/git'
    - assets:
      - CHANGELOG.md
      - pyproject.toml

  # notify slack, using SLACK_TOKEN from environment
  - - 'semantic-release-slack-bot'
    - packageName: csm-terraform-modules
      notifyOnSuccess: true
      notifyOnFail: true
      slackChannel: "#my-slack-channel"
      markdownReleaseNotes: true

preset: conventionalcommits

Hope this saves the next guy about 8hrs of time. 🤦🏼

@lukeduda
Copy link

I finally pieced this all together as well, and it was a chore. Let me save the next guy some time:

If you are absolutely allergic to using a PAT for this, we created an org-level Github App specifically for dealing with the limitations of GITHUB_TOKEN. Follow this documentation to create a Github App. Let's call our Github App MyBot

Once you have your GIthub App, configure its permissions. We gave ours a repository-level permissions -- for the purposes of this use-case, I believe Content is what you need.

Next create a Private Key. This will download a PEM file -- don't lose it. Also take note of your App's App ID.

Now install it to your organization. We chose to install it to just the repo that I'm working with, but I see no reason you couldn't install it org-wide if you're okay with the security implications.

Now that we have that set up, we can go to our repo and set up some secrets. I added a MYBOT_APP_ID and MYBOT_PRIVATE KEY. Dump the contents of your App ID and Private Key into those secrets.

Next, we go to branch protection rules. I'm assuming if you're reading this, you're going to have Require a pull request before merging ticked, as well as Require approvals. You may have others (I didn't). Under Allow specified actors to bypass required pull requests, you can now type MyBot and add him to the list of actors that can bypass the rules. Make sure Do not allow bypassing the above settings is not checked below.

We can finally write our workflow

name: Semantic Release

on:
  push:
    branches:
      - master

jobs:
  release:
    runs-on: ubuntu-latest
    concurrency: release

    steps:
      - name: Generate token
        id: generate_token
        uses: tibdex/github-app-token@v1
        with:
          app_id: ${{ secrets.MYBOT_APP_ID }}
          private_key: ${{ secrets.MYBOT_PRIVATE_KEY }}

      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
          token: ${{ steps.generate_token.outputs.token }}

      - name: Semantic Release
        uses: codfish/semantic-release-action@v2
        with:
          additional_packages: |
            [
              'conventional-changelog-conventionalcommits',
              '@semantic-release/changelog',
              '@google/semantic-release-replace-plugin',
              '@semantic-release/git',
              'semantic-release-slack-bot'
            ]
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
          SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}

And, for completeness, my .releaserc (I use the YAML format):

branches: master
plugins:
  - '@semantic-release/commit-analyzer'
  - '@semantic-release/release-notes-generator'
  - '@semantic-release/github'

  # generate changelog CHANGELOG.md
  - '@semantic-release/changelog'

  # update pyproject.toml with newest version
  - - '@google/semantic-release-replace-plugin'
    - replacements:
      - files: [pyproject.toml]
        from: "version = \".*\""
        to: "version = \"${nextRelease.version}\""
        results:
          - file: pyproject.toml
            hasChanged: true
            numMatches: 1
            numReplacements: 1
        countMatches: true

  # commit CHANGELOG.md and pyproject.toml
  - - '@semantic-release/git'
    - assets:
      - CHANGELOG.md
      - pyproject.toml

  # notify slack, using SLACK_TOKEN from environment
  - - 'semantic-release-slack-bot'
    - packageName: csm-terraform-modules
      notifyOnSuccess: true
      notifyOnFail: true
      slackChannel: "#my-slack-channel"
      markdownReleaseNotes: true

preset: conventionalcommits

Hope this saves the next guy about 8hrs of time. 🤦🏼

That's the best answer in this thread! Works like a charm!!! 💪

intcreator pushed a commit to kelektiv/node-cron that referenced this issue Jul 20, 2023
## Purpose of the changes

In order to improve the maintainability and velocity of this project, I
suggested we implement an automatic release pipeline.

To support this automation feature, I've set up the repository to follow
the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) formatting
standard. This allows any commit to be parsed programmatically, and the
release type (major, minor, patch) associated with a group of new
commits to be determined automatically.

For more information on the different commit types and their associated
releases, please check [the table listing from the configuration
preset](https://github.com/insurgent-lab/conventional-changelog-preset#commit-types).

Once those changes are merged to `master`:
- new commits on `master` will automatically be linted (locally with a
pre-commit hook) to ensure they follow the formatting standard.
- commits on other branches won't be linted, instead, the PR title will
be linted (removing overhead for contributors). If the PR title isn't
compliant, an explanation message will automatically be posted on the
PR.
- any commit pushed to the `master` branch will trigger a Test & Release
workflow (unless `[skip ci]` is present in the commit title) that will
analyze the commits since the last version, automatically determine the
necessary version bump, and handle the whole release process (updating
`package.json` & `package-lock.json`, generating new `CHANGELOG.md`
entries, publishing Github tag & release, then publishing the new
version to npm).

## Todo before merging the PR:

- [x] create a git tag for v2.3.1 (pointing to
988f7f2)
- [x] only allow squash merging PRs (cf screenshot below)
- go to
https://github.com/kelektiv/node-cron/settings#merge-button-settings
- check "Allow squash merging" and set the below dropdown to "Default to
pull request title"
  - uncheck "Allow merge commits" & "Allow rebase merging"
- [x] setup branch protection for `master` (cf screenshot below)
- go to https://github.com/kelektiv/node-cron/settings/branches and
create/update branch protection for `master` with (at least) the
following options:
    - "Require a pull request before merging"
    - "Dismiss stale pull request approvals when new commits are pushed"
    - "Require status checks to pass before merging"
- "Require branches to be up to date before merging" > then find and
select all "lint-and-test" workflows (should be 9 of them + "Lint PR
title" + "security/snyk").
    - "Require conversation resolution before merging"
    - "Require linear history"
- make sure "Do not allow bypassing the above settings" is
**unchecked**, else the automatic release commits won't work
- [x] setup Github PAC for the repository (required because of
[limitations with the default access token when branch protection is
enabled](semantic-release/github#175))
  - go to https://github.com/settings/personal-access-tokens/new
  - set Expiration in one year (custom)
  - select the right resource owner (should be "kelektiv")
- under "Repository" access, select "Only select repositories" and
select only "node-cron"
- under "Permissions", set "Contents", "Issues" and "Pull requests" to
"Read and write"
  - the "Overview" section should look like this (cf screenshot below)
- copy the generated token to a new `CI_GITHUB_TOKEN` repository secret
on the Github repository
- [x] setup npm token for the package
  - go to https://www.npmjs.com/settings/{NPM_USERNAME}/tokens
  - "Generate New Token" > "Granular Access Token"
  - set Expiration to "365 days"
- set Permissions to "Read and write", then click on "Only select
packages and scopes" and select only "cron"
- copy the generated token to a new `NPM_TOKEN` repository secret on the
Github repository

## Screenshots
<details>
<summary>disable merge commits in PR, only allow squash
merging</summary>
  

![image](https://github.com/kelektiv/node-cron/assets/11234273/96e8eb3e-125a-4ce5-9a45-8289a0cdfc19)
</details>

<details>
<summary>setup branch protection for `master` *(required checks are not
exactly the same in the screenshot)*</summary>
  

![image](https://github.com/kelektiv/node-cron/assets/11234273/bdb712b0-9a62-4391-a85b-6ee762797232)
</details>

<details>
<summary>Github PAC > the "Overview" section should look like
this</summary>
  

![image](https://github.com/kelektiv/node-cron/assets/11234273/0fb4b9ef-8674-42c2-af4a-bf89776239a4)
</details>


## Notes
- The "Squash and Merge" button should be the only one available when
trying to merge this PR.
Slenderman00 pushed a commit to Slenderman00/revanced-patches-grindr that referenced this issue Sep 3, 2023
@berkon
Copy link

berkon commented Sep 11, 2023

For anybody using GitHub Actions, you need to set the token option of the actions/checkout action so that GitHub would authorize local Git with the necessary push permissions.

This is a very important and not really obvious information! Its a pity that this is not written down somewhere in the semantic-release docs. Apart from that I additionally had to add my admin account on GitHub to the list of the actors allowed to bypass the branch protection. I don't really understand why, because in that box there is a small hint, telling that admin accounts are always allowed to bypass the pull request requirement. Thus I think it should not be necessary to add the account to that list.

patrickm68 added a commit to patrickm68/node-cron-types that referenced this issue Sep 14, 2023
## Purpose of the changes

In order to improve the maintainability and velocity of this project, I
suggested we implement an automatic release pipeline.

To support this automation feature, I've set up the repository to follow
the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) formatting
standard. This allows any commit to be parsed programmatically, and the
release type (major, minor, patch) associated with a group of new
commits to be determined automatically.

For more information on the different commit types and their associated
releases, please check [the table listing from the configuration
preset](https://github.com/insurgent-lab/conventional-changelog-preset#commit-types).

Once those changes are merged to `master`:
- new commits on `master` will automatically be linted (locally with a
pre-commit hook) to ensure they follow the formatting standard.
- commits on other branches won't be linted, instead, the PR title will
be linted (removing overhead for contributors). If the PR title isn't
compliant, an explanation message will automatically be posted on the
PR.
- any commit pushed to the `master` branch will trigger a Test & Release
workflow (unless `[skip ci]` is present in the commit title) that will
analyze the commits since the last version, automatically determine the
necessary version bump, and handle the whole release process (updating
`package.json` & `package-lock.json`, generating new `CHANGELOG.md`
entries, publishing Github tag & release, then publishing the new
version to npm).

## Todo before merging the PR:

- [x] create a git tag for v2.3.1 (pointing to
988f7f24e3dde2e8bfe72890fdcc9a899b49f9b5)
- [x] only allow squash merging PRs (cf screenshot below)
- go to
https://github.com/kelektiv/node-cron/settings#merge-button-settings
- check "Allow squash merging" and set the below dropdown to "Default to
pull request title"
  - uncheck "Allow merge commits" & "Allow rebase merging"
- [x] setup branch protection for `master` (cf screenshot below)
- go to https://github.com/kelektiv/node-cron/settings/branches and
create/update branch protection for `master` with (at least) the
following options:
    - "Require a pull request before merging"
    - "Dismiss stale pull request approvals when new commits are pushed"
    - "Require status checks to pass before merging"
- "Require branches to be up to date before merging" > then find and
select all "lint-and-test" workflows (should be 9 of them + "Lint PR
title" + "security/snyk").
    - "Require conversation resolution before merging"
    - "Require linear history"
- make sure "Do not allow bypassing the above settings" is
**unchecked**, else the automatic release commits won't work
- [x] setup Github PAC for the repository (required because of
[limitations with the default access token when branch protection is
enabled](semantic-release/github#175))
  - go to https://github.com/settings/personal-access-tokens/new
  - set Expiration in one year (custom)
  - select the right resource owner (should be "kelektiv")
- under "Repository" access, select "Only select repositories" and
select only "node-cron"
- under "Permissions", set "Contents", "Issues" and "Pull requests" to
"Read and write"
  - the "Overview" section should look like this (cf screenshot below)
- copy the generated token to a new `CI_GITHUB_TOKEN` repository secret
on the Github repository
- [x] setup npm token for the package
  - go to https://www.npmjs.com/settings/{NPM_USERNAME}/tokens
  - "Generate New Token" > "Granular Access Token"
  - set Expiration to "365 days"
- set Permissions to "Read and write", then click on "Only select
packages and scopes" and select only "cron"
- copy the generated token to a new `NPM_TOKEN` repository secret on the
Github repository

## Screenshots
<details>
<summary>disable merge commits in PR, only allow squash
merging</summary>
  

![image](https://github.com/kelektiv/node-cron/assets/11234273/96e8eb3e-125a-4ce5-9a45-8289a0cdfc19)
</details>

<details>
<summary>setup branch protection for `master` *(required checks are not
exactly the same in the screenshot)*</summary>
  

![image](https://github.com/kelektiv/node-cron/assets/11234273/bdb712b0-9a62-4391-a85b-6ee762797232)
</details>

<details>
<summary>Github PAC > the "Overview" section should look like
this</summary>
  

![image](https://github.com/kelektiv/node-cron/assets/11234273/0fb4b9ef-8674-42c2-af4a-bf89776239a4)
</details>


## Notes
- The "Squash and Merge" button should be the only one available when
trying to merge this PR.
@dvictory
Copy link

I finally pieced this all together as well, and it was a chore. Let me save the next guy some time:

If you are absolutely allergic to using a PAT for this, we created an org-level Github App specifically for dealing with the limitations of GITHUB_TOKEN. Follow this documentation to create a Github App. Let's call our Github App MyBot

Once you have your GIthub App, configure its permissions. We gave ours a repository-level permissions -- for the purposes of this use-case, I believe Content is what you need.

Next create a Private Key. This will download a PEM file -- don't lose it. Also take note of your App's App ID.

Now install it to your organization. We chose to install it to just the repo that I'm working with, but I see no reason you couldn't install it org-wide if you're okay with the security implications.

Now that we have that set up, we can go to our repo and set up some secrets. I added a MYBOT_APP_ID and MYBOT_PRIVATE KEY. Dump the contents of your App ID and Private Key into those secrets.

Next, we go to branch protection rules. I'm assuming if you're reading this, you're going to have Require a pull request before merging ticked, as well as Require approvals. You may have others (I didn't). Under Allow specified actors to bypass required pull requests, you can now type MyBot and add him to the list of actors that can bypass the rules. Make sure Do not allow bypassing the above settings is not checked below.

We can finally write our workflow

name: Semantic Release

on:
  push:
    branches:
      - master

jobs:
  release:
    runs-on: ubuntu-latest
    concurrency: release

    steps:
      - name: Generate token
        id: generate_token
        uses: tibdex/github-app-token@v1
        with:
          app_id: ${{ secrets.MYBOT_APP_ID }}
          private_key: ${{ secrets.MYBOT_PRIVATE_KEY }}

      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
          token: ${{ steps.generate_token.outputs.token }}

      - name: Semantic Release
        uses: codfish/semantic-release-action@v2
        with:
          additional_packages: |
            [
              'conventional-changelog-conventionalcommits',
              '@semantic-release/changelog',
              '@google/semantic-release-replace-plugin',
              '@semantic-release/git',
              'semantic-release-slack-bot'
            ]
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
          SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}

And, for completeness, my .releaserc (I use the YAML format):

branches: master
plugins:
  - '@semantic-release/commit-analyzer'
  - '@semantic-release/release-notes-generator'
  - '@semantic-release/github'

  # generate changelog CHANGELOG.md
  - '@semantic-release/changelog'

  # update pyproject.toml with newest version
  - - '@google/semantic-release-replace-plugin'
    - replacements:
      - files: [pyproject.toml]
        from: "version = \".*\""
        to: "version = \"${nextRelease.version}\""
        results:
          - file: pyproject.toml
            hasChanged: true
            numMatches: 1
            numReplacements: 1
        countMatches: true

  # commit CHANGELOG.md and pyproject.toml
  - - '@semantic-release/git'
    - assets:
      - CHANGELOG.md
      - pyproject.toml

  # notify slack, using SLACK_TOKEN from environment
  - - 'semantic-release-slack-bot'
    - packageName: csm-terraform-modules
      notifyOnSuccess: true
      notifyOnFail: true
      slackChannel: "#my-slack-channel"
      markdownReleaseNotes: true

preset: conventionalcommits

Hope this saves the next guy about 8hrs of time. 🤦🏼

I had to add the Issues permission for my app, otherwise the @semantic-release/github plugin fails to search issues. Hope this helps others.

@amrsmind
Copy link

amrsmind commented Dec 7, 2023

You can use the @semantic-release/exec plugin in combination with GitHub CLI.

Note that my answer is missing the part about getting GitHub CLI to be installed and configured (with a GitHub token) in your CI environment.

  1. Install the exec plugin:

    npm install --save-dev @semantic-release/exec
  2. Update your semantic-release configuration:
    Add the exec plugin in your release.config.js to run a custom script that handles PR creation.

    module.exports = {
      // ... other config ...
      plugins: [
        // ... other plugins ...
        [
          '@semantic-release/exec',
          {
            prepareCmd: './create-release-pr.sh ${nextRelease.version} "${nextRelease.notes}"'
          }
        ]
      ],
    };
  3. Create a script for PR creation (create-release-pr.sh):
    Write a script that checks out a new branch, commits changes like package.json and CHANGELOG.md, and then uses gh to create a PR.

    #!/bin/bash
    VERSION=$1
    NOTES=$2
    
    git checkout -b release/$VERSION
    git add package.json CHANGELOG.md
    git commit -m "chore(release): $VERSION [skip ci]"
    git push origin release/$VERSION
    
    gh pr create --base main --head release/$VERSION --title "Release $VERSION" --body "$NOTES"

@boxrick
Copy link

boxrick commented Dec 19, 2023

So one issue I find is I want to do this more widely with basically all repos generated from templates in the 'init' stage. This obviously creates some issues since we have a CODEOWNERS which only allows a certain team to commit back to the repo.

So I thought why don't I just add it to the TEAM on repo creation but this isn't easy to due Github having a lack of fine grained permissions on a user on all repos and also

  • The gh action token user cannot add itself to a team
  • The team PAT token cannot add the repo to a team

So my solution / workaround for this is to use a PAT token, but this PAT token can be owned against an org rather than a user. Then give it the following set of permissions to enable it to both add it to the TEAM and modify the permissions on the repo:

Screenshot 2023-12-19 at 16 32 07

@travi
Copy link
Member

travi commented Dec 20, 2023

I would start by asking if you truly need to make a commit as part of your release process. If you choose not to make a commit, the need to push a commit no longer exists. There is a reason we do not include the git plugin in core.

@mrlubos
Copy link

mrlubos commented Dec 21, 2023

@travi Is the recommended approach to create a commit as a part of pull request before being merged?

@travi
Copy link
Member

travi commented Dec 21, 2023

To cover the most common reasons folks choose to make commits during a release, the recommended approach is to use GitHub releases (or similar) for release notes rather than updating a changelog file and rely on the registry when determining the latest version rather than updating the version in the package.json file. Avoid making a commit altogether for those sorts of details.

Not recommending making the updates manually. If you decide you still want those changes as part of a release, let semantic-release automate them for you, but know that having a commit adds significant complexity that you could avoid.

kennedykori added a commit to kennedykori/jutils that referenced this issue Jan 13, 2024
Update the token used by Semantic release to allow bypassing branch
protections rules.

See [this discussion](semantic-release/github#175 (comment))
for more details.
kennedykori added a commit to kennedykori/jutils that referenced this issue Jan 13, 2024
Change the token used by Semantic release to allow bypassing branch
protection rules.

See [this discussion](semantic-release/github#175 (comment))
for more details.
kennedykori added a commit to kennedykori/jutils that referenced this issue Jan 13, 2024
Change the token used by Semantic release to allow bypassing branch
protection rules.

See [this discussion](semantic-release/github#175 (comment))
for more details.
kennedykori added a commit to kennedykori/jutils that referenced this issue Jan 13, 2024
Change the token used by Semantic release to allow bypassing branch
protection rules.

See [this discussion](semantic-release/github#175 (comment))
for more details.
kennedykori added a commit to kennedykori/jutils that referenced this issue Jan 13, 2024
Change the token used by Semantic release to allow bypassing branch
protection rules.

See [this discussion](semantic-release/github#175 (comment))
for more details.
kennedykori added a commit to kennedykori/jutils that referenced this issue Jan 13, 2024
Change the token used by Semantic release to allow bypassing branch
protection rules.

See [this discussion](semantic-release/github#175 (comment))
for more details.
@cloverink
Copy link

      - name: 👾 Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests