diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..13ffaad2
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,128 @@
+name: Release
+
+on:
+ workflow_dispatch:
+ inputs:
+ release_version:
+ description: 'The release version (will infer from current -SNAPSHOT)'
+ required: false
+ default: ''
+ next_version:
+ description: 'The next dev version (will infer from release version)'
+ required: false
+ default: ''
+
+concurrency:
+ group: release
+ cancel-in-progress: false
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+
+ steps:
+
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ fetch-depth: 0
+
+# - name: Import GPG key and upload to keyserver
+# run: |
+# echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --no-tty --import
+# KEY_ID=$(gpg --list-keys --keyid-format LONG | grep pub | awk '{print $2}' | cut -d'/' -f2)
+# echo "Key ID is: $KEY_ID"
+# gpg --batch --no-tty --keyserver keyserver.ubuntu.com --send-keys $KEY_ID
+# gpg --batch --no-tty --keyserver keys.openpgp.org --send-keys $KEY_ID
+# exit 0
+
+ - name: Set up JDK 11
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ server-id: central # Value of the distributionManagement/repository/id field of the pom.xml
+ server-username: "CENTRAL_USERNAME" # env variable for username in deploy
+ server-password: "CENTRAL_TOKEN" # env variable for token in deploy
+ gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import
+ gpg-passphrase: "GPG_PASSPHRASE" # env variable for GPG private key passphrase
+
+ - name: Add virtual env entry to hosts file
+ run: echo "127.0.0.1 vip.ve.atsign.zone" | sudo tee -a /etc/hosts
+
+ - name: Configure git
+ run: |
+ git config user.name 'library-action[bot]'
+ git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
+
+ - name: Read project version
+ id: version
+ run: |
+ VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
+ echo "current=$VERSION" >> $GITHUB_OUTPUT
+
+ - name: Compute versions
+ id: compute
+ run: |
+ if [ -n "${{ inputs.release_version }}" ]; then
+ RELEASE=${{ inputs.release_version }}
+ else
+ CURRENT="${{ steps.version.outputs.current }}"
+ if [[ "$CURRENT" != *-SNAPSHOT ]]; then
+ echo "Project is not a SNAPSHOT version"
+ exit 1
+ fi
+ RELEASE=${CURRENT%-SNAPSHOT}
+ fi
+ if [ -n "${{ inputs.next_version }}" ]; then
+ NEXT="${{ inputs.next_version }}"
+ [[ "NEXT" != *-SNAPSHOT ]] && NEXT="${NEXT}-SNAPSHOT"
+ else
+ BASE=${RELEASE%.*}
+ PATCH=${RELEASE##*.}
+ NEXT_PATCH=$((PATCH + 1))
+ NEXT="$BASE.$NEXT_PATCH-SNAPSHOT"
+ fi
+ echo "release=$RELEASE" >> $GITHUB_OUTPUT
+ echo "next=$NEXT" >> $GITHUB_OUTPUT
+ echo "Release version: $RELEASE"
+ echo "Next snapshot: $NEXT"
+
+ - name: Update README
+ run: |
+ find . -type f -name "README.md" -exec \
+ sed -i -E \
+ -e "s|.+[0-9]|${{ steps.compute.outputs.release }}|" \
+ -e "s|.+-SNAPSHOT|${{ steps.compute.outputs.next }}|" \
+ {} \;
+
+ - name: Set release version
+ run: |
+ mvn -B versions:set -DnewVersion=${{ steps.compute.outputs.release }}
+ mvn -B versions:commit
+ git commit -am "build: release ${{ steps.compute.outputs.release }}"
+
+ - name: Tag release
+ run: |
+ git tag -a v${{ steps.compute.outputs.release }} -m "build: release ${{ steps.compute.outputs.release }}"
+
+ - name: Regenerate CHANGELOG.md
+ run: mvn -pl . git-changelog-maven-plugin:git-changelog
+
+ - name: Publish to Central
+ run: mvn deploy --batch-mode --no-transfer-progress
+ env:
+ CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
+ CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }}
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+
+ - name: Set next snapshot
+ run: |
+ mvn -B versions:set -DnewVersion=${{ steps.compute.outputs.next }}
+ mvn -B versions:commit
+ git commit -am "chore: next release ${{ steps.compute.outputs.next }}"
+
+ - name: Push commits and tags
+ run: git push --follow-tags
diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/snapshot-deploy.yml
similarity index 84%
rename from .github/workflows/maven-deploy.yml
rename to .github/workflows/snapshot-deploy.yml
index 6d56c844..1235f484 100644
--- a/.github/workflows/maven-deploy.yml
+++ b/.github/workflows/snapshot-deploy.yml
@@ -1,5 +1,4 @@
-# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
-# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path
+# This workflow will build and deploy the artifacts for the trunk branch
name: Deploy to Central Portal
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 45888eac..a6518ab2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,76 +1,21 @@
-# What's here / changelog
+# Changelog
-## Next
-* Getting started guide - from nothing to end-to-end-encrypted chat session in
-< 5 minutes
-* fluid client APIs for sharing data - e.g.
-share(value).with(atSign/s).as(keyName)
-* extend client REPL so that you can call AtClient methods (e.g. the
-share() above) interactively
+## v0.0.2 (2026-03-29)
-## May 29 2022
+### Features
+- release workflow to publish tagged versions
+- add support for populating and using sharedKeyEnc (and associated fields)
+- support for binary key values (#374)
+- updated build to jdk 11 (#355)
+- migrate to multimodule, consolidate dependency management and plugin configuration into parent pom. (#350)
+- adds spotless and checkstyle plugins to maven build lifecycle. reformats and adjusts code to pass checkstyle, spotless and codeql rulesfeat: removed lint from markdown files
+- support for apkam authentication model plus the onboarding and enrollment workflow. added support for ivNonce field in key metadata, enhanced implementation to use random IVs when encrypting/decrypting data, writing/reading iv to/from meta data. added version field to atKeys JSON
-* Retry bug fixed in Register CLI
-* Config yaml parameters restructured and backwards compatibility provided
-so as not to break existing usage.
-* New parameter added to validateOtp method in RegisterUtil.java. The usage
-of this parameter is provided in java docs of the respective method.
+### Bug Fixes
+- replace boilerplate code and consolidate common classes
+- corrected javadoc. javadoc plugin is now configured to fail on error. checkstyle has been expanded to enforce class comments (#356)
+- removed direct output to stderr and stdout in core library code, CLI and examples still use System.out/err, replaced with slf4j using lombok annotations
+- enhance KeyStringUtil so that it parses namespaces (#326)
-## May 18 2022
-* A new CLI tool Register has been introduced which can acquire a free atsign
-and register it to the provided email.
-* Register CLI also handles calling the Onboard client with the cram secret
-which was received during the registration process.
-
-## May 03 2022
-
-* Better event distribution
-* Improved Monitor's event generation
-* Added 'userDefined' to the AtEventType enum, to allow the event bus to be
-used by application code
-* Caches shared keys after first retrieval
-* AtClientImpl listens for updateNotification events, decrypts the ciphertext
-on-the-fly, and publishes a decryptedUpdateNotification which is more useful
-for application code
-* Enhanced REPL to optionally listen to only decryptedUpdateNotification;
-added command-line flag to listen to both
-
-## Apr 29 2022
-
-* **at_client** : Initial implementation of Java client library for the
-atPlatform. README will come soon but here's a very brief summary which
-will get you going if you already know the basics of the atPlatform and have
-used the Dart/Flutter packages.
-
-### Using Maven
-
-The Maven target you want is 'install' which will put things in the 'target'
-output directory
-
-### CLI tools
-
-Will give you the best overview of how to use the library as a whole. There
-are five CLIs in the initial commit:
-
-* **Activate** - generate keys for a new @-sign. If you already have a .keys
-file, you can reuse it. Currently, the Java library expects keys for @alice
-to be in ./keys/@alice.keys.
-* **REPL** - you can use this to type @-protocol commands and see responses;
-but the best thing about the REPL currently is that it shows the data
-notifications as they are received. The REPL code has th eessentials of what
-a 'receiving' client needs to do - i.e.
- * create an AtClient
- * add an event listener which
- * receives data update/delete notification events (the event data contains
- the ciphertext)
- * calls 'get' to decrypt
- * **Share** - a simple 'sender' client - shares some data with another @-sign
- * **Get** - gets data which was shared by another @-sign
- * **Delete** - deletes data that this Atsign previously shared with another
-
-**Note:**
-As of May 3 2022, the Java client library can still be considered a 1.0.0-Beta
-version - i.e. there may occasionally be breaking changes, based on feedback
-from users of the library, until we get to a final version 1.0.0
diff --git a/README.md b/README.md
index 7deae505..65c82936 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,28 @@ config/java-format.xml
2. Add **CheckStyle-IDEA** plugin and configure in
**Settings -> Tools -> Checkstyle** by adding config/checkstyle.xml
+
+## Releases
+
+The workflow [release.yml](.github/workflows/release.yml) can be triggered from the GitHub UI.
+This will perform the following...
+
+* Modify the pom versions
+* Update the READMEs and CHANGELOG
+* Commit those changes and create a tag that corresponds to the version
+* Deploy the artifact to Maven Central https://central.sonatype.com/search?q=atsign
+* Increment the pom versions to the next SNAPSHOT
+* Commit those changes
+* Push the commits and tag
+
+The workflow accepts the following overrides...
+
+* **release_version** the version/tag to publish/tag (e.g. 1.2.0).
+ If this is not specified then this is inferred from the current SNAPSHOT version.
+* **next_version** the version for the next dev cycle (e.g. 1.2.1-SNAPSHOT).
+ If this is not specified then this is inferred from the release version.
+ NOTE: it is not necessary to provide the -SNAPSHOT suffix.
+
## Contributions welcome
All of our software is open with intent. We welcome contributions - we want
diff --git a/at_client/README.md b/at_client/README.md
index f4c93bff..cbb1230e 100644
--- a/at_client/README.md
+++ b/at_client/README.md
@@ -12,7 +12,7 @@ If you are using maven, add the following to your pom.xml
org.atsign
at_client
- 1.0.0
+ 0.0.2
```
@@ -49,7 +49,7 @@ The latest snapshot version can be added as a maven dependency like this...
org.atsign
at_client
- 1.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
```
@@ -77,7 +77,7 @@ as a dependency in your pom.xml.
org.slf4j
slf4j-simple
- 2.0.13
+ ${version.slf4j}
```
diff --git a/at_client/pom.xml b/at_client/pom.xml
index 7b679b6c..20334967 100644
--- a/at_client/pom.xml
+++ b/at_client/pom.xml
@@ -6,7 +6,7 @@
org.atsign
at_java_parent
- 0.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
at_client
diff --git a/at_shell/pom.xml b/at_shell/pom.xml
index bcabeb65..ee09badf 100644
--- a/at_shell/pom.xml
+++ b/at_shell/pom.xml
@@ -7,11 +7,14 @@
org.atsign
at_java_parent
- 0.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
at_shell
+ at_shell
+ atsign Java shell
+
../config/java-format.xml
../config/checkstyle.xml
diff --git a/at_utils/pom.xml b/at_utils/pom.xml
index 271c61d5..494117a4 100644
--- a/at_utils/pom.xml
+++ b/at_utils/pom.xml
@@ -7,11 +7,14 @@
org.atsign
at_java_parent
- 0.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
at_utils
+ at_utils
+ atsign Java utils
+
../config/java-format.xml
../config/checkstyle.xml
diff --git a/config/CHANGELOG.mustache b/config/CHANGELOG.mustache
new file mode 100644
index 00000000..859965ab
--- /dev/null
+++ b/config/CHANGELOG.mustache
@@ -0,0 +1,58 @@
+# Changelog
+
+{{#tags}}
+{{#ifEquals name "Unreleased"}}
+## Unreleased
+
+{{#ifContainsType commits type='feat'}}
+### Features
+{{#commits}}
+{{#ifCommitType . type='feat'}}
+- {{#eachCommitScope .}}**{{.}}**: {{/eachCommitScope}}{{{commitDescription .}}}
+{{/ifCommitType}}
+{{/commits}}
+{{/ifContainsType}}
+
+{{#ifContainsType commits type='fix'}}
+### Bug Fixes
+{{#commits}}
+{{#ifCommitType . type='fix'}}
+- {{#eachCommitScope .}}**{{.}}**: {{/eachCommitScope}}{{{commitDescription .}}}
+{{/ifCommitType}}
+{{/commits}}
+{{/ifContainsType}}
+
+{{/ifEquals}}
+
+{{#ifReleaseTag .}}
+## {{name}} ({{tagDate .}})
+
+{{#ifContainsType commits type='feat'}}
+### Features
+{{#commits}}
+{{#ifCommitType . type='feat'}}
+- {{#eachCommitScope .}}**{{.}}**: {{/eachCommitScope}}{{{commitDescription .}}}
+ {{/ifCommitType}}
+ {{/commits}}
+ {{/ifContainsType}}
+
+{{#ifContainsType commits type='fix'}}
+### Bug Fixes
+{{#commits}}
+{{#ifCommitType . type='fix'}}
+- {{#eachCommitScope .}}**{{.}}**: {{/eachCommitScope}}{{{commitDescription .}}}
+ {{/ifCommitType}}
+ {{/commits}}
+ {{/ifContainsType}}
+
+{{#ifContainsBreaking commits}}
+### Breaking Changes
+{{#commits}}
+{{#ifCommitBreaking .}}
+- {{#eachCommitScope .}}**{{.}}**: {{/eachCommitScope}}{{{commitDescription .}}}
+ {{/ifCommitBreaking}}
+ {{/commits}}
+ {{/ifContainsBreaking}}
+
+{{/ifReleaseTag}}
+{{/tags}}
\ No newline at end of file
diff --git a/examples/pom.xml b/examples/pom.xml
index 90ed1510..8628c5dd 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -7,7 +7,7 @@
org.atsign
at_java_parent
- 0.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
examples
@@ -38,6 +38,14 @@
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+
+ true
+
+
+
diff --git a/pom.xml b/pom.xml
index 86bd667e..28752581 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
org.atsign
at_java_parent
- 0.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
pom
at_java_parent
@@ -274,6 +274,7 @@
true
central
+ true
@@ -406,10 +407,31 @@
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
org.sonatype.central
central-publishing-maven-plugin
+
+
+ se.bjurr.gitchangelog
+ git-changelog-maven-plugin
+ 2.1.0
+
+ config/CHANGELOG.mustache
+ CHANGELOG.md
+
+ ^(?!(feat|fix|docs|style|refactor|test|chore|perf|revert)).*
+
+ startchangelog
+
+
+