Skip to content

Commit

Permalink
Remove the need for an ADMIN_GITHUB_TOKEN (#557)
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 authored Mar 4, 2024
1 parent 58a343c commit a349a20
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 50 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/prep-self-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ on:
jobs:
prep_release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
Expand All @@ -37,7 +39,7 @@ jobs:
id: prep-release
uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
version_spec: ${{ github.event.inputs.version_spec }}
post_version_spec: ${{ github.event.inputs.post_version_spec }}
target: jupyter-server/jupyter_releaser
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/publish-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,27 @@ on:
jobs:
publish_changelog:
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@v4
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Install Dependencies
shell: bash
run: |
pip install -e .
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Publish changelog
id: publish-changelog
uses: jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
target: ${{ github.event.inputs.target }}
branch: ${{ github.event.inputs.branch }}

Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/publish-self-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
runs-on: ubuntu-latest
environment: release
permissions:
# This is useful if you want to use PyPI trusted publisher
# and NPM provenance
id-token: write
steps:
- uses: actions/checkout@v4
Expand All @@ -27,11 +25,16 @@ jobs:
shell: bash
run: |
pip install -e .
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Populate Release
id: populate-release
uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
target: jupyter-server/jupyter_releaser
branch: ${{ github.event.inputs.branch }}
release_url: ${{ github.event.inputs.release_url }}
Expand All @@ -43,7 +46,7 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
target: ${{ github.event.inputs.target }}
release_url: ${{ steps.populate-release.outputs.release_url }}

Expand Down
7 changes: 7 additions & 0 deletions docs/source/background/theory.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ This project should help maintainers reduce toil and save time in the release pr
- Dry run publish on CI
- Revert to Dev version after release (optional)

## Security

We strive to use the most secure release practices possible, reflected in the `Checklist for Adoption`
and the example workflows.
This includes using PyPI Trusted Publishing, using GitHub Environments, encouraging the use of Rulesets and GitHub Apps with limited bypass capability, and provenance data for npm.
In addition, there is an automatic check for whether the user who triggered the action is an admin.

## Action Details

Detailed workflows are available to draft a changelog, draft a release, publish a release, and check a release.
Expand Down
52 changes: 33 additions & 19 deletions docs/source/how_to_guides/convert_repo_from_repo.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,32 @@ See checklist below for details:

## Checklist for Adoption

- [ ] Add a GitHub [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token), preferably from a "machine user" GitHub
account that has admin access to the repository. The token itself will
need "public_repo", and "repo:status" permissions. Save the token as
`ADMIN_GITHUB_TOKEN`
in the [repository secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository). We need this
access token to allow for branch protection rules, which block the pushing
of commits when using the `GITHUB_TOKEN`, even when run from an admin user
account.
- [ ] Set up a [GitHub App](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps#github-apps-that-act-on-their-own-behalf) on your organization (or personal account for a personal project).

- Disable the web hook
- Enable Repository permissions > Contents > Read and write
- Select "Only on this account"
- Click "Create GitHub App"
- Browse to the App Settings
- Select "Install App" and install on all repositories
- Under "General" click "Generate a private key"
- Store the `APP_ID` and the private key in a secure location (Jupyter Vault if using a Jupyter Org)

- [ ] Create a "release" [environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) on your repository and add an `APP_ID` Environment Variable and `APP_PRIVATE_KEY` secret.
The environment should be enabled for ["Protected branches only"](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-branches-and-tags).

- [ ] Configure [Rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets) for the repository

- Set up branch protection (with default rules) on publication branches
- Remove global tag protection.
- Add a branch Ruleset for all branches
- Allow the GitHub App to bypass protections
- Set up Pull Request and Required Checks
- Add a tags Ruleset for all tags
- Allow the GitHub App to bypass protections

- [ ] Set up PyPI:

<details><summary>Using PyPI token (legacy way)</summary>

- Add access token for the [PyPI registry](https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#saving-credentials-on-github) stored as `PYPI_TOKEN`.
_Note_ For security reasons, it is recommended that you scope the access
to a single repository. Additionally, this token should belong to a
machine account and not a user account.

</details>

<details><summary>Using PyPI trusted publisher (modern way)</summary>

- Set up your PyPI project by [adding a trusted publisher](https://docs.pypi.org/trusted-publishers/adding-a-publisher/)
Expand All @@ -45,10 +51,18 @@ See checklist below for details:

</details>

<details><summary>Using PyPI token (legacy way)</summary>

- Add access token for the [PyPI registry](https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#saving-credentials-on-github) stored as `PYPI_TOKEN`.
_Note_ For security reasons, it is recommended that you scope the access
to a single repository. Additionally, this token should belong to a
machine account and not a user account.

</details>

- [ ] If needed, add access token for [npm](https://docs.npmjs.com/creating-and-viewing-access-tokens), saved as `NPM_TOKEN`. Again this should
be created using a machine account that only has publish access.
- [ ] Ensure that only trusted users with 2FA have admin access to the
repository, since they will be able to trigger releases.
- [ ] Ensure that only trusted users with 2FA have admin access to the repository, since they will be able to trigger releases.
- [ ] Switch to Markdown Changelog
- We recommend [MyST](https://myst-parser.readthedocs.io/en/latest/?badge=latest), especially if some of your docs are in reStructuredText.
- Can use `pandoc -s changelog.rst -o changelog.md` and some hand edits as needed.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/how_to_guides/maintain_fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## How to keep fork of Jupyter Releaser up to date

- The manual workflow files target the `@v1` actions in the source repository, which means that as long as
- The manual workflow files target the `@v2` actions in the source repository, which means that as long as
the workflow files themselves are up to date, you will always be running the most up to date actions.

- Make sure your workflow is up to date by checking the "Fetch Upstream" dropdown on the main page of your fork.
Expand Down
44 changes: 31 additions & 13 deletions example-workflows/full-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,51 +27,69 @@ on:
description: "Comma separated list of steps to skip during Populate Release"
required: false
jobs:
full_release:
prep_release:
runs-on: ubuntu-latest
permissions:
# This is useful if you want to use PyPI trusted publisher
# and NPM provenance
id-token: write
contents: write
steps:
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Prep Release
id: prep-release
uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
version_spec: ${{ github.event.inputs.version_spec }}
# silent: ${{ github.event.inputs.silent }}
post_version_spec: ${{ github.event.inputs.post_version_spec }}
target: ${{ github.event.inputs.target }}
branch: ${{ github.event.inputs.branch }}
# silent: ${{ github.event.inputs.silent }}
since: ${{ github.event.inputs.since }}
since_last_stable: ${{ github.event.inputs.since_last_stable }}

publish_release:
needs: [prep_release]
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Populate Release
id: populate-release
uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
target: ${{ github.event.inputs.target }}
branch: ${{ github.event.inputs.branch }}
release_url: ${{ steps.prep-release.outputs.release_url }}
release_url: ${{ github.event.inputs.release_url }}
steps_to_skip: ${{ github.event.inputs.steps_to_skip }}

- name: Finalize Release
id: finalize-release
env:
# The following are needed if you use legacy PyPI set up
# PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
# PYPI_TOKEN_MAP: ${{ secrets.PYPI_TOKEN_MAP }}
# TWINE_USERNAME: __token__
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
target: ${{ github.event.inputs.target }}
release_url: ${{ steps.populate-release.outputs.release_url }}

- name: "** Next Step **"
if: ${{ success() }}
run: |
echo "Verify the final release"
echo ${{ steps.finalize-release.outputs.release_url }}
- name: "** Failure Message **"
if: ${{ failure() }}
run: |
echo "Failed to Publish the Draft Release Url:"
echo ${{ steps.populate-release.outputs.release_url }}
7 changes: 5 additions & 2 deletions example-workflows/prep-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,21 @@ on:
jobs:
prep_release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Prep Release
id: prep-release
uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
version_spec: ${{ github.event.inputs.version_spec }}
# silent: ${{ github.event.inputs.silent }}
post_version_spec: ${{ github.event.inputs.post_version_spec }}
target: ${{ github.event.inputs.target }}
branch: ${{ github.event.inputs.branch }}
# silent: ${{ github.event.inputs.silent }}
since: ${{ github.event.inputs.since }}
since_last_stable: ${{ github.event.inputs.since_last_stable }}

Expand Down
10 changes: 9 additions & 1 deletion example-workflows/publish-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,21 @@ on:
jobs:
publish_changelog:
runs-on: ubuntu-latest
environment: release
steps:
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Publish changelog
id: publish-changelog
uses: jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
branch: ${{ github.event.inputs.branch }}

- name: "** Next Step **"
Expand Down
17 changes: 9 additions & 8 deletions example-workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,34 @@ on:
jobs:
publish_release:
runs-on: ubuntu-latest
environment: release
permissions:
# This is useful if you want to use PyPI trusted publisher
# and NPM provenance
id-token: write
steps:
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Populate Release
id: populate-release
uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
branch: ${{ github.event.inputs.branch }}
release_url: ${{ github.event.inputs.release_url }}
steps_to_skip: ${{ github.event.inputs.steps_to_skip }}

- name: Finalize Release
id: finalize-release
env:
# The following are needed if you use legacy PyPI set up
# PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
# PYPI_TOKEN_MAP: ${{ secrets.PYPI_TOKEN_MAP }}
# TWINE_USERNAME: __token__
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2
with:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
release_url: ${{ steps.populate-release.outputs.release_url }}

- name: "** Next Step **"
Expand Down

0 comments on commit a349a20

Please sign in to comment.