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

Release via GHA #229

Merged
merged 11 commits into from
Nov 30, 2023
Merged

Release via GHA #229

merged 11 commits into from
Nov 30, 2023

Conversation

jonathonherbert
Copy link
Contributor

@jonathonherbert jonathonherbert commented Oct 9, 2023

What does this change?

Automates the release of the Sonatype and NPM packages generated by this project.

How to test

I've run this action manually with a hardcoded workflow and version 17.8.0-beta.0, and we have releases for sonatype and npm.

@jonathonherbert jonathonherbert force-pushed the jsh/release-via-gh-actions branch 10 times, most recently from 01e20c9 to e9d5674 Compare October 12, 2023 16:55
@jonathonherbert jonathonherbert force-pushed the jsh/release-via-gh-actions branch 11 times, most recently from 1e22f18 to f975b31 Compare November 13, 2023 15:35
@jonathonherbert jonathonherbert marked this pull request as ready for review November 13, 2023 15:42
@jonathonherbert jonathonherbert requested a review from a team as a code owner November 13, 2023 15:42
@jonathonherbert
Copy link
Contributor Author

Merging, but noting that it'd be good to include https://github.com/guardian/actions-sbt-release in future to remove SBT release boilerplate.

@jonathonherbert jonathonherbert merged commit d892745 into master Nov 30, 2023
1 check passed
@jonathonherbert jonathonherbert deleted the jsh/release-via-gh-actions branch November 30, 2023 12:34
rtyley added a commit to guardian/gha-scala-library-release-workflow that referenced this pull request Jan 4, 2024
This addresses #10,
providing support for publishing *preview* releases based off feature branches, ie PRs.

The UX of doing a preview release is very similar to the existing process for doing a full
release (https://github.com/guardian/gha-scala-library-release-workflow/blob/main/docs/making-a-release.md),
with only these differences:

* The developer needs to select the PR branch before clicking the green `Run workflow` button
* The version number will be the **upcoming** version number, but with a suffix that clearly
  indicates this is a preview release, eg: `1.0.7-PREVIEW.feature1.2024-01-04T1230.42ed11d4`.
  Note that this is _not_ a `-SNAPSHOT` release, the workflow does not support `SNAPSHOT`
  releases.
* No branches are updated by the release (ie, not the PR's feature branch, and not the
  default `main` branch) - the preview release commit exists as its own tagged commit,
  taking the latest PR commit as its parent.
* GitHub release notes will not be created, but instead the PR using that branch will be
  updated with a comment providing details of the new release (version number, etc).

Internally, these 'preview release' changes take place if a non-default branch (ie a feature
branch, not `main`) is used:

* The `🔒 Init` job `release_type` output is `PREVIEW_FEATURE_BRANCH` rather than `FULL_MAIN_BRANCH`
* Only 1 commit is pushed by the workflow, rather than 2, and _not_ onto the branch - the
  single commit exists as a tagged leaf to the side of the PR branch. The 2nd commit normally needed
  by the full release process (incrementing the version number and adding the `-SNAPSHOT`
  suffix) is not needed for preview releases - there are already enough details in the `-PREVIEW`
  version-suffix to keep preview releases unique, even if you do many releases for 1 commit in 1 PR.
* When that 1 commit is pushed, it's initially pushed with a _disposable_ Git tag - not the
  _release_ tag. Pushing _any_ commit requires either a branch or tag for the `git push` command
  to work on (you can't just push a commit id - I've tried), and there is no pre-existing suitable
  branch (we don't want to modify the PR feature branch) or tag (the release tag has an annotation
  message including the hashes of all artifact files generated by the release, and at the point
  when the commit is pushed, those artifacts & their hashes are not available yet), so we have to use
  a new, different, disposable, Git tag instead.

## Choice of version-suffix for preview releases

https://semver.org/#spec-item-9 says:

> 9. A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92, 1.0.0-x-y-z.--.
>
> 10. Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3----117B344092BD.

### How can we prevent tooling from thinking our preview releases are stable releases?

If we're not using the `-SNAPSHOT` suffix, there's a risk that tooling will assume that our preview releases are stable releases, and attempt to auto-upgrade to them.

* IntelliJ automatically suggests dependency upgrades - it uses `PackageVersionNormalizer` with specific stability tokens that include 'preview'
* Scala Steward raises dependency upgrade PRs - it uses `isPreRelease` which recognises `Hash` (6+ or 8 hex chars) & specific `Alpha` components that include 'preview'. See also scala-steward-org/scala-steward#1033, scala-steward-org/scala-steward#1549 etc
* Scaladex uses PreRelease.scala - scalacenter/scaladex#614

Consequently, to be certain of being recognised as a pre-release, it seems wise to include these components in the version number:

* 'PREVIEW'
* a commit hash of at least 8 characters

### NPM version numbers...

Some Guardian libraries are released simultaneously for both Scala and other platforms like NPM
(for instance, `content-api-models`, see guardian/content-api-models#229).
Both NPM and sbt/Maven work well with simple three-number semver version numbers, but how well will
NPM handle extended version number like `1.0.7-PREVIEW.feature1.2024-01-04T1230.42ed11d4` ?

### 'PREVIEW', 'BETA', 'ALPHA', or...?

Justin points out the 'PREVIEW' has a particular meaning for the Content Pipeline team ('Preview' vs 'Live'
content) - could potentially cause some confusion there.

I initially chose 'PREVIEW' (from the identifiers that IntelliJ & Scala Steward understand) partially
because both 'BETA' & 'ALPHA' imply some meaning about the stage of development in the software release
cycle that may or may not be appropriate - it's not obvious which one truly reflects what we're doing
when we make an early release from a PR, and it's annoying to have to choose. Additionally, looking at
the Wikipedia article that describes the different stages - the label 'pre-alpha' might even be more
appropriate: https://en.wikipedia.org/wiki/Software_release_life_cycle

## Problems with backticks

Ideally we would be generating a markdown message for the PR comment with lots of backticks
for styling:

https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks

...like this:

rtyley/sample-project-using-gha-scala-library-release-workflow#1 (comment)

...but they get interpreted by BASH, and cause trouble...

https://github.com/rtyley/sample-project-using-gha-scala-library-release-workflow/actions/runs/7399435634/job/20130944058

...so for the time being this PR avoids them in the generated PR comment.
rtyley added a commit that referenced this pull request Jan 24, 2024
This change adopts `gha-scala-library-release-workflow` for publishing releases,
replacing some of the work done in PR #229 and providing some improvements:

* Automatic version-numbering based on automated compatibility-assessment by sbt-version-policy
* Standardisation with the other projects across the Guardian that have also adopted the workflow
* Reduced configuration (fewer sbt settings, and less workflow yaml)

This specific commit only provides Scala Maven release, removing NPM release
capability, but NPM release capability is returned in the next commit.
rtyley added a commit that referenced this pull request Jan 24, 2024
This change adopts `gha-scala-library-release-workflow` for publishing releases,
replacing some of the work done in PR #229 and providing some improvements:

* Automatic version-numbering based on automated compatibility-assessment by sbt-version-policy
* Standardisation with the other projects across the Guardian that have also adopted the workflow
* Reduced configuration (fewer sbt settings, and less workflow yaml)

This specific commit only provides Scala Maven release, removing NPM release
capability, but NPM release capability is returned in the next commit.
rtyley added a commit that referenced this pull request Jan 24, 2024
This is in addition to the Scala Maven release provided by the previous
commit. This change is only separated out from the previous commit to
show how the 'standard' release.yml has been modified for this dual
Scala & Typescript release workflow.

Note that #229 already
did a lot of the work involved in getting automated NPM releases going,
this is just a refactoring to work better with the
gha-scala-library-release-workflow.
rtyley added a commit that referenced this pull request Jan 24, 2024
This is in addition to the Scala Maven release provided by the previous
commit. This change is only separated out from the previous commit to
show how the 'standard' release.yml has been modified for this dual
Scala & Typescript release workflow.

This is a first for gha-scala-library-release-workflow - so far that
workflow has only been used for publishing Scala projects to Maven - but
the earlier work done in PR #229 supported automated release to both Maven
and NPM (for NPM, we're talking Typescript artifacts generated from Thrift
by scrooge-extras), and so it was important to continue to that support.

Rather than teach the gha-scala-library-release-workflow reusable-release.yml
how to publish NPM artifacts, it was easier to just modify the standard
release.yml workflow that calls reusable-release.yml, adding an additional
NPM Release workflow job after the Maven release process.
rtyley added a commit that referenced this pull request Jan 24, 2024
This change adopts `gha-scala-library-release-workflow` for publishing releases,
replacing some of the work done in PR #229 and providing some improvements:

* Automatic version-numbering based on automated compatibility-assessment by sbt-version-policy
* Standardisation with the other projects across the Guardian that have also adopted the workflow
* Reduced configuration (fewer sbt settings, and less workflow yaml)

This specific commit only provides Scala Maven release, removing NPM release
capability, but NPM release capability is returned in the next commit.
rtyley added a commit that referenced this pull request Jan 24, 2024
This is in addition to the Scala Maven release provided by the previous
commit. This change is only separated out from the previous commit to
show how the 'standard' release.yml has been modified for this dual
Scala & Typescript release workflow.

This is a first for gha-scala-library-release-workflow - so far that
workflow has only been used for publishing Scala projects to Maven - but
the earlier work done in PR #229 supported automated release to both Maven
and NPM (for NPM, we're talking Typescript artifacts generated from Thrift
by scrooge-extras), and so it was important to continue to that support.

Rather than teach the gha-scala-library-release-workflow reusable-release.yml
how to publish NPM artifacts, it was easier to just modify the standard
release.yml workflow that calls reusable-release.yml, adding an additional
NPM Release workflow job after the Maven release process.
rtyley added a commit that referenced this pull request Jan 24, 2024
This change adopts `gha-scala-library-release-workflow` for publishing releases,
replacing some of the work done in PR #229 and providing some improvements:

* Automatic version-numbering based on automated compatibility-assessment by sbt-version-policy
* Standardisation with the other projects across the Guardian that have also adopted the workflow
* Reduced configuration (fewer sbt settings, and less workflow yaml)

This specific commit only provides Scala Maven release, removing NPM release
capability, but NPM release capability is returned in the next commit.
rtyley added a commit that referenced this pull request Jan 24, 2024
This is in addition to the Scala Maven release provided by the previous
commit. This change is only separated out from the previous commit to
show how the 'standard' release.yml has been modified for this dual
Scala & Typescript release workflow.

This is a first for gha-scala-library-release-workflow - so far that
workflow has only been used for publishing Scala projects to Maven - but
the earlier work done in PR #229 supported automated release to both Maven
and NPM (for NPM, we're talking Typescript artifacts generated from Thrift
by scrooge-extras), and so it was important to continue to that support.

Rather than teach the gha-scala-library-release-workflow reusable-release.yml
how to publish NPM artifacts, it was easier to just modify the standard
release.yml workflow that calls reusable-release.yml, adding an additional
NPM Release workflow job after the Maven release process.
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

Successfully merging this pull request may close these issues.

None yet

2 participants