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

doc: Github release workflows #585

Open
LecrisUT opened this issue Apr 15, 2024 · 10 comments
Open

doc: Github release workflows #585

LecrisUT opened this issue Apr 15, 2024 · 10 comments

Comments

@LecrisUT
Copy link

LecrisUT commented Apr 15, 2024

It would be nice to document some Github workflow designs that the user can use. I have not included the example yamls, since I am not sure about the cli interface to run this, after studying it a bit, or if someone comments with some implementation I will update this post.

on.workflow_dispatch

Uses inputs to specify what version to tag (and on which commit/branch to checkout).

Steps:

  • Update the Changelog.md
  • Create/Push a new commit
  • Create a new tag
  • Create github release

Pros:

  • Most flexible release cycle

Cons:

  • Cannot trigger CI with on.push.tag (unless PAT is used)

on.push.tag

Current release cycle is already configured

Steps:

  • Create github release
  • Update the Changelog.md for next release cycle (tagging the date for old cycle)
  • Create/Push new commit

Pros:

  • Simple workflow
  • Can integrate with other workflows
  • Signable git tags

Cons:

  • Harder to manage bug fix releases
@adiroiban
Copy link
Member

Hi. Thanks for the report.

I think that we should start by using some "reference" command as part of towncrier's GHA YAML file.

We currently have this

task:
- name: Check Newsfragment
run: |
nox -e check_newsfragment
nox -e draft_newsfragment >> $GITHUB_STEP_SUMMARY

but this is called via nox... which makes it a bit harder to read.


One idea is to create a separate composite job for GitHub Actions that can be used as an example for others.


Regarding workflow_dispatch vs push and Cons: Harder to manage bug fix releases

can you please add more details about why it's harder to use towncrier for bugfix releases ?

Thanks

@LecrisUT
Copy link
Author

One idea is to create a separate composite job for GitHub Actions that can be used as an example for others.

Composite action or reusable workflow? The latter addresses how one can design the triggers, inputs, etc. But the former would still be nice to have as well in order to simplify the execution and export the variables. The action could also handle some of the tagging, but that needs to be discussed with an actual implementation and interface.

For the reusable workflow though, everyone might have different usage, e.g. how to handle the release notes. I think for this case it will be better to document instead and discuss how one would use either workflows, what other tools one can integrate this with, etc.

Design wise, I would say using pipx would be preferred because it is pre-built and skips the python-setup action. Although I am not sure if it can integrate with python-setup if users would prefer to use a specific python environment.


Regarding workflow_dispatch vs push and Cons: Harder to manage bug fix releases

can you please add more details about why it's harder to use towncrier for bugfix releases ?

Thanks

I need to get back in the headspace where I was when I wrote that.

  • Changelog.md would differ if the bug fixes are cherry-picked on a separate release branch. Getting the Changelog.md back in sync would be tricky there to not have duplication.
    But this issue is present for both cases, so I don't think this is what I was considering
  • One difference between these 2 is where the tag appears. workflow_dispatch the tag is after Changelog.md is changed, while push the tag is before that. In the later, the source would not have changes so it might be harder to figure out what are the changes for the specific tag
    This is probably what I was thinking of then, but it's not exactly about managing bug fix releases

But the more I think about it the more skeptical I am of on.push.tag. It would be nice for the maintainers, but is there an actual way of implementing it?

@adiroiban
Copy link
Member

I am not sure what are the problems that you want to solve using towncrier

For CI, you usually want to use the towncrier check command.

We have the general usage documentation here.

If someting is not clear, we might want to start by improving that documentation.

towncrier check is executed for every commit, before a merge into the main branch.

@LecrisUT
Copy link
Author

Sorry, I was intending to write up an example workflow, which would describe the issue more clearly. This is not about a CI workflow, but a CD workflow, i.e. how to create the tag and/or release using the contents of a .changelog.d. For example, one CD workflow I have in a project looks like:

.github/workflows/release.yaml
name: 🚀 release
run-name: Release ${{ github.ref_name }}

on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"

jobs:
  tests:
    name: tests
    uses: ./.github/workflows/step_test.yaml
  build-wheel:
    name: build-wheel
    needs: [ tests ]
    uses: ./.github/workflows/step_build-wheel.yaml
  upload_pypi:
    name: Upload to PyPI repository
    needs: [ tests, build-wheel ]
    runs-on: ubuntu-latest
    environment:
      name: pypi
      url: https://pypi.org/project/spglib/
    permissions:
      id-token: write
    steps:
      - name: Get sdist
        uses: actions/download-artifact@v4
        with:
          name: Packages
          path: dist
      - name: Get wheels
        uses: actions/download-artifact@v4
        with:
          pattern: cibw-wheels-*
          path: dist
          merge-multiple: true
      - name: Publish package to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
  release:
    needs: [ upload_pypi ]
    name: Create release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: softprops/action-gh-release@v1
        with:
          name: Spglib ${{ github.ref_name }}
          draft: true
          prerelease: ${{ contains(github.ref, 'rc') }}
          generate_release_notes: true

Some example workflows would help figure out how to integrate with this release automation.

The design questions to answer:

  • where to put tonwcrier build command
  • towncrier generates the Changelog.md which would need to be committed in the project, but how would one add this to the workflow

@adiroiban
Copy link
Member

I don't think that towncrier was designed for this use case.

You might want to check https://docs.openstack.org/reno/latest/ ... I have not used, but from what I remember, you don't need to commit anything. it alwasy keeps all the fragments and always re-generates the release notes


towncrier was designed to be used in a release process that works something like the one documented here https://towncrier.readthedocs.io/en/latest/release.html

you manually generage the version number, commit the release notes and the push the tag.

@LecrisUT
Copy link
Author

I understand, that's why I was showing the 2 workflows to also give the user ideas of how to adapt from 1 to another. The release workflow there is to show-case where a user might be coming from and what they would need to adapt.

There could be 2 approaches here:

  • reconfigure the workflow to trigger on dispatch. The problem to be solved there is how to migrate the workflow steps that they might have. I think the example I have would be the minimal complex workflow that would be a steppingstone for users to start from
  • keep push on tag, but re-tag commit after the release notes are generated. This can be easily supported in the current workflow by changing the checkout commit/tag to use in subsequent steps. Haven't tested such a workflow though

@adiroiban
Copy link
Member

Feel free to send a PR with what you thing might be useful ... or wait for others to add more feedback to this issue.

I am using a different release process, so I am not very familiar with the problem that is discusses here.

@LecrisUT
Copy link
Author

LecrisUT commented Aug 2, 2024

I have a new reference more similar withon.workflow_dispatch. See changeset/action (example where it creates an "immortal PR" that is rebased for every push to main recreating the final CHANGELOG.md such that the developer needs only to merge the PR when the release is finished, after which a similar workflow would do the tagging + release. Isn't this more inline with the current workflow using towncrier?

@adiroiban
Copy link
Member

I am not using on.workflow_dispatch or changeset project... so I can't provide any feedback. Sorry.
We can leave this ticket open to allow other to add their feedback.

@LecrisUT
Copy link
Author

LecrisUT commented Aug 6, 2024

The comment on the on.workflow_dispatch is a bit of a red-herring in this discussion. Please check the links of the working example I posted there. The workflow is as follows:

  • After any commit to main, there is a GH action that constructs CHANGELOG.md from the snippets, i.e. towncrier build. These are then committed and pushed to a Release PR. (Note, due to GH action being what it is, GH workflows cannot run on that PR)
  • When you wish to cut the release merge/queue the PR, at which point a different workflow creates the tag and release, bumps the version, etc. All of this being unrelated to towncrier itself since at this point the CHANGELOG.md is already ready for developing the next cycle

The comment about on.workflow_dispatch is because you could automate the first part to also run on on.workflow_dispatch where you specify the git commit/branch and tag if you want to backport changes and reuse the changelog snippets from the cherry-picked commits.


With regards to the documentation, the first part is rather straightforward to document, or even create a reusable github action/workflow if you are willing to host it. On the user side it could look something like this:

name: Prepare release

on:
  push:
    branches: [main]

jobs:
  update-release:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-python@v5
      with:
        python-version: 3.x
    - name: Update CHANGELOG.md and push to release PR
      run: |
        pip install towncrier
        towncrier build
        git add -A
        git commit -m "Release X.Y"
        git push --force release/X.Y
        gh pr create --title "Release X.Y"

Designing the second part is the tricky bit

name: Prepare release

on:
  pull_request:
    types: [enqueued, closed]
    branches: [release/**]

jobs:
  publish-release:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Create and push tag
      run: |
        git tag vX.Y
        git push vX.Y
    - name: Create GitHub release
      uses: softprops/action-gh-release@v2
      with:
        name: vX.Y

These are just some rough drafts of these which at least covers the main steps of the automation.


Edit: I've found some other interesting GH actions that can help:

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

2 participants