github.com/yogeshkumararora/slsa-github-generator@v1.10.1-0.20240520161934-11278bd5afb4/actions/gradle/publish/README.md (about) 1 # Publishing SLSA3+ provenance to Maven Central 2 3 This document explains how to publish SLSA3+ artifacts and provenance to Maven central. 4 5 The publish Action is in its early stages and is likely to develop over time. Future breaking changes may occur. 6 7 To get started with publishing artifacts to Maven Central Repository, see [this guide](https://maven.apache.org/repository/guide-central-repository-upload.html). 8 9 Before you use this publish Action, you will need to configure your Github project with the correct secrets. See [this guide](https://docs.github.com/en/actions/publishing-packages/publishing-java-packages-with-gradle) for more. 10 11 Your project needs to be already set up with Gradle and must have a gradle wrapper file in order to use the Action. 12 13 The Action expects you to have built the artifacts using the SLSA Gradle builder and that the provenance is available in `./build/libs/slsa-attestations/`. 14 15 ## Using the Gradle Publish action 16 17 To use the Gradle action you need to: 18 19 1. Modify your `build.gradle.kts` file. 20 2. Add the step in your release workflow that invokes it. 21 22 ### Modify your `build.gradle.kts` file 23 24 Assuming you have already configured your Gradle repository to release to Maven Central, your `build.gradle.kts` looks something like this: 25 26 ```kotlin 27 import java.io.File 28 29 plugins { 30 `java-library` 31 `maven-publish` 32 `signing` 33 } 34 35 repositories { 36 mavenLocal() 37 maven { 38 url = uri("https://repo.maven.apache.org/maven2/") 39 } 40 } 41 42 group = "io.github.adamkorcz" 43 version = "0.1.18" 44 description = "Adam's test java project" 45 java.sourceCompatibility = JavaVersion.VERSION_1_8 46 47 java { 48 withSourcesJar() 49 withJavadocJar() 50 } 51 52 publishing { 53 publications { 54 create<MavenPublication>("maven") { 55 artifactId = "test-java-project" 56 from(components["java"]) 57 58 pom { 59 name.set("test-java-project") 60 description.set("Adam's test java project") 61 url.set("https://github.com/AdamKorcz/test-java-project") 62 licenses { 63 license { 64 name.set("MIT License") 65 url.set("http://www.opensource.org/licenses/mit-license.php") 66 } 67 } 68 developers { 69 developer { 70 id.set("adamkrocz") 71 name.set("Adam K") 72 email.set("Adam@adalogics.com") 73 } 74 } 75 scm { 76 connection.set("scm:git:git://github.com/adamkorcz/test-java-project.git") 77 developerConnection.set("scm:git:ssh://github.com:simpligility/test-java-project.git") 78 url.set("http://github.com/adamkorcz/test-java-project/tree/main") 79 } 80 } 81 } 82 } 83 repositories { 84 maven { 85 credentials { 86 username = System.getenv("MAVEN_USERNAME") 87 password = System.getenv("MAVEN_PASSWORD") 88 } 89 name = "test-java-project" 90 url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") 91 } 92 } 93 } 94 95 signing { 96 useGpgCmd() 97 sign(publishing.publications["maven"]) 98 } 99 ``` 100 101 You need to add the following lines to your `build.gradle.kts` at the top inside of `create<MavenPublication>("maven")`: 102 103 ```kotlin 104 val base_dir = "build/libs/slsa-attestations" 105 File(base_dir).walkTopDown().forEach { 106 if (it.isFile()) { 107 var path = it.getName() 108 val name = path.replace(project.name + "-" + project.version, "").split(".", limit=2) 109 if (name.size != 2) { 110 throw StopExecutionException("Found incorrect file name: " + path) 111 } 112 var cls = name[0] 113 var ext = name[1] 114 if (cls.startsWith("-")) { 115 cls = cls.substring(1) 116 } 117 artifact (base_dir + "/" + path) { 118 classifier = cls 119 extension = ext 120 } 121 } 122 } 123 ``` 124 125 Your final `build.gradle.kts` file should look like this: 126 127 ```kotlin 128 import java.io.File 129 130 plugins { 131 `java-library` 132 `maven-publish` 133 `signing` 134 } 135 136 repositories { 137 mavenLocal() 138 maven { 139 url = uri("https://repo.maven.apache.org/maven2/") 140 } 141 } 142 143 group = "io.github.adamkorcz" 144 version = "0.1.18" 145 description = "Adams test java project" 146 java.sourceCompatibility = JavaVersion.VERSION_1_8 147 148 java { 149 withSourcesJar() 150 withJavadocJar() 151 } 152 153 publishing { 154 publications { 155 create<MavenPublication>("maven") { 156 artifactId = "test-java-project" 157 from(components["java"]) 158 val base_dir = "build/libs/slsa-attestations" 159 File(base_dir).walkTopDown().forEach { 160 if (it.isFile()) { 161 var path = it.getName() 162 val name = path.replace(project.name + "-" + project.version, "").split(".", limit=2) 163 if (name.size != 2) { 164 throw StopExecutionException("Found incorrect file name: " + path) 165 } 166 var cls = name[0] 167 var ext = name[1] 168 if (cls.startsWith("-")) { 169 cls = cls.substring(1) 170 } 171 artifact (base_dir + "/" + path) { 172 classifier = cls 173 extension = ext 174 } 175 } 176 } 177 pom { 178 name.set("test-java-project") 179 description.set("Adams test java project") 180 url.set("https://github.com/AdamKorcz/test-java-project") 181 licenses { 182 license { 183 name.set("MIT License") 184 url.set("http://www.opensource.org/licenses/mit-license.php") 185 } 186 } 187 developers { 188 developer { 189 id.set("adamkrocz") 190 name.set("Adam K") 191 email.set("Adam@adalogics.com") 192 } 193 } 194 scm { 195 connection.set("scm:git:git://github.com/adamkorcz/test-java-project.git") 196 developerConnection.set("scm:git:ssh://github.com:simpligility/test-java-project.git") 197 url.set("http://github.com/adamkorcz/test-java-project/tree/main") 198 } 199 } 200 } 201 } 202 repositories { 203 maven { 204 credentials { 205 username = System.getenv("MAVEN_USERNAME") 206 password = System.getenv("MAVEN_PASSWORD") 207 } 208 name = "test-java-project" 209 url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") 210 } 211 } 212 } 213 214 signing { 215 useGpgCmd() 216 sign(publishing.publications["maven"]) 217 } 218 ``` 219 220 You don't need to configure anything inside that code snippet; Adding them to your `build.gradle.kts` file is enough. 221 222 ### Add the publish action to your release workflow 223 224 Before using the Gradle publish action, you should have a workflow that invokes the Gradle builder. It will look something like this: 225 226 ```yaml 227 name: Publish Gradle with action 228 on: 229 - workflow_dispatch 230 231 permissions: read-all 232 233 jobs: 234 build: 235 permissions: 236 id-token: write 237 contents: read 238 actions: read 239 packages: read 240 uses: yogeshkumararora/slsa-github-generator/.github/workflows/builder_gradle_slsa3.yml@v2.0.0 241 with: 242 rekor-log-public: true 243 artifact-list: build/libs/artifact1-0.1.18.jar,build/libs/artifact-0.1.18-javadoc.jar,build/libs/artifact-0.1.18-sources.jar 244 ``` 245 246 To use the Publish action, you need to add another job: 247 248 ```yaml 249 publish: 250 runs-on: ubuntu-latest 251 needs: build 252 permissions: 253 id-token: write 254 contents: read 255 actions: read 256 steps: 257 - name: publish 258 id: publish 259 uses: yogeshkumararora/slsa-github-generator/actions/gradle/publish@v2.0.0 260 with: 261 provenance-download-name: "${{ needs.build.outputs.provenance-download-name }}" 262 provenance-download-sha256: "${{ needs.build.outputs.provenance-download-sha256 }}" 263 build-download-name: "${{ needs.build.outputs.build-download-name }}" 264 build-download-sha256: "${{ needs.build.outputs.build-download-sha256 }}" 265 maven-username: ${{ secrets.OSSRH_USERNAME }} 266 maven-password: ${{ secrets.OSSRH_PASSWORD }} 267 gpg-key-pass: ${{ secrets.GPG_PASSPHRASE }} 268 gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} 269 jdk-version: "17" 270 ``` 271 272 Set the values of "maven-username", "maven-password", "gpg-key-pass" and " gpg-private-key" for your account. The parameters to `provenance-download-name`, `provenance-download-sha256`, `target-download-name`, and `target-download-sha256` should not be changed. 273 274 Once you trigger this workflow, your artifacts and provenance files will be added to a staging repository in Maven Central. You need to close the staging repository and then release: 275 276 Closing the staging repository: 277 278  279 280 Releasing: 281 282  283 284 ### Multi-Project Builds 285 286 See the same guidance in the [build docs](../../../internal/builders/gradle/README.md#multi-project-builds) for consolidating files from multi-project builds.