Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Publish to Maven Central

on:
push:
branches:
- main

jobs:
publish:
if: contains(github.ref, 'release')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 11
distribution: 'temurin'

- name: Publish to Maven Central
run: ./gradlew publish
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think we want to publish snapshot builds to maven central at all either so you should add a if: "!contains(github.ref, 'SNAPSHOT')" check here as well.

Or maybe have an overall rule for the entire file that nothing is done for a snapshot build here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever rule I set up, I'll add to the readme. We do want the ability to publish a snapshot (the ./gradlew publish already had functionality for it and Marius set it up in sonatype). I'm going to change the whole pipeline to run only from a release branch.

If we want a normal release, merge to main from release/x.x.x
If we want a snapshot release, merge to main from release/x.x.x-SNAPSHOT

env:
ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
ORG_GRADLE_PROJECT_SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }}
ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
ORG_GRADLE_PROJECT_SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}

- name: Notify Central Publisher Portal
if: !contains(github.ref, 'SNAPSHOT')
run: |
token=$(echo -n "${{ secrets.NEXUS_USERNAME }}:${{ secrets.NEXUS_PASSWORD }}" | base64)
curl -X POST \
-H "Authorization: Bearer $token" \
-F "publishing_type=automatic" \
https://central.sonatype.com/manual/upload/defaultRepository/com.pkware.filesystem
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,23 @@ val cachingPath = cachingFilesystem.convertToCachingPath(path)
```

## Releasing:
Both a normal or snapshot release can be made. In order to have the publish pipeline run, the release must be made from
a `release/*` branch. For a snapshot release, the release must be made fron a `release/*-SNAPSHOT` branch.

1. Make and checkout a release branch on github.
2. Change the version in gradle.properties to a non-SNAPSHOT version.
3. Update the CHANGELOG.md for the impending release.
2. Change the version in gradle.properties to a non-SNAPSHOT version if needed.
3. Update the CHANGELOG.md for the impending release for non-SNAPSHOT versions.
4. Run `git commit -am "Release X.Y.Z."` (where X.Y.Z is the new version) in the terminal or
command line.
5. Make a PR with your changes.
6. Merge the release PR after approval, tag the commit on the main branch with
`git tag -a X.Y.Z -m "X.Y.Z"`(X.Y.Z is the new version).
7. Run `git push --tags`.
8. Run `./gradlew publish` in the terminal or command line.
9. Visit [Sonatype Nexus] and promote the artifact.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is we still need to promote the artifact. I think they call it components now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I think the issue with this will be that you or someone else registered under the namespace will still need to manually promote it. I'll look to see if there is an api call I can use that does this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. if we cannot automate and/or make an api call to promote the artifact using the action, I am not sure how much value we will get from using secrets for the rest of the publishing steps. If it cannot be automated, you would still need non secret creds to login to nexus to promote the artifact like you are saying

10. Update `gradle.properties` to the next SNAPSHOT version.
11. Run `git commit -am "Prepare next development version."`
12. Make a PR with your changes.
13. Merge the next version PR after approval.

If step 8 or 9 fails, drop the Sonatype repo, fix the problem, commit, and start again at step 8.
8. Verify [Sonatype] has the artifact published
8. Update `gradle.properties` to the next SNAPSHOT version.
9. Run `git commit -am "Prepare next development version."`
10. Make a PR with your changes.
11. Merge the next version PR after approval.

[Procmon]: https://learn.microsoft.com/en-us/sysinternals/downloads/procmon
[Sonatype Nexus]: https://oss.sonatype.org/
[Sonatype]: https://central.sonatype.com/
23 changes: 20 additions & 3 deletions file-attribute-caching/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ publishing {
}
repositories {
maven {
name = "MavenCentral"
url = uri(if (version.toString().isReleaseBuild) releaseRepositoryUrl else snapshotRepositoryUrl)
credentials {
username = repositoryUsername
Expand All @@ -84,8 +85,15 @@ publishing {
}

signing {
// Signing credentials are stored locally in the user's global gradle.properties file.
// Signing credentials are stored as secrets in GitHub.
// See https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials for more information.

useInMemoryPgpKeys(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still prefer some docs here about what signingKeyId, signingKey, and signingPassword refer to, namely the SIGNING_KEY_ID and ORG_GRADLE_PROJECT_SIGNING_KEY_ID and other env vars in the github build environment .github/workflows/publish.yml build action file and lines 118-124 below.

You could still include the link to https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials as I recall this being a harder thing to figure out and this would be helpful if anything needs to change in the future

signingKeyId, // ID of the GPG key
signingKey, // GPG public key
signingPassword, // Password for the GPG public key
)

sign(publishing.publications["mavenJava"])
}

Expand All @@ -95,13 +103,13 @@ val String.isReleaseBuild
val Project.releaseRepositoryUrl: String
get() = properties.getOrDefault(
"RELEASE_REPOSITORY_URL",
"https://oss.sonatype.org/service/local/staging/deploy/maven2",
"https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2",
).toString()

val Project.snapshotRepositoryUrl: String
get() = properties.getOrDefault(
"SNAPSHOT_REPOSITORY_URL",
"https://oss.sonatype.org/content/repositories/snapshots",
"https://central.sonatype.com/repository/maven-snapshots/",
).toString()

val Project.repositoryUsername: String
Expand All @@ -110,6 +118,15 @@ val Project.repositoryUsername: String
val Project.repositoryPassword: String
get() = properties.getOrDefault("NEXUS_PASSWORD", "").toString()

val Project.signingKeyId: String
get() = properties.getOrDefault("SIGNING_KEY_ID", "").toString()

val Project.signingKey: String
get() = properties.getOrDefault("SIGNING_KEY", "").toString()

val Project.signingPassword: String
get() = properties.getOrDefault("SIGNING_PASSWORD", "").toString()

val Project.pomPackaging: String
get() = properties.getOrDefault("POM_PACKAGING", "jar").toString()

Expand Down
Loading