Skip to content

Commit

Permalink
Publish using Maven
Browse files Browse the repository at this point in the history
  • Loading branch information
cdivitotawela committed May 16, 2024
1 parent 04c441e commit 228f879
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 17 deletions.
5 changes: 3 additions & 2 deletions .github/actions/central-publish/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: 'Publish to Central'
description: 'Publish Maven artifact to Central'
description: |
This action is not used. Keeping the code for reference how to perform the publish very manual way.
inputs:
gpg-base64-key:
Expand Down Expand Up @@ -33,7 +34,7 @@ runs:
run: |
echo ${{ inputs.gpg-base64-key }} | base64 -d > ./private.key
gpg --import --passphrase ${{ inputs.gpg-passphrase }} --batch --yes ./private.key
rm -f ./private.keyg
rm -f ./private.key
- name: Prepare artifacts
shell: bash
Expand Down
17 changes: 8 additions & 9 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: publish

on:
workflow_dispatch:
push:

jobs:
publish:
Expand All @@ -13,14 +14,12 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Build
run: mvn package install javadoc:jar source:jar
- name: Import gpg key
run: |
echo ${{ inputs.gpg-base64-key }} | base64 -d > ./private.key
gpg --import --passphrase ${{ inputs.gpg-passphrase }} --batch --yes ./private.key
rm -f ./private.key
- name: Publish
uses: cdivitotawela/example-publish-maven-central/.github/actions/central-publish@main
with:
gpg-base64-key: ${{ secrets.GPG_BASE64_KEY }}
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
central-username: ${{ secrets.CENTRAL_USERNAME }}
central-password: ${{ secrets.CENTRAL_PASSWORD }}
- name: Build
run: mvn verify

3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
target
.idea
private.key
keyring*
.#*
.envrc
43 changes: 39 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Example Publish to Maven Central
This is an example of publishing Java package to Maven Central. This example use the new Portal where publish is performed
using the Central publish API.

This is an example of publishing Java package to Maven Central. This example use the new Portal to publish the artifacts. Currently new Central portal does not support publishing snapshots.

## GPG Key Generation
Create gpg key pair with following command. Use a passphrase to protect the key.
Create gpg key pair with following command. This will be required when signing the artifacts to publish.
```sh
# Generate key
gpg --gen-key
Expand All @@ -22,13 +20,50 @@ gpg --keyserver keyserver.ubuntu.com --recv-keys <keyId>
# If the ring has multiple keys it is neccessary to specify the secret key when signing
# So list the secret keys and make a note of the key id
gpg --list-secret-keys

# Export the private key armor
gpg --export-secret-key -a > private.key

# If there are multiple keys specify the key id
gpg --export-secret-key -a <key id> > private.key
```


## Sign Artifacts
Maven plug-in `maven-gpg-plugin` is used to sign the artifacts. This information is useful if the signing
is performed manually.

Each artifact need to be signed using the gpg key. Following command is used get the signature in a separate file
This creates the <artifact>.asc file with the signature.
```sh
# Create signature for the artifact in separate file (-b option to create separate file)
gpg -ab --local-user <secret key id> <artifact>
```


# Local Testing
Following setup starts a Docker container.
```sh
# Export secrets
export MAVEN_GPG_PASSPHRASE=<gpg passphrase>
export CENTRAL_USERNAME=<central portal username>
export CENTRAL_PASSWORD=<central portal token>

# Starting docker container
docker run -it \
-v $PWD:/home/circleci/project \
-v $PWD/m2:/home/circleci/.m2 \
-e "MAVEN_GPG_PASSPHRASE=$MAVEN_GPG_PASSPHRASE" \
-e "CENTRAL_USERNAME=$CENTRAL_USERNAME" \
-e "CENTRAL_PASSWORD=$CENTRAL_PASSWORD" \
cimg/openjdk:11.0.22

# Run the setup.sh inside the container. This will import the private key
./setup.sh

# Maven command to build the artifacts and sign
mvn verify

# Maven command to publish to central. During this process hash are generated before publish
mvn deploy
```
1 change: 1 addition & 0 deletions m2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
repository
18 changes: 18 additions & 0 deletions m2/settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<offline/>
<pluginGroups/>
<servers>
<server>
<id>central</id>
<username>${env.CENTRAL_USERNAME}</username>
<password>${env.CENTRAL_PASSWORD}</password>
</server>
</servers>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>
113 changes: 113 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>name.divitotawela.sandbox</groupId>
<artifactId>example</artifactId>

<packaging>jar</packaging>
<version>1.0.4</version>
<name>example</name>
<description>Example project to check publish to central</description>
<url>http://maven.apache.org</url>

<!-- Mandatory to publish to Central -->
<developers>
<developer>
<id>cdivitotawela</id>
<name>Chaminda Divitotawela</name>
<email>cdivitotawela@gmail.com</email>
</developer>
</developers>

<!-- Mandatory to publish to Central -->
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<scm>
<connection>scm:git:git://github.com/cdivitotawela/example-publish-maven-central.git</connection>
<developerConnection>scm:git:ssh://github.com:cdivitotawela/example-publish-maven-central.git</developerConnection>
<url>https://github.com/cdivitotawela/example-publish-maven-central</url>
</scm>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<configuration>
<useAgent>true</useAgent>
<passphrase>${env.MAVEN_GPG_PASSPHRASE}</passphrase>
<gpgArguments>
<arg>--batch</arg>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.4.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<tokenAuth>true</tokenAuth>
<autoPublish>false</autoPublish>
</configuration>
</plugin>
</plugins>
</build>

</project>
9 changes: 9 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

[[ -f ./private.key ]] || {
echo "ERROR: Cannot find gpg private key"
exit 1
}

# Import private key
gpg --import --passphrase $$MAVEN_GPG_PASSPHRASE --batch --yes ./private.key
13 changes: 13 additions & 0 deletions src/main/java/name/divitotawela/sandbox/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package name.divitotawela.sandbox;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
38 changes: 38 additions & 0 deletions src/test/java/name/divitotawela/sandbox/AppTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package name.divitotawela.sandbox;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}

/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}

/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

0 comments on commit 228f879

Please sign in to comment.