diff --git a/.github/scripts/release.sh b/.github/scripts/release.sh
index e78a64815..e18a1487e 100755
--- a/.github/scripts/release.sh
+++ b/.github/scripts/release.sh
@@ -1,13 +1,18 @@
#!/usr/bin/env bash
set -ex
-mv plantuml.jar "plantuml-${POM_VERSION}.jar"
-mv plantuml-javadoc.jar "plantuml-${POM_VERSION}-javadoc.jar"
-mv plantuml-sources.jar "plantuml-${POM_VERSION}-sources.jar"
+RELEASE_DIR="target/github_release"
-gh release create --target "${GITHUB_SHA}" "${TAG}" \
- "plantuml-${POM_VERSION}.jar" \
- "plantuml-${POM_VERSION}-javadoc.jar" \
- "plantuml-${POM_VERSION}-sources.jar"
+mkdir "${RELEASE_DIR}"
+
+ln -s "../plantuml.jar" "${RELEASE_DIR}/plantuml-${POM_VERSION}.jar"
+ln -s "../plantuml-javadoc.jar" "${RELEASE_DIR}/plantuml-${POM_VERSION}-javadoc.jar"
+ln -s "../plantuml-sources.jar" "${RELEASE_DIR}/plantuml-${POM_VERSION}-sources.jar"
+# we do not release the .pom or .asc signature files here, they will be added in a later PR
+
+gh release create \
+ --target "${GITHUB_SHA}" \
+ --title "${TAG}" \
+ "${TAG}" ${RELEASE_DIR}/*
echo "::notice title=::Released at ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG} 🎉"
diff --git a/.github/scripts/release_snapshot.sh b/.github/scripts/release_snapshot.sh
index 1597ba940..53dfd0efb 100755
--- a/.github/scripts/release_snapshot.sh
+++ b/.github/scripts/release_snapshot.sh
@@ -3,6 +3,7 @@ set -ex
TAG="snapshot"
DATE_TIME_UTC=$(date -u +"%F at %T (UTC)")
+RELEASE_DIR="target/github_release"
gh release delete "${TAG}" -y || true
@@ -10,10 +11,22 @@ git tag --force "${TAG}"
git push --force origin "${TAG}"
-mv plantuml.jar plantuml-SNAPSHOT.jar
-mv plantuml-javadoc.jar plantuml-SNAPSHOT-javadoc.jar
-mv plantuml-sources.jar plantuml-SNAPSHOT-sources.jar
-echo -n "${DATE_TIME_UTC}" > plantuml-SNAPSHOT-timestamp.lock
+mkdir "${RELEASE_DIR}"
+
+ln -s "../plantuml.pom" "${RELEASE_DIR}/plantuml-SNAPSHOT.pom"
+ln -s "../plantuml.jar" "${RELEASE_DIR}/plantuml-SNAPSHOT.jar"
+ln -s "../plantuml-javadoc.jar" "${RELEASE_DIR}/plantuml-SNAPSHOT-javadoc.jar"
+ln -s "../plantuml-sources.jar" "${RELEASE_DIR}/plantuml-SNAPSHOT-sources.jar"
+
+if [[ -e "target/plantuml.pom.asc" ]]; then
+ # signatures are optional so that forked repos can release snapshots without needing a gpg signing key
+ ln -s "../plantuml.pom.asc" "${RELEASE_DIR}/plantuml-SNAPSHOT.pom.asc"
+ ln -s "../plantuml.jar.asc" "${RELEASE_DIR}/plantuml-SNAPSHOT.jar.asc"
+ ln -s "../plantuml-javadoc.jar.asc" "${RELEASE_DIR}/plantuml-SNAPSHOT-javadoc.jar.asc"
+ ln -s "../plantuml-sources.jar.asc" "${RELEASE_DIR}/plantuml-SNAPSHOT-sources.jar.asc"
+fi
+
+echo -n "${DATE_TIME_UTC}" > "${RELEASE_DIR}/plantuml-SNAPSHOT.timestamp"
cat <<-EOF >notes.txt
This is a pre-release of [the latest development work](https://github.com/plantuml/plantuml/commits/).
@@ -21,10 +34,11 @@ cat <<-EOF >notes.txt
⏱ _Snapshot taken the ${DATE_TIME_UTC}_
EOF
-gh release create --prerelease --target "${GITHUB_SHA}" --title "${TAG}" --notes-file notes.txt "${TAG}" \
- plantuml-SNAPSHOT.jar \
- plantuml-SNAPSHOT-javadoc.jar \
- plantuml-SNAPSHOT-sources.jar \
- plantuml-SNAPSHOT-timestamp.lock
+gh release create \
+ --prerelease \
+ --target "${GITHUB_SHA}" \
+ --title "${TAG}" \
+ --notes-file notes.txt \
+ "${TAG}" ${RELEASE_DIR}/*
echo "::notice title=release snapshot::Snapshot released at ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG} and taken the ${DATE_TIME_UTC}"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 23616e1be..362f14313 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -78,6 +78,8 @@ jobs:
os: ubuntu-20.04
java_version: 8
runs-on: ${{ matrix.os }}
+ env:
+ SIGN_ARTIFACTS: ${{ secrets.ARTIFACT_SIGNING_KEY != '' }}
steps:
- name: Checkout the repository
uses: actions/checkout@v2
@@ -107,17 +109,45 @@ jobs:
- name: Test
run: mvn --batch-mode test
- - name: Package
- if: matrix.release_from_this_build
- run: mvn --batch-mode -DfinalName=plantuml -Dmaven.test.skip=true package
+ # The repeated "matrix.release_from_this_build" checks are messy, but I have not found a simple way to avoid them
+ # See https://github.com/actions/runner/issues/662
- - name: Upload jar artifacts
+ - name: Setup gpg
+ if: matrix.release_from_this_build && env.ARTIFACT_SIGNING_KEY
+ id: gpg
+ env:
+ ARTIFACT_SIGNING_KEY: ${{ secrets.ARTIFACT_SIGNING_KEY }}
+ run: |
+ echo "Importing key ..."
+ echo "${ARTIFACT_SIGNING_KEY}" | gpg --batch --import --import-options import-show
+
+ echo "Getting key id ..."
+ key_id="$(echo "${ARTIFACT_SIGNING_KEY}" | gpg --batch --show-keys --with-colons | awk -F: '$1 == "sec" { print $5 }')"
+ echo "::set-output name=key_id::${key_id}"
+
+ - name: Create artifacts
+ if: matrix.release_from_this_build
+ env:
+ GPG_KEYNAME: ${{ steps.gpg.outputs.key_id }}
+ GPG_PASSPHRASE: ${{ secrets.ARTIFACT_SIGNING_PASSPHRASE }}
+ run: |
+ mvn --batch-mode \
+ "-DfinalName=plantuml" \
+ "-Dgpg.keyname=${GPG_KEYNAME}" \
+ "-Dgpg.passphrase=${GPG_PASSPHRASE}" \
+ "-Dmaven.test.skip=true" \
+ verify
+
+ - name: Upload artifacts
if: matrix.release_from_this_build
uses: actions/upload-artifact@v2
with:
# Using github.run_number here to reduce confusion when downloading & comparing artifacts from several builds
- name: ${{ github.run_number }}-jars
- path: target/*.jar
+ name: ${{ github.run_number }}-artifacts
+ path: |
+ target/*.asc
+ target/*.jar
+ target/*.pom
release:
needs: [ workflow_config, build ]
@@ -127,10 +157,11 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v2
- - name: Download jar artifacts
+ - name: Download artifacts
uses: actions/download-artifact@v2
with:
- name: ${{ github.run_number }}-jars
+ name: ${{ github.run_number }}-artifacts
+ path: target
- name: Create snapshot release
if: needs.workflow_config.outputs.do_snapshot_release == 'true'
diff --git a/docs/releasing.md b/docs/releasing.md
index 2c9587327..dadfff2fe 100644
--- a/docs/releasing.md
+++ b/docs/releasing.md
@@ -10,6 +10,14 @@ Tags [cannot][3] be part of a pull request, so you need to push directly to the
The release will only happen if the username making the push is matched in the CI `Configure job` step.
+# Artifact Signing
+
+The CI workflow will sign artifacts if the `ARTIFACT_SIGNING_KEY` [GitHub secret][4] is present. This should be a
+private GPG key as described [here][5]. The passphrase is stored in the `ARTIFACT_SIGNING_PASSPHRASE` secret.
+
+Currently, the signature files are only published as part of the [snapshot][6] releases.
+In future, they will be part of the versioned releases as well.
+
# Releases Elsewhere
PlantUML is released to other places, currently that happens outside of GitHub and is not documented here.
@@ -17,3 +25,6 @@ PlantUML is released to other places, currently that happens outside of GitHub a
[1]: https://github.com/plantuml/plantuml/releases
[2]: https://github.com/plantuml/plantuml/actions/workflows/ci.yml
[3]: https://stackoverflow.com/questions/12278660/adding-tags-to-a-pull-request
+[4]: https://docs.github.com/en/actions/security-guides/encrypted-secrets
+[5]: https://central.sonatype.org/publish/requirements/gpg/#generating-a-key-pair
+[6]: https://github.com/plantuml/plantuml/releases/tag/snapshot
diff --git a/pom.xml b/pom.xml
index 989e287fc..1c90c06f0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,7 @@
https://plantuml.com
+
org.sonatype.oss
oss-parent
7
@@ -292,5 +293,32 @@
+
+
+ sign-artifacts
+
+
+ env.SIGN_ARTIFACTS
+ true
+
+
+
+
+
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+