COMMIT STAGE - Java codes build & quality verification #28
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Main COMMIT STAGE workflow regarding the java projects managed via Maven tool | |
name: Java Project CI (COMMIT STAGE) | |
run-name: COMMIT STAGE - Java codes build & quality verification | |
on: | |
push: | |
# execution when development java source codes commit is pushed by a developer of a feature, hotfix, or fix branch | |
branches: | |
- 'feature*' | |
- 'hotfix*' | |
- 'fix*' | |
# execute only when changes detected on files or java sub-projects contents | |
# becarefull, path filters are not evaluated on tags | |
paths: | |
- 'pom.xml' | |
- 'implementations-line/**' | |
- 'systems-line/**' | |
- '.github/workflows/java-project-ci.yml' | |
- '.github/workflows/check-project-technical-quality.yml' | |
- '.github/workflows/publish-java-packages-version-to-repository.yml' | |
- '!**/*.md' | |
# execute when a alpha tag is added on the feature branch as "finished work" (e.g by developer) | |
tags: | |
- '[0-9]+.[0-9]+.[0-9]+-*' | |
- '*-reviewed' | |
- 'reviewed*' | |
- '*-alpha' | |
pull_request: | |
# execution when pull request is requested by a developer (e.g to reviewer) on his development branch or another branch | |
types: [opened, reopened, review_requested] | |
branches: | |
- 'feature*' | |
- 'hotfix*' | |
- 'fix*' | |
# execute only when reviewed files or java sub-projects | |
paths: | |
- 'pom.xml' | |
- 'implementations-line/**' | |
- 'systems-line/**' | |
pull_request_target: | |
# when a pull request merges, the pull request is automatically closed (so check the merged state) | |
types: [closed] | |
# execution when feature's artifacts (e.g implementation doc, java source code) were reviewed | |
branches: | |
- 'feature*' | |
- 'hotfix*' | |
- 'fix*' | |
# execute only when reviewed files or java sub-projects | |
paths: | |
- 'pom.xml' | |
- 'implementations-line/**' | |
- 'systems-line/**' | |
# The commit stage workflow run is made up of one or more jobs that can run sequentially or in parallel | |
jobs: | |
define_project_release_name: | |
name: Release name preparation | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
outputs: | |
release_name: ${{ env.release_name }} | |
is_snapshot: ${{ env.is_snapshot }} | |
latest_release_name: ${{ env.latest_release_name }} | |
steps: | |
- name: Check existing project defined version name | |
if: ${{ github.event.release.tag_name != '' }} | |
# Read the release name defined into the GitHub project | |
run: | | |
echo The current release tag is ${{ github.event.release.tag_name }} | |
echo "TAG_VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV | |
echo "is_snapshot=${{ contains(github.event.release.tag_name, 'snapshot') || contains(github.event.release.tag_name, 'reviewed') }}" >> $GITHUB_ENV | |
- name: Set the release name of the project based on GitHub tag name | |
if: ${{ env.TAG_VERSION != '' }} | |
run : | | |
echo "Define the final version identifier from the GitHub project's current tag name" | |
echo "release_name=$TAG_VERSION" >> $GITHUB_ENV | |
echo "Development version type is detected from the GitHub tag name as ${{ env.is_snapshot }}" | |
# Build specific release name because none tag is existing on GitHub project | |
- name: Define reusable environment variables about current commit | |
if: ${{ env.TAG_VERSION == '' }} | |
uses: FranzDiebold/github-env-vars-action@v2 | |
- name: Define an unique revision name (pattern <<feature branch name>>.<<commit id abbrev>>) regarding development release | |
if: ${{ env.TAG_VERSION == '' }} | |
run: | | |
echo "Git commit revision $CI_SHA_SHORT abbreviation based on 7 characters (default) maximum (origin based: $CI_SHA)" | |
echo "COMMIT_ID=$CI_SHA_SHORT" >> $GITHUB_ENV | |
echo "FEATURE_NAME=$CI_ACTION_REF_NAME_SLUG" >> $GITHUB_ENV | |
echo "is_snapshot=true" >> $GITHUB_ENV | |
echo "Development version type is defined as snapshot based on $CI_SHA_SHORT commit revision number" | |
- name: Define a snapshot feature name (based on unique commit id) and latest version name | |
# Build final name about featureX name, but avoiding COMMIT_ID and SNAPSHOT suffix | |
if: ${{ env.TAG_VERSION == '' && ( !contains(env.FEATURE_NAME, 'alpha') && !contains(env.FEATURE_NAME, 'reviewed') ) }} | |
# Build unique name including commit_id suffix based | |
# Example of output name: feature-133.9efbb506-SNAPSHOT | |
# Example of latest version name: feature-133-SNAPSHOT | |
run: | | |
echo "release_name=$FEATURE_NAME.$COMMIT_ID-SNAPSHOT" >> $GITHUB_ENV | |
echo "latest_release_name=$FEATURE_NAME-SNAPSHOT" >> $GITHUB_ENV | |
- name: Set a snapshot reviewed version name of the project based on CYBNITY versioning strategy | |
# Build final name about any tag named branch (maybe don't include feature name including -reviewed or -alpha) | |
if: ${{ env.TAG_VERSION == '' && env.release_name == '' }} | |
# Build name based on a potential included tag (e.g 0.0.7-reviewed, 0.0.7-alpha, 0.0.7) without commit_id suffix | |
# Example of output name 0.0.7-reviewed-SNAPSHOT, feature133-alpha-SNAPSHOT | |
run: echo "release_name=$FEATURE_NAME-SNAPSHOT" >> $GITHUB_ENV | |
binary_build: | |
name: Java components build & test | |
if: success() && github.event_name == 'push' | |
needs: [define_project_release_name] | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
env: | |
RELEASE_NAME: ${{ needs.define_project_release_name.outputs.release_name }} | |
DOCKER_REGISTRY_USERNAME: ${{ secrets.DOCKER_REGISTRY_ACCESS_ACCOUNT }} | |
DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_ACCESS_TOKEN }} | |
MAVEN_USERNAME: ${{ secrets.AGNET_REPO_USERNAME }} | |
MAVEN_PASSWORD: ${{ secrets.AGNET_REPO_PASSWORD }} | |
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} | |
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password | |
outputs: | |
release_name: ${{ env.RELEASE_NAME }} | |
steps: | |
- name: Checkout source codes from branch | |
id: checkout_step | |
uses: actions/checkout@v4 | |
with: | |
repository: ${{ github.repository }} | |
token: ${{ github.token }} | |
ref: ${{ inputs.branch_name }} | |
- name: Set up java runtime (Temurin JDK) | |
uses: actions/setup-java@v4 | |
with: | |
java-version: '11' | |
distribution: 'temurin' | |
cache: maven | |
# defined settings.xml values allowing use of CYBNITY Maven remote repository | |
server-id: agnet | |
server-username: MAVEN_USERNAME | |
server-password: MAVEN_PASSWORD | |
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value (without an modification than exported by the gpg --export-secret-keys command) of the GPG private key (33105BFD367D25B3) to import | |
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase | |
- name: Install gpg secret key used for artefacts signing | |
run: | | |
# Install gpg secret key | |
cat <(echo -e "${{ secrets.MAVEN_GPG_PRIVATE_KEY }}") | gpg --batch --import | |
# Verify gpg secret key | |
gpg --list-secret-keys --keyid-format LONG | |
- name: Validate all necessary information and compile source code | |
run: | | |
echo "Set the project artifacts version in pom files" | |
mvn -B -DgenerateBackupPoms=true -DprocessAllModules=true versions:set -DnewVersion=${{ env.RELEASE_NAME }} | |
echo "Execute the java project(s) build via Maven tool" | |
mvn --batch-mode --update-snapshots --show-version -Drevision=${{ env.RELEASE_NAME }} --fail-fast --file pom.xml -Dstage=commit clean compile -Dmaven.test.skip=true | |
- name: Execute unit tests validating the java compiled source code | |
run: | | |
echo "Compile unit tests and java project(s), and execute tests via Maven tool" | |
mvn --batch-mode --update-snapshots --show-version -Drevision=${{ env.RELEASE_NAME }} -Dmaven.test.skip=false --fail-fast --file pom.xml -Dstage=commit test | |
- name: Package compiled java code in its distributable format (e.g JAR, Docker image) | |
run: | | |
mvn --batch-mode --update-snapshots --show-version -Drevision=${{ env.RELEASE_NAME }} -Ddocker.username=${{ env.DOCKER_REGISTRY_USERNAME }} -Ddocker.password=${{ env.DOCKER_REGISTRY_PASSWORD }} -Ddocker.cleanup=none --fail-fast --file pom.xml -Dstage=commit package -Dmaven.test.skip=true | |
- name: Verify packaged components | |
run: | | |
echo "Run any checks to verify the package is valid and meets quality criteria (including test resources) without unit test execution" | |
mvn -Drevision=${{ env.RELEASE_NAME }} --batch-mode --update-snapshots --show-version -Ddocker.username=${{ env.DOCKER_REGISTRY_USERNAME }} -Ddocker.password=${{ env.DOCKER_REGISTRY_PASSWORD }} -Ddocker.cleanup=none --fail-fast --file pom.xml -Dstage=commit verify -DskipTests | |
# Verify the technical quality of the version | |
check_technical_quality: | |
name: Technical quality check | |
if: success() && github.event_name == 'push' | |
needs: [binary_build] | |
uses: ./.github/workflows/check-project-technical-quality.yml | |
with: | |
config-path: ${{ needs.binary_build.steps.checkout_step.ref }} | |
package_release_name: ${{ needs.binary_build.outputs.release_name }} | |
secrets: inherit | |
# Prepare a release for remote repository installation (published in place of old equals release name in remote repository, reviewed or not) | |
# Publish release of parent pom.xml and sub-projects (reusable by other development, or for processing by Automated Acceptance Test stage) that potentially replace previous equals version named | |
publish_version_to_release_remote_repository: | |
name: Release publishing | |
if: ${{ success() && needs.define_project_release_name.outputs.is_snapshot == 'false' }} | |
needs: [define_project_release_name, binary_build] | |
uses: ./.github/workflows/publish-java-packages-version-to-repository.yml | |
with: | |
config-path: ${{ needs.binary_build.steps.checkout_step.ref }} | |
target_repository: RELEASE | |
package_release_name: ${{ needs.binary_build.outputs.release_name }} | |
secrets: inherit | |
# Prepare only a snapshot version for remote repository installation | |
publish_tagged_version_to_snapshot_remote_repository: | |
name: Tagged snapshot version publishing | |
# By default, don't publish snapshot version on other repository than the local developer workstation's maven repository | |
# The Pull Request (PR) of development revision was approved and merged, but maybe work is not finished | |
# Publish TAGGED snapshot version (parent pom.xml and sub-projects available for other features' developers) on remote repository | |
# it's a development version publishable as 'snapshot' | |
# only when approved, merged and tagged as 'reviewed' (e.g by reviewer) | |
# or only when a reviewed tag is pushed only on the branch (e.g after a review already executed after closed PR) | |
# or only when a alpha tag is pushed only on the branch (e.g when feature developer or reviewer indicate that work is finished) | |
if: ${{ success() | |
&& needs.define_project_release_name.outputs.is_snapshot == 'true' | |
&& ( | |
(github.event.pull_request.merged == true && github.event.pull_request.reviewDecision == 'approved') | |
|| | |
( github.event_name == 'push' && github.ref_type == 'tag' && ( contains(github.ref_name, 'reviewed') || contains(github.ref_name, 'alpha') )) | |
) | |
}} | |
needs: [define_project_release_name, binary_build] | |
uses: ./.github/workflows/publish-java-packages-version-to-repository.yml | |
with: | |
config-path: ${{ needs.binary_build.steps.checkout_step.ref }} | |
target_repository: SNAPSHOT | |
package_release_name: ${{ needs.binary_build.outputs.release_name }} | |
secrets: inherit | |
# Prepare only a snapshot latest version for remote repository installation | |
publish_latest_version_to_snapshot_remote_repository: | |
name: Latest version publishing | |
# Publish not tagged snapshot version but as a common name equals to latest version of feature branche available for other domain application projects managed in other repositories | |
if: ${{ success() | |
&& needs.define_project_release_name.outputs.is_snapshot == 'true' | |
&& (github.event_name == 'push' && needs.define_project_release_name.outputs.latest_release_name != '' && contains(github.ref_name, 'feature')) | |
}} | |
needs: [define_project_release_name, binary_build] | |
uses: ./.github/workflows/publish-java-packages-version-to-repository.yml | |
with: | |
config-path: ${{ needs.binary_build.steps.checkout_step.ref }} | |
target_repository: SNAPSHOT | |
package_release_name: ${{ needs.define_project_release_name.outputs.latest_release_name }} | |
secrets: inherit |