Reusable GitHub Actions workflows

build-reusable.yaml

This workflow:

  • Compiles using the specified Java compiler version

Examples

Snippet from an example build.yaml using this workflow
build:
  uses: apache/logging-parent/.github/workflows/build-reusable.yaml@gha/v0
  secrets:
    DV_ACCESS_TOKEN: ${{ startsWith(github.ref_name, 'release/') && '' || secrets.DEVELOCITY_ACCESS_KEY }}
  with:
    site-enabled: true
    reproducibility-check-enabled: false
    develocity-enabled: ${{ ! startsWith(github.ref_name, 'release/') }}

deploy-snapshot-reusable.yaml

This workflow deploys SNAPSHOT artifacts.

Examples

Snippet from an example build.yaml using this workflow
deploy-snapshot:
  needs: build
  if: github.repository == 'apache/logging-log4j2' && github.ref_name == '2.x'
  uses: apache/logging-parent/.github/workflows/deploy-snapshot-reusable.yaml@gha/v0
  # Secrets for deployments
  secrets:
    NEXUS_USERNAME: ${{ secrets.NEXUS_USER }}
    NEXUS_PASSWORD: ${{ secrets.NEXUS_PW }}

deploy-release-reusable.yaml

This workflow:

  • Deploys release artifacts

  • Updates revision and project.build.outputTimestamp Maven properties

  • Generates the distribution ZIP containing Git-tracked sources, binary attachments, NOTICE.txt, etc.

  • Generates the release vote & announcement emails

  • Uploads the distribution ZIP and emails to SVN

Examples

Snippet from an example build.yaml using this workflow
deploy-release:
  needs: build
  if: github.repository == 'apache/logging-log4j2' && startsWith(github.ref_name, 'release/')
  uses: apache/logging-parent/.github/workflows/deploy-release-reusable.yaml@gha/v0
  # Secrets for deployments
  secrets:
    GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }}
    NEXUS_USERNAME: ${{ secrets.LOGGING_STAGE_DEPLOYER_USER }}
    NEXUS_PASSWORD: ${{ secrets.LOGGING_STAGE_DEPLOYER_PW }}
    SVN_USERNAME: ${{ secrets.LOGGING_SVN_DEV_USERNAME }}
    SVN_PASSWORD: ${{ secrets.LOGGING_SVN_DEV_PASSWORD }}
  # Write permissions to allow the Maven `revision` property update, changelog release, etc.
  permissions:
    contents: write
  with:
    project-id: log4j

verify-reproducibility-reusable.yaml

This workflow verifies the reproducibility of a previous deploy-snapshot-reusable.yaml or deploy-release-reusable.yaml workflow.

Examples

To verify the reproducibility of a snapshot, you can use:

Snippet from an example build.yaml using this workflow
verify-reproducibility-snapshot:
  needs: deploy-snapshot
  name: "verify-reproducibility (${{ needs.deploy-snapshot.outputs.project-version }})"
  uses: apache/logging-parent/.github/workflows/verify-reproducibility-reusable.yaml@gha/v0
  with:
    # Reference repository
    nexus-url: https://repository.apache.org/content/groups/snapshots
    # Encode the `runs-on` input as JSON array
    runs-on: '["ubuntu-latest", "macos-latest"]'

To verify the reproducibility of a release, you can use:

Snippet from an example build.yaml using this workflow
verify-reproducibility-release:
  needs: deploy-release
  name: "verify-reproducibility (${{ needs.deploy-release.outputs.project-version }})"
  uses: apache/logging-parent/.github/workflows/verify-reproducibility-reusable.yaml@gha/v0
  with:
    # Reference repository
    nexus-url: ${{ needs.deploy-release.outputs.nexus-url }}
    # Encode the `runs-on` input as JSON array
    runs-on: '["ubuntu-latest", "macos-latest"]'

analyze-dependabot-reusable.yaml

Analyzes Dependabot pull requests to collect detailed information about updated dependencies. Stores the results in the dependabot-metadata artifact, which is later consumed by the process-dependabot-reusable.yaml workflow to automate changelog generation and PR processing.

This workflow must be triggered by an event that includes the pull_request payload and does not require any privileges. It can then be used in a pull_request workflow.

Snippet from an example analyze-dependabot.yaml using this workflow
analyze-dependabot:
  # `github.actor` prevents recursive calls when `github-actions[bot]` pushes to the PR;
  # `github.event.pull_request.user.login` skips PRs not opened by Dependabot.
  if: ${{
      github.repository == 'apache/logging-parent'
      && github.actor == 'dependabot[bot]'
      && github.event.pull_request.user.login == 'dependabot[bot]'
    }}
  uses: apache/logging-parent/.github/workflows/analyze-dependabot-reusable.yaml@gha/v0

process-dependabot-reusable.yaml

Helps to process Dependabot pull requests by:

  • Generating changelog entries for the updated dependencies and committing them to the PR branch.

  • Switching the pull request into “draft mode”.

The workflow only needs the default GITHUB_TOKEN with contents: write and pull-requests: write permissions.

This workflow is designed to be triggered by the workflow_run event, as soon as the analyze-dependabot-reusable.yaml workflow completes.

Pushes made with GITHUB_TOKEN do not retrigger workflows (GitHub anti-recursion rule), so the changelog commit cannot re-run the required checks on its own. This reusable workflow therefore parks the PR in “draft mode” and stops there.

The expected flow for each Dependabot PR is:

  1. The reusable workflow appends the changelog commit and converts the PR into draft.

  2. A maintainer reviews the change, clicks Ready for review, and enables Auto-merge.

  3. The required-check workflows re-run against the new HEAD; once they pass, Auto-merge completes the merge without further manual action.

For step 3 to work, every workflow providing a required check must subscribe to ready_for_review:

on:
  pull_request:
    types:
      # Standard types
      - opened
      - synchronize
      - reopened
      # Used in Dependabot PRs to retrigger required workflows
      - ready_for_review

This reusable workflow does not enable “Auto-merge”; a maintainer must do that by hand.

Snippet from an example process-dependabot.yaml using this workflow
process-dependabot:
  # Skip this workflow on commits not pushed by Dependabot
  if: ${{
      github.repository == 'apache/logging-parent'
      && github.actor == 'dependabot[bot]'
      && github.event.workflow_run.conclusion == 'success'
    }}
  uses: apache/logging-parent/.github/workflows/process-dependabot-reusable.yaml@gha/v0
  permissions:
    # Append the changelog commit
    contents: write
    # Convert the PR into draft
    pull-requests: write
  with:
    # The path to the changelog directory for the current development branch.
    changelog-path: src/changelog/.12.x.x

deploy-site-reusable.yaml

This workflow builds and deploys the website.

Examples

To update the staging website, you can use:

Snippet from an example deploy-site.yaml using this workflow
deploy-site-stg:
  if: github.repository == 'apache/logging-log4j2' && github.ref_name == '2.x'
  uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@gha/v0
  # Secrets for committing the generated site
  secrets:
    GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }}
  # Write permissions for committing the generated site
  permissions:
    contents: write
  with:
    asf-yaml-content: |
      staging:
        profile: ~
        whoami: ${{ github.ref_name }}-site-stg-out
        subdir: content/log4j/2.x
    install-required: true
    target-branch: ${{ github.ref_name }}-site-stg-out

To stage a separate website for a release candidate, you can use:

Snippet from an example deploy-site.yaml using this workflow
export-version:
  if: github.repository == 'apache/logging-log4j2' && startsWith(github.ref_name, 'release/')
  runs-on: ubuntu-latest
  outputs:
    version: ${{ steps.export-version.outputs.version }}
  steps:
    - name: Export version
      id: export-version
      run: |
        version=$(echo "${{ github.ref_name }}" | sed 's/^release\///')
        echo "version=$version" >> "$GITHUB_OUTPUT"

deploy-site-rel:
  needs: export-version
  uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@gha/v0
  # Secrets for committing the generated site
  secrets:
    GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }}
  # Write permissions for committing the generated site
  permissions:
    contents: write
  with:
    asf-yaml-content: |
      staging:
        profile: ~
        whoami: ${{ github.ref_name }}-site-stg-out
        subdir: content/log4j/${{ needs.export-version.outputs.version }}
    install-required: true
    target-branch: ${{ github.ref_name }}-site-stg-out

To update the production website after a release, you can use:

Snippet from an example deploy-site.yaml using this workflow
deploy-site-pro:
  if: github.repository == 'apache/logging-log4j2' && github.ref_name == '2.x-site-pro'
  uses: apache/logging-parent/.github/workflows/deploy-site-reusable.yaml@gha/v0
  # Secrets for committing the generated site
  secrets:
    GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }}
  # Write permissions for committing the generated site
  permissions:
    contents: write
  with:
    asf-yaml-content: |
      publish:
        whoami: ${{ github.ref_name }}-out
        subdir: content/log4j/2.x
    install-required: true
    target-branch: ${{ github.ref_name }}-out