Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ckipp01/mill-ci-release
A Mill plugin to help making publishing to Sonatype from GitHub Actions easier.
https://github.com/ckipp01/mill-ci-release
mill mill-plugin
Last synced: 11 days ago
JSON representation
A Mill plugin to help making publishing to Sonatype from GitHub Actions easier.
- Host: GitHub
- URL: https://github.com/ckipp01/mill-ci-release
- Owner: ckipp01
- License: apache-2.0
- Created: 2022-08-30T05:53:41.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-22T08:25:37.000Z (3 months ago)
- Last Synced: 2024-10-10T14:27:26.855Z (about 1 month ago)
- Topics: mill, mill-plugin
- Language: Scala
- Homepage:
- Size: 143 KB
- Stars: 14
- Watchers: 3
- Forks: 6
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# mill-ci-release
This is a [Mill][mill] plugin modeled after the fantastic
[sbt-ci-release][sbt-ci-release] plugin which helps automate publishing to
[Sonatype][sonatype] from GitHub Actions with as little friction as possible.
These are the key features of using the plugin.- A new git tag is published as a regular release
- A merge is published as a SNAPSHOT release
- Auto versioning based on git by [mill-vcs-version][mill-vcs-version]
- A simple one-liner in CI to publish## Getting Started
If you've never published to Sonatype before you'll need to do a one-time setup
per domain name that you're publishing under. You can find the instructions for
this [here][sonatype-setup]. If you don't have a domain name you can use
`io.github.<@your_username>`.**NOTE**: Keep in mind that as of February 2021 newly created accounts and group ids (even if your account was created before February 2021) are tied
to https://s01.oss.sonatype.org/ whereas older accounts will be tied to
https://oss.sonatype.org/. This matters when logging in. You'll also want to
make sure you set `sonatypeHost` to `Some(SonatypeHost.s01)` in this scenario. See [this section](#im-getting-a-403-when-attempting-to-publish-and-i-have-my-env-variables-correct)### Installing the Plugin
To start using this plugin you'll want to include the following import in your
build file:```scala
import $ivy.`io.chris-kipp::mill-ci-release::`
```This plugin under the hood uses [mill-vcs-version][mill-vcs-version] to manage
your version, so if you have a `publishVersion` set, remove it. The reason for
this is that mill-ci-release is making sure that when you're on a snapshot
version, it's appending `-SNAPSHOT` which is necessary to publish to Sonatype
Snapshots. You still can override `publishVersion` locally, but then you're 100%
on your own to ensure that `-SNAPSHOT` is appended when necessary. This might
just be easily included in the plugin in the [future][mill-vcs-discussion].The only other thing you'll need to do to your build is replace `PublishModule`
with `CiReleaseModule`.```diff
- import de.tobiasroeser.mill.vcs.version.VcsVersion
+ import io.kipp.mill.ci.release.CiReleaseModuleobject example
extends ScalaModule
- with PublishModule {
+ with CiReleaseModule {- def publishVersion = VcsVersion.vcsState().format()
```You'll still need to ensure your `pomSettings` are correctly filled in, just as
if you were extending `PublishModule`.**NOTE**: Again, if you have a newly created account (as of February 2021)
you'll also want to ensure you add the following:```diff
+ import io.kipp.mill.ci.release.SonatypeHost
...
+ override def sonatypeHost = Some(SonatypeHost.s01)
```This will then set the correct `sonatypeUri` and `sonatypeSnapshotUri` for you.
If you have an older account, then there is no need to change the default or use
`sonatypeHost` at all.### Using with custom Sonatype Nexus instances
If you're using your own instance of Sonatype Nexus, your configuration needs to be adapted slightly:
```diff
- override def sonatypeHost = Some(SonatypeHost.s01)
+ override def sonatypeUri = "https://your-sonatype-nexus.url/path/to/releases"
+ override def sonatypeSnapshotUri = "https://your-sonatype-nexus.url/path/to/snapshots"
+
+ // The Open Source version of Nexus does not support staging
+ override def stagingRelease = false
```### GPG
If you've never created a keypair before that can be used to sign your artifacts
you'll need to do this. You can find a guide for doing this [here][gpg].### Secrets
Before using mill-ci-release in your GitHub actions workflow you'll need to have
the following secrets defined. You can add these by going to repo `Settings ->
Secrets -> New repository secret`.Here are the necessary secrets:
- `PGP_PASSPHRASE`: The passphrase that was used when creating your keypair.
This will be the same passphrase that you're prompted to use when copying
the value for your `PGP_SECRET`.
- `PGP_SECRET`: A base64 encoded secret of your private key that you can export
from the command line like below:```
# macOS
gpg --export-secret-key -a $LONG_ID | base64 | pbcopy
# Ubuntu (assuming GNU base64)
gpg --export-secret-key -a $LONG_ID | base64 -w0 | xclip
# Arch
gpg --export-secret-key -a $LONG_ID | base64 | sed -z 's;\n;;g' | xclip -selection clipboard -i
# FreeBSD (assuming BSD base64)
gpg --export-secret-key -a $LONG_ID | base64 | xclip
# Windows
gpg --export-secret-key -a %LONG_ID% | openssl base64
```- `SONATYPE_USERNAME`: The username you use to log into your Sonatype account.
- `SONATYPE_PASSWORD`: The password you use to log into your Sonatype account.### GitHub Actions
You can use an exact copy of what is being used in this repo to publish by
doing the following command:```
curl -sLo .github/workflows/release.yml --create-dirs https://raw.githubusercontent.com/ckipp01/mill-ci-release/main/.github/workflows/release.yml
```This will create a `.github/workflows/release.yml` file which will be triggered
by a new git tag or a merge to `main`. The contents should look like this:```yaml
name: Release
on:
push:
branches:
- main
tags: ["*"]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- run: ./mill -i io.kipp.mill.ci.release.ReleaseModule/publishAll
env:
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
PGP_SECRET: ${{ secrets.PGP_SECRET }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
```By default, this will publish all of your modules that are extending
`CiReleaseModule`.## How does this differ from just using Mill?
The underlying publish should actually be identical as it's using the same
[Sonatype publisher][mill-publisher]. The difference is only in the set up.
Below is a comparison of what you'll commonly see with Mill to release vs using
mill-ci-release.```diff
- name: Publish
+ run: ./mill -i io.kipp.mill.ci.release.ReleaseModule/publishAll
- run: |
- if [[ $(git tag --points-at HEAD) != '' ]]; then
- echo $PGP_PRIVATE_KEY | base64 --decode > gpg_key
- gpg --import --no-tty --batch --yes gpg_key
- rm gpg_key
- ./mill -i mill.scalalib.PublishModule/publishAll \
- --publishArtifacts __.publishArtifacts \
- --sonatypeUri "https://s01.oss.sonatype.org/service/local" \
- --sonatypeSnapshotUri "https://s01.oss.sonatype.org/content/repositories/snapshots" \
- --sonatypeCreds $SONATYPE_USER:$SONATYPE_PASSWORD \
- --gpgArgs --passphrase=$PGP_PASSWORD,--no-tty,--pinentry-mode,loopback,--batch,--yes,-a,-b \
- --readTimeout 600000 \
- --awaitTimeout 600000 \
- --release true \
- --signed true
- fi
```## FAQs
#### I'm getting a 403 when attempting to publish and I have my env variables correct
Most often this is due to not correctly setting the following if you have a new
account or group id:```scala
override def sonatypeHost = Some(SonatypeHost.s01)
```_Or manually doing_
```scala
override def sonatypeUri = "https://s01.oss.sonatype.org/service/local"
override def sonatypeSnapshotUri =
"https://s01.oss.sonatype.org/content/repositories/snapshots"
```#### It's publishing a 0.0.0-something-SNAPSHOT even though I have a git tag
If you see this it's probably because you forgot to add the `fetch-depth` in
checkout, meaning that no git tags are getting pulled in CI:```yaml
- uses: actions/checkout@v3
with:
fetch-depth: 0
```## Notes
This plugin has only really been tested on more minimal projects. There is
purposefully not many configuration options mainly because I firmly believe in
sane defaults that should easily allow what most users want to do with minimal
setup. If you're missing certain configuration options, please do open a
discussion or an issue and we can explore adding more customization options to
this.[mill]: https://com-lihaoyi.github.io/mill/mill/Intro_to_Mill.html
[sbt-ci-release]: https://github.com/sbt/sbt-ci-release
[sonatype]: https://www.sonatype.com/
[mill-vcs-version]: https://github.com/lefou/mill-vcs-version
[sonatype-setup]: https://central.sonatype.org/pages/ossrh-guide.html
[mill-vcs-discussion]: https://github.com/lefou/mill-vcs-version/discussions/62
[gpg]: https://central.sonatype.org/publish/requirements/gpg/
[mill-publisher]: https://github.com/com-lihaoyi/mill/blob/main/scalalib/src/publish/SonatypePublisher.scala