From c9475ffe61f41fbc5a6bdf1b2f632a788b3df3f8 Mon Sep 17 00:00:00 2001 From: Michael Seele Date: Tue, 5 May 2026 12:42:00 +0000 Subject: [PATCH] feat: add maven-build action --- .forgejo/workflows/tag-release.yml | 1 + README.md | 1 + maven-build/README.md | 58 +++++++++++++++ maven-build/action.yml | 116 +++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 maven-build/README.md create mode 100644 maven-build/action.yml diff --git a/.forgejo/workflows/tag-release.yml b/.forgejo/workflows/tag-release.yml index 0c7be9f..2209052 100644 --- a/.forgejo/workflows/tag-release.yml +++ b/.forgejo/workflows/tag-release.yml @@ -19,6 +19,7 @@ on: - cache - checkout - inject-content + - maven-build - pnpm-build - publish-static-contents - terraform-apply diff --git a/README.md b/README.md index 4c67c09..1955a88 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Shared actions for Forgejo CI/CD pipelines. | [cache](cache) | Cache files between workflow runs | | [checkout](checkout) | Action for checking out a repository | | [inject-content](inject-content) | Inject content into a file by appending or overwriting | +| [maven-build](maven-build) | Action for building and validating Maven projects | | [pnpm-build](pnpm-build) | Action for building and validating with PNPM | | [publish-static-contents](publish-static-contents) | Syncs frontend assets to S3 and invalidates a CloudFront distribution | | [terraform-apply](terraform-apply) | Apply Terraform configuration files using the official Terraform CLI | diff --git a/maven-build/README.md b/maven-build/README.md new file mode 100644 index 0000000..8e243d5 --- /dev/null +++ b/maven-build/README.md @@ -0,0 +1,58 @@ +# maven-build + +Action for building and validating Maven projects. + +## Inputs + +| Input | Required | Default | Description | +|-------|----------|---------|-------------| +| `java-version` | No | `25` | Java version to set up for the build | +| `maven-version` | No | `3.9.15` | Maven version to set up for the build | +| `distribution` | No | `temurin` | JDK distribution to use | +| `phase` | No | `verify` | Build phase to execute: `verify` runs code-quality checks; `deploy` builds and pushes a Docker image | +| `verify-goals` | No | `spotless:check checkstyle:check test` | Space-separated Maven goals to run during the verify phase | +| `maven-profile` | No | `test` | Maven profile to activate during deploy | +| `service-dir` | No | `.` | Working directory for the Maven build | +| `maven-settings` | **Yes** | — | Secret containing the `settings.xml` content used for repository authentication | +| `extra-args` | No | `""` | Additional Maven arguments appended to the build command | + +## Outputs + +| Output | Description | +|--------|-------------| +| `image-tag` | The Docker image tag used during the deploy phase | + +## Usage + +### Verify (code quality + tests) + +```yaml +- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/maven-build@maven-build-v1 + with: + maven-settings: ${{ secrets.MAVEN_SETTINGS }} +``` + +### Deploy (build and push Docker image) + +```yaml +- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/maven-build@maven-build-v1 + with: + phase: deploy + maven-profile: prod + maven-settings: ${{ secrets.MAVEN_SETTINGS }} +``` + +### Multi-module project + +```yaml +- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/maven-build@maven-build-v1 + with: + service-dir: my-service + maven-settings: ${{ secrets.MAVEN_SETTINGS }} +``` + +## Notes + +- The `maven-settings` input is written to a temporary file (`/tmp/maven-settings.xml`) and removed after the build, even on failure. +- During the `deploy` phase, the image tag is generated as `-` and exposed via the `image-tag` output. +- Third-party actions used internally are pinned to exact commit SHAs to prevent supply chain attacks. diff --git a/maven-build/action.yml b/maven-build/action.yml new file mode 100644 index 0000000..263766f --- /dev/null +++ b/maven-build/action.yml @@ -0,0 +1,116 @@ +name: maven-build +description: Action for building and validating Maven projects + +inputs: + java-version: + required: false + default: '25' + description: 'Java version to set up for the build' + maven-version: + required: false + default: '3.9.15' + description: 'Maven version to set up for the build' + distribution: + required: false + default: 'temurin' + description: 'JDK distribution to use' + phase: + required: false + default: 'verify' + description: 'Build phase to execute: "verify" runs code-quality checks; "deploy" builds and pushes a Docker image' + verify-goals: + required: false + default: 'spotless:check checkstyle:check test' + description: 'Space-separated Maven goals to run during the verify phase' + maven-profile: + required: false + default: 'test' + description: 'Maven profile to activate during deploy' + service-dir: + required: false + default: '.' + description: 'Working directory for the Maven build' + maven-settings: + required: true + description: 'Secret containing the settings.xml content used for repository authentication' + extra-args: + required: false + default: '' + description: 'Additional Maven arguments appended to the build command' + +outputs: + image-tag: + description: 'The Docker image tag used during the deploy phase' + value: ${{ steps.deploy.outputs.image-tag }} + +runs: + using: composite + steps: + - name: Validate phase + shell: bash + env: + BUILD_PHASE: ${{ inputs.phase }} + run: | + case "$BUILD_PHASE" in + verify|deploy) ;; + *) echo "Invalid phase '$BUILD_PHASE'. Must be 'verify' or 'deploy'." && exit 1 ;; + esac + + # Pinned to commit SHA instead of a tag to prevent supply chain attacks. + # actions/setup-java v4.8.0 — https://github.com/actions/setup-java/tree/v4.8.0 + - name: Setup Java + uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 + with: + java-version: ${{ inputs.java-version }} + distribution: ${{ inputs.distribution }} + + - name: Setup Maven + shell: bash + env: + MAVEN_VERSION: ${{ inputs.maven-version }} + run: | + curl -fsSL "https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz" \ + | tar -xzf - -C /opt + echo "/opt/apache-maven-${MAVEN_VERSION}/bin" >> "$GITHUB_PATH" + echo "Maven ${MAVEN_VERSION} installed successfully" + + - name: Write Maven settings + shell: bash + env: + MAVEN_SETTINGS: ${{ inputs.maven-settings }} + run: printf '%s\n' "$MAVEN_SETTINGS" > /tmp/maven-settings.xml + + - name: Verify + if: ${{ inputs.phase == 'verify' }} + shell: bash + working-directory: ${{ inputs.service-dir }} + env: + VERIFY_GOALS: ${{ inputs.verify-goals }} + EXTRA_ARGS: ${{ inputs.extra-args }} + run: | + mvn --batch-mode $VERIFY_GOALS \ + -s /tmp/maven-settings.xml \ + $EXTRA_ARGS + + - name: Deploy + id: deploy + if: ${{ inputs.phase == 'deploy' }} + shell: bash + working-directory: ${{ inputs.service-dir }} + env: + MAVEN_PROFILE: ${{ inputs.maven-profile }} + EXTRA_ARGS: ${{ inputs.extra-args }} + run: | + IMAGE_TAG="${FORGEJO_SHA}-$(date +%s)" + mvn --batch-mode clean package jib:build \ + -DsendCredentialsOverHttp=true \ + "-Djib.to.tags=$IMAGE_TAG" \ + -P "$MAVEN_PROFILE" \ + -s /tmp/maven-settings.xml \ + $EXTRA_ARGS + echo "image-tag=$IMAGE_TAG" >> "$GITHUB_OUTPUT" + + - name: Remove Maven settings + if: always() + shell: bash + run: rm -f /tmp/maven-settings.xml