{"id":15667330,"url":"https://github.com/ckipp01/mill-ci-release","last_synced_at":"2025-03-31T13:31:26.329Z","repository":{"id":65508484,"uuid":"530517028","full_name":"ckipp01/mill-ci-release","owner":"ckipp01","description":"A Mill plugin to help making publishing to Sonatype from GitHub Actions easier.","archived":false,"fork":false,"pushed_at":"2025-03-18T05:02:00.000Z","size":168,"stargazers_count":16,"open_issues_count":7,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-30T14:05:01.831Z","etag":null,"topics":["mill","mill-plugin"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ckipp01.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"ckipp01"}},"created_at":"2022-08-30T05:53:41.000Z","updated_at":"2025-03-28T02:21:13.000Z","dependencies_parsed_at":"2024-02-20T09:28:49.695Z","dependency_job_id":"beedde6f-5b06-4429-a24f-bcc1f32157f3","html_url":"https://github.com/ckipp01/mill-ci-release","commit_stats":{"total_commits":122,"total_committers":9,"mean_commits":"13.555555555555555","dds":0.5163934426229508,"last_synced_commit":"ce4bbae2b5a4fb25a6b6d696487604adae15a098"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckipp01%2Fmill-ci-release","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckipp01%2Fmill-ci-release/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckipp01%2Fmill-ci-release/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckipp01%2Fmill-ci-release/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ckipp01","download_url":"https://codeload.github.com/ckipp01/mill-ci-release/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246473836,"owners_count":20783354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mill","mill-plugin"],"created_at":"2024-10-03T14:02:34.892Z","updated_at":"2025-03-31T13:31:26.318Z","avatar_url":"https://github.com/ckipp01.png","language":"Scala","funding_links":["https://github.com/sponsors/ckipp01"],"categories":[],"sub_categories":[],"readme":"# mill-ci-release\n\nThis is a [Mill][mill] plugin modeled after the fantastic\n[sbt-ci-release][sbt-ci-release] plugin which helps automate publishing to\n[Sonatype][sonatype] from GitHub Actions with as little friction as possible.\nThese are the key features of using the plugin.\n\n- A new git tag is published as a regular release\n- A merge is published as a SNAPSHOT release\n- Auto versioning based on git by [mill-vcs-version][mill-vcs-version]\n- A simple one-liner in CI to publish\n\n## Getting Started\n\nIf you've never published to Sonatype before you'll need to do a one-time setup\nper domain name that you're publishing under. You can find the instructions for\nthis [here][sonatype-setup]. If you don't have a domain name you can use\n`io.github.\u003c@your_username\u003e`.\n\n**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\nto \u003chttps://s01.oss.sonatype.org/\u003e whereas older accounts will be tied to\n\u003chttps://oss.sonatype.org/\u003e. This matters when logging in. You'll also want to\nmake 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)\n\n### Installing the Plugin\n\nTo start using this plugin you'll want to include the following import in your\nbuild file:\n\n```scala\nimport $ivy.`io.chris-kipp::mill-ci-release::\u003clatest-version\u003e`\n```\n\nThis plugin under the hood uses [mill-vcs-version][mill-vcs-version] to manage\nyour version, so if you have a `publishVersion` set, remove it. The reason for\nthis is that mill-ci-release is making sure that when you're on a snapshot\nversion, it's appending `-SNAPSHOT` which is necessary to publish to Sonatype\nSnapshots. You still can override `publishVersion` locally, but then you're 100%\non your own to ensure that `-SNAPSHOT` is appended when necessary. This might\njust be easily included in the plugin in the [future][mill-vcs-discussion].\n\nThe only other thing you'll need to do to your build is replace `PublishModule`\nwith `CiReleaseModule`.\n\n```diff\n- import de.tobiasroeser.mill.vcs.version.VcsVersion\n+ import io.kipp.mill.ci.release.CiReleaseModule\n\nobject example \n    extends ScalaModule\n-    with PublishModule {\n+    with CiReleaseModule {\n\n-  def publishVersion = VcsVersion.vcsState().format()\n```\n\nTo publish snapshots overwriting the previous version with an incremental minor version,\nyou can define the following in your module that extends `CiReleaseModule`:\n\n```scala\n    extends ScalaModule\n    with CiReleaseModule {\n\n  override def flatSnapshot = true\n```\n\nWith this setting, the version will be incremented by one minor version for each snapshot release.\n\nEg. if the last release was `0.4.3`, the next snapshot release will be `0.5-SNAPSHOT`.\n\nYou'll still need to ensure your `pomSettings` are correctly filled in, just as\nif you were extending `PublishModule`.\n\n**NOTE**: Again, if you have a newly created account (as of February 2021)\nyou'll also want to ensure you add the following:\n\n```diff\n+ import io.kipp.mill.ci.release.SonatypeHost\n...\n+  override def sonatypeHost = Some(SonatypeHost.s01)\n```\n\nThis will then set the correct `sonatypeUri` and `sonatypeSnapshotUri` for you.\nIf you have an older account, then there is no need to change the default or use\n`sonatypeHost` at all.\n\n### Using with custom Sonatype Nexus instances\n\nIf you're using your own instance of Sonatype Nexus, your configuration needs to be adapted slightly:\n\n```diff\n-  override def sonatypeHost = Some(SonatypeHost.s01)\n+  override def sonatypeUri = \"https://your-sonatype-nexus.url/path/to/releases\"\n+  override def sonatypeSnapshotUri = \"https://your-sonatype-nexus.url/path/to/snapshots\"\n+\n+  // The Open Source version of Nexus does not support staging\n+  override def stagingRelease = false\n```\n\n### GPG\n\nIf you've never created a keypair before that can be used to sign your artifacts\nyou'll need to do this. You can find a guide for doing this [here][gpg].\n\n### Secrets\n\nBefore using mill-ci-release in your GitHub actions workflow you'll need to have\nthe following secrets defined. You can add these by going to repo `Settings -\u003e\nSecrets -\u003e New repository secret`.\n\nHere are the necessary secrets:\n\n- `PGP_PASSPHRASE`: The passphrase that was used when creating your keypair.\n    This will be the same passphrase that you're prompted to use when copying\n    the value for your `PGP_SECRET`.\n- `PGP_SECRET`: A base64 encoded secret of your private key that you can export\n    from the command line like below:\n\n```\n# macOS\ngpg --export-secret-key -a $LONG_ID | base64 | pbcopy\n# Ubuntu (assuming GNU base64)\ngpg --export-secret-key -a $LONG_ID | base64 -w0 | xclip\n# Arch\ngpg --export-secret-key -a $LONG_ID | base64 | sed -z 's;\\n;;g' | xclip -selection clipboard -i\n# FreeBSD (assuming BSD base64)\ngpg --export-secret-key -a $LONG_ID | base64 | xclip\n# Windows\ngpg --export-secret-key -a %LONG_ID% | openssl base64\n```\n\n- `SONATYPE_USERNAME`: The username you use to log into your Sonatype account.\n- `SONATYPE_PASSWORD`: The password you use to log into your Sonatype account.\n\n### GitHub Actions\n\nYou can use an exact copy of what is being used in this repo to publish by\ndoing the following command:\n\n```\ncurl -sLo .github/workflows/release.yml --create-dirs https://raw.githubusercontent.com/ckipp01/mill-ci-release/main/.github/workflows/release.yml\n```\n\nThis will create a `.github/workflows/release.yml` file which will be triggered\nby a new git tag or a merge to `main`. The contents should look like this:\n\n```yaml\nname: Release\non:\n  push:\n    branches:\n      - main\n    tags: [\"*\"]\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '17'\n      - run: ./mill -i io.kipp.mill.ci.release.ReleaseModule/publishAll\n        env:\n          PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}\n          PGP_SECRET: ${{ secrets.PGP_SECRET }}\n          SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}\n          SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}\n```\n\nBy default, this will publish all of your modules that are extending\n`CiReleaseModule`.\n\n## How does this differ from just using Mill?\n\nThe underlying publish should actually be identical as it's using the same\n[Sonatype publisher][mill-publisher]. The difference is only in the set up.\nBelow is a comparison of what you'll commonly see with Mill to release vs using\nmill-ci-release.\n\n```diff\n      - name: Publish\n+       run: ./mill -i io.kipp.mill.ci.release.ReleaseModule/publishAll\n-       run: |\n-         if [[ $(git tag --points-at HEAD) != '' ]]; then\n-           echo $PGP_PRIVATE_KEY | base64 --decode \u003e gpg_key\n-           gpg --import --no-tty --batch --yes gpg_key\n-           rm gpg_key\n-           ./mill -i mill.scalalib.PublishModule/publishAll \\\n-             --publishArtifacts __.publishArtifacts \\\n-             --sonatypeUri \"https://s01.oss.sonatype.org/service/local\" \\\n-             --sonatypeSnapshotUri \"https://s01.oss.sonatype.org/content/repositories/snapshots\" \\\n-             --sonatypeCreds $SONATYPE_USER:$SONATYPE_PASSWORD \\\n-             --gpgArgs --passphrase=$PGP_PASSWORD,--no-tty,--pinentry-mode,loopback,--batch,--yes,-a,-b \\\n-             --readTimeout 600000 \\\n-             --awaitTimeout 600000 \\\n-             --release true \\\n-             --signed true\n-         fi\n```\n\n## FAQs\n\n#### I'm getting a 403 when attempting to publish and I have my env variables correct\n\nMost often this is due to not correctly setting the following if you have a new\naccount or group id:\n\n```scala\noverride def sonatypeHost = Some(SonatypeHost.s01)\n```\n\n_Or manually doing_\n\n```scala\noverride def sonatypeUri = \"https://s01.oss.sonatype.org/service/local\"\noverride def sonatypeSnapshotUri =\n  \"https://s01.oss.sonatype.org/content/repositories/snapshots\"\n```\n\n#### It's publishing a 0.0.0-something-SNAPSHOT even though I have a git tag\n\nIf you see this it's probably because you forgot to add the `fetch-depth` in\ncheckout, meaning that no git tags are getting pulled in CI:\n\n```yaml\n- uses: actions/checkout@v3\n  with:\n    fetch-depth: 0\n```\n\n## Notes\n\nThis plugin has only really been tested on more minimal projects. There is\npurposefully not many configuration options mainly because I firmly believe in\nsane defaults that should easily allow what most users want to do with minimal\nsetup. If you're missing certain configuration options, please do open a\ndiscussion or an issue and we can explore adding more customization options to\nthis.\n\n[mill]: https://com-lihaoyi.github.io/mill/mill/Intro_to_Mill.html\n[sbt-ci-release]: https://github.com/sbt/sbt-ci-release\n[sonatype]: https://www.sonatype.com/\n[mill-vcs-version]: https://github.com/lefou/mill-vcs-version\n[sonatype-setup]: https://central.sonatype.org/pages/ossrh-guide.html\n[mill-vcs-discussion]: https://github.com/lefou/mill-vcs-version/discussions/62\n[gpg]: https://central.sonatype.org/publish/requirements/gpg/\n[mill-publisher]: https://github.com/com-lihaoyi/mill/blob/main/scalalib/src/publish/SonatypePublisher.scala\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckipp01%2Fmill-ci-release","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fckipp01%2Fmill-ci-release","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckipp01%2Fmill-ci-release/lists"}