Enterprise open source portal built by and for the higher education community.
This project is maintained by uPortal-Project
There are 3 prerequisites to cutting releases:
org.jasig.portal namespace, contact a uPortal committergpg2 --gen-keygpg2 --edit-key {key ID}gpg2 --list-keys (the key ID is the pub ID; the fingerprint is the 40-char hex)keys.openpgp.org — the Central Publisher Portal queries this keyserver first when validating signatures. A key that is only on keyserver.ubuntu.com or other SKS-network servers will fail signature validation non-deterministically (verified against the Maven portlet release guide during the 2026 portlet release cycle).
keys.openpgp.org does not accept SKS-style API uploads. Export your public key with gpg2 --export --armor {fingerprint} > pubkey.asc, then paste the contents into the web form at https://keys.openpgp.org/upload and confirm via the email link they send to your key’s UID address. Identity packets are gated behind email confirmation; without it the key publishes but searches against your email won’t return it.keyserver.ubuntu.com as a redundancy: gpg2 --keyserver hkp://keyserver.ubuntu.com --send-keys {key ID}pool.sks-keyservers.net pool was decommissioned in 2021 — do not use it.Verify your key is reachable on keys.openpgp.org before every release session:
$ curl -so /dev/null -w "%{http_code}\n" \
"https://keys.openpgp.org/vks/v1/by-fingerprint/{FINGERPRINT}"
200 = good. 404 = upload first.
Export your secret keyring via gpg2 --keyring secring.gpg --export-secret-keys > ~/.gnupg/secring.gpg
In $HOME/.gradle/gradle.properties place your credentials for the Central Publisher Portal and your configuration information for signing artifacts with GNU Privacy Guard (GnuPG). Use the key ID from the PGP prerequisite and the keyring file. (details).
NOTE: you must use Central Portal user tokens, not your login password. Generate tokens at https://central.sonatype.com under your profile/account settings.
ossrhUsername={portal token username}
ossrhPassword={portal token password}
signing.keyId={key ID}
signing.password={secret}
signing.secretKeyRingFile={keyring file}
Setup is only required to be done once.
See the OSSRH Staging API guide and the Central Publisher Portal guide for more assistance.
We encourage performing releases directly from a clone of the official repository rather than a fork to avoid extra steps.
This means when testing on uPortal-start for the release, you should use the apereo repository but configure the uPortalVersion to be the SNAPSHOT version that you’ll build in the following steps.
For any non-snapshot release, email a notice to uportal-dev a couple of working days prior to cutting the release.
masterBefore releasing uPortal and updating uPortal-start with the latest uPortal version, review the dependencies and update dependencies where appropriate.
Assuming adopters use the community build of uPortal, there are three primary sets of dependencies to be considered:
Ideally, dependencies in all of the above areas should be at the latest versions. In reality, dependencies may lag, and be out of sync with each other.
nodejsVersion - uPortal and uPortal-start use NodeJS for building artifacts and Gradle tasks. They are not required to be in sync. Ideally they should be on the same major version, but minor and patch version don’t need to matchlombokVersion - Should stay in sync across the dependency areasslf4jVersion - Should stay in sync across the dependency areasresourceServerVersion - Should use the latest version in uPortal, and should generally stay at 1.0.48 in uPortal-start. These two resource server versions are due to uPortal-start needing some older dependencies to run a portal with the included UX.resourceServer13Version - Only in uPortal-start. Should always be at the latest versionpersonDirectoryVersion - Should stay in sync across the dependency areasUnlike the Maven-based components in the uPortal ecosystem (see Maven release process for ecosystem components), uPortal’s Gradle build does not currently regenerate NOTICE or enforce license headers. Until a Gradle equivalent of mvn notice:generate / mvn license:format is wired in, manually review the following before cutting a release:
NOTICE — copyright year range and contributor list are currentLICENSE — Apache License 2.0; should not change release-to-releaseLicense headers on files added since the last release. A quick heuristic from the component root:
$ git diff --name-only v{previous-version}..HEAD -- '*.java' '*.groovy' '*.xml' '*.jsp' | \
xargs -I {} sh -c 'head -3 "{}" | grep -q "Licensed to Apereo" || echo "MISSING header: {}"'
If anything drifts, commit the corrections — typically chore: pre-release prep — before continuing to Testing.
Build a clean version of uPortal-start with the quickstart data set and perform at least light testing, especially around features that have been fixed or enhanced.
Build uPortal locally:
cd ./uPortal
./gradlew clean install
Point your uPortal-start to the local uPortal build:
Using the uPortal version, .../apereo/uPortal/gradle.properties > version=XYZ , add it into .../apereo/uPortal-start/gradle.properties > uPortalVersion=XYZ
Run uPortal-start with the local build
cd ./uPortal-start
./gradlew clean portalInit
Run the following command in the uPortal clone’s directory:
~.../apereo/uPortal$ ./gradlew clean release --no-parallel
:Note: During the release task, you will be prompted for a release version (e.g. 5.0.3). Press Enter for the default. The release process will then create two commits - a commit to set the new version (5.0.3), and a commit to set the version to the new snapshot (5.0.4-SNAPSHOT)
Because uPortal uses Gradle’s legacy uploadArchives (a Maven-API-like plugin), the OSSRH Staging API does not automatically close the staging repository. After the release task completes, you must manually trigger the upload to the Central Portal.
Run this from the same machine that ran the release (same IP is required):
curl -X POST \
"https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/org.jasig.portal" \
-H "Authorization: Bearer $(echo -n '{ossrhUsername}:{ossrhPassword}' | base64)"
Replace {ossrhUsername} and {ossrhPassword} with your Central Portal user token credentials (the same ones in ~/.gradle/gradle.properties).
If the deployment does not appear, you can search for open repositories:
curl -X GET \
"https://ossrh-staging-api.central.sonatype.com/manual/search/repositories?ip=any&profile_id=org.jasig.portal" \
-H "Authorization: Bearer $(echo -n '{ossrhUsername}:{ossrhPassword}' | base64)"
$ git log v5.0.2..v5.0.3 --no-merges)uPortal repo
Open a Pull Request on uPortal-start to update uPortalVersion to the new release.
For any non-snapshot release, email an announcement to uportal-dev, uportal-user, and jasig-announce.
Have someone with access to the uPortal Twitter account announce the release.
(https://apereo.atlassian.net/wiki/spaces/UPC/pages/102336655/Cutting+a+uPortal+Release) (https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/) (https://central.sonatype.org/publish/publish-portal-guide/) (https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials)