pre-review

name: pre-review

on:
  pull_request:
    branches:
      - main
      - release-*

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  GRADLE_OPTS: "-Xmx6g -Dorg.gradle.parallel=true"
  total-runners: 8

jobs:
  repolint:
    name: "Repository Linting"
    runs-on: ubuntu-22.04
    container: ghcr.io/todogroup/repolinter:v0.11.2
    steps:
    - name: Checkout Code
      uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      with:
        ref: ${{ github.event.pull_request.head.sha || github.ref }}
    - name: Lint Repo
      run: bundle exec /app/bin/repolinter.js --rulesetUrl https://raw.githubusercontent.com/hyperledger-labs/hyperledger-community-management-tools/main/repo_structure/repolint.json --format markdown
  gradle-wrapper:
    name: "Gradle Wrapper Validation"
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
      - uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4
  spotless:
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: run spotless
        run: ./gradlew spotlessCheck
  compile:
    runs-on: ubuntu-22.04
    timeout-minutes: 30
    needs: [spotless, gradle-wrapper, repolint]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: Gradle Compile
        run: ./gradlew build -x test -x spotlessCheck
  unitTests:
    env:
        GRADLEW_UNIT_TEST_ARGS: ${{matrix.gradle_args}}
    runs-on: ubuntu-22.04
    needs: [spotless, gradle-wrapper, repolint]
    permissions:
      checks: write
      statuses: write
    strategy:
      fail-fast: true
      matrix:
        runner_index: [0,1,2,3,4,5,6,7]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: Install required packages
        run:  sudo apt-get install -y xmlstarlet
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: List unit tests
        run: ./gradlew test --test-dry-run -Dorg.gradle.parallel=true -Dorg.gradle.caching=true
      - name: Extract current test list
        run: mkdir tmp; find . -type f -name TEST-*.xml | xargs -I{} bash -c "xmlstarlet sel -t -v '/testsuite/@name' '{}'; echo '{}' | sed 's#\./\(.*\)/build/test-results/.*# \1#'" | tee tmp/currentTests.list
      - name: Get unit test reports
        uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d
        continue-on-error: true
        with:
          branch: main
          workflow: update-test-reports.yml
          name: unit-test-results
          path: tmp/junit-xml-reports-downloaded
          if_no_artifact_found: ignore
      - name: Split tests
        run: .github/workflows/splitTestsByTime.sh tmp/junit-xml-reports-downloaded "tmp/junit-xml-reports-downloaded/unit-.*-test-results" "build/test-results" ${{env.total-runners}} ${{ matrix.runner_index }} > testList.txt
      - name: Upload Timing
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        if: matrix.runner_index == 0
        with:
          name: unit-tests-timing
          path: 'tmp/timing.tsv'
      - name: Upload Lists
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        if: matrix.runner_index == 0
        with:
          name: unit-tests-lists
          path: 'tmp/*.list'
      - name: Upload gradle test tasks
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          name: testList-${{ matrix.runner_index }}.txt
          path: testList.txt
      - name: run unit tests
        run: cat testList.txt | xargs -P 1 ./gradlew -Dorg.gradle.parallel=true -Dorg.gradle.caching=true
      - name: Remove downloaded test results
        run: rm -rf tmp/junit-xml-reports-downloaded
      - name: Upload Unit Test Results
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          name: unit-${{matrix.runner_index}}-test-results
          path: '**/test-results/**/TEST-*.xml'
  unittests-passed:
    name: "unittests-passed"
    runs-on: ubuntu-22.04
    needs: [compile, unitTests]
    permissions:
      checks: write
      statuses: write
    if: always()
    steps:
      # Fail if any `needs` job was not a success.
      # Along with `if: always()`, this allows this job to act as a single required status check for the entire workflow.
      - name: Fail on workflow error
        run: exit 1
        if: >-
          ${{
            contains(needs.*.result, 'failure')
            || contains(needs.*.result, 'cancelled')
            || contains(needs.*.result, 'skipped')
          }}


reference-tests

name: reference-tests
on:
  workflow_dispatch:
  pull_request:
    branches:
      - main
      - release-*

env:
  GRADLE_OPTS: "-Xmx6g -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.caching=true"
  total-runners: 10

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  referenceTestEthereum:
    runs-on: ubuntu-22.04
    permissions:
      statuses: write
      checks: write
      packages: read
    strategy:
      fail-fast: true
      matrix:
        runner_index: [1,2,3,4,5,6,7,8,9,10]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
          submodules: recursive
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: semeru # IBM Semeru with OpenJ9
          java-version: 21
      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: execute generate reference tests
        run: ./gradlew ethereum:referencetests:referenceTestClasses -Dorg.gradle.parallel=true -Dorg.gradle.caching=true
      - name: list test files generated
        run: find ethereum/referencetests/build/generated/sources/reference-test -name "*.java" | sort >> filenames.txt
      - name: Split tests
        run: ./.github/workflows/splitList.sh filenames.txt ${{env.total-runners}}
      - name: echo test file count
        run: cat group_${{matrix.runner_index}}.txt | wc
      - name: convert to test suite classnames
        run: cat group_${{matrix.runner_index}}.txt | sed -e 's/^.*java\///' -e 's@/@.@g' -e 's/\.java//' -e 's/^/--tests /' > testClasses.txt
      - name: compose gradle args
        run: tr '\n' ' ' < testClasses.txt > refTestArgs.txt
      - name: refTestArgs.txt
        run: cat refTestArgs.txt
      - name: run reference tests
        run: ./gradlew ethereum:referenceTests:referenceTests `cat refTestArgs.txt`
      - name: Upload Test Report
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        if: always() # always run even if the previous step fails
        with:
          name: reference-test-node-${{matrix.runner_index}}-results
          path: '**/build/test-results/referenceTests/TEST-*.xml'
  reftests-passed:
    name: "reftests-passed"
    runs-on: ubuntu-22.04
    needs: [ referenceTestEthereum ]
    permissions:
      checks: write
      statuses: write
    if: always()
    steps:
      # Fail if any `needs` job was not a success.
      # Along with `if: always()`, this allows this job to act as a single required status check for the entire workflow.
      - name: Fail on workflow error
        run: exit 1
        if: >-
          ${{
            contains(needs.*.result, 'failure')
            || contains(needs.*.result, 'cancelled')
            || contains(needs.*.result, 'skipped')
          }}


integration-tests

name: integration-tests
on:
  workflow_dispatch:
  pull_request:
    branches:
      - main
      - release-*

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  GRADLE_OPTS: "-Xmx6g -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.caching=true"

jobs:
  integration-tests:
    name: "integration-passed"
    runs-on: ubuntu-22.04
    permissions:
      statuses: write
      checks: write
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: run integration tests
        run: ./gradlew integrationTest compileJmh


docker develop

name: docker develop

on:
  push:
    branches:
      - main
env:
  registry: docker.io

jobs:
  hadolint:
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true

      - name: hadoLint
        run: docker run --rm -i hadolint/hadolint < docker/Dockerfile
  buildDocker:
    needs: hadolint
    permissions:
      contents: read
      packages: write

    strategy:
      fail-fast: false
      matrix:
        platform:
          - ubuntu-22.04
          - besu-arm64
    runs-on: ${{ matrix.platform }}
    steps:
      - name: Prepare
        id: prep
        run: |
          platform=${{ matrix.platform }}
          if [ "$platform" = 'ubuntu-22.04' ]; then
            echo "PLATFORM_PAIR=linux-amd64" >> $GITHUB_OUTPUT
            echo "ARCH=amd64" >> $GITHUB_OUTPUT
          else
            echo "PLATFORM_PAIR=linux-arm64" >> $GITHUB_OUTPUT
            echo "ARCH=arm64" >> $GITHUB_OUTPUT
          fi

          # Get the current date and time in the format YY.MM
          DATE_TIME=$(date +"%y.%-m")
          # Get the short SHA of the merge commit
          SHORT_SHA=${GITHUB_SHA::7}
          # Construct the build target name
          BUILD_TARGET_NAME="${DATE_TIME}-develop-${SHORT_SHA}"
          echo "Build Target Name: $BUILD_TARGET_NAME"
          # Set the build target name as an environment variable
          echo "BUILD_TARGET_NAME=${BUILD_TARGET_NAME}" >> $GITHUB_ENV

      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: install goss
        run: |
          mkdir -p docker/reports
          curl -L https://github.com/aelsabbahy/goss/releases/download/v0.4.4/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} -o ./docker/tests/goss-${{ steps.prep.outputs.PLATFORM_PAIR }}
      - name: login to ${{ env.registry }}
        uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        with:
          registry: ${{ env.registry }}
          username: ${{ secrets.DOCKER_USER_RW }}
          password: ${{ secrets.DOCKER_PASSWORD_RW }}
      - name: build and test docker
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        env:
          architecture: ${{ steps.prep.outputs.ARCH }}
        with:
          cache-disabled: true
          arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{ env.BUILD_TARGET_NAME}} -Prelease.releaseVersion=develop
      - name: publish
        env:
          architecture: ${{ steps.prep.outputs.ARCH }}
        run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{ env.BUILD_TARGET_NAME }} -Prelease.releaseVersion=develop
  multiArch:
    needs: buildDocker
    runs-on: ubuntu-22.04
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21
      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true
      - name: login to ${{ env.registry }}
        uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        with:
          registry: ${{ env.registry }}
          username: ${{ secrets.DOCKER_USER_RW }}
          password: ${{ secrets.DOCKER_PASSWORD_RW }}
      - name: multi-arch docker
        run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{ env.BUILD_TARGET_NAME }} -Prelease.releaseVersion=develop


update-test-reports

name: update-test-reports

on:
  push:
    branches:
      - main

jobs:
  syncTestReports:
    if: github.repository == 'hyperledger/besu'
    runs-on: ubuntu-22.04
    steps:
      - name: Get latest merge PR number
        id: latest_merged_pr_number
        run: echo "PULL_REQUEST_NUMBER=$(gh pr list --repo hyperledger/besu --base main --state merged --json "number,mergedAt" --search "sort:updated-desc" --jq 'max_by(.mergedAt)|.number')" >> "$GITHUB_OUTPUT"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Get unit test reports from latest merged PR
        uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d
        with:
          workflow: pre-review.yml
          workflow_conclusion: success
          pr: ${{ env.LATEST_MERGED_PR_NUMBER }}
          name_is_regexp: true
          name: 'unit-\d+-test-results'
          path: unit-test-results
          if_no_artifact_found: fail
        env:
          LATEST_MERGED_PR_NUMBER: ${{ steps.latest_merged_pr_number.outputs.PULL_REQUEST_NUMBER }}
      - name: Upload unit test results
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          name: unit-test-results
          path: 'unit-test-results/**/test-results/**/TEST-*.xml'
      - name: Get acceptance test reports from latest merged PR
        uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d
        with:
          workflow: acceptance-tests.yml
          workflow_conclusion: success
          pr: ${{ env.LATEST_MERGED_PR_NUMBER }}
          name_is_regexp: true
          name: 'acceptance-node-\d+-test-results'
          path: acceptance-test-results
          if_no_artifact_found: fail
        env:
          LATEST_MERGED_PR_NUMBER: ${{ steps.latest_merged_pr_number.outputs.PULL_REQUEST_NUMBER }}
      - name: Upload acceptance test results
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          name: acceptance-test-results
          path: 'acceptance-test-results/**/TEST-*.xml'


container security scan

name: container security scan

on:
  workflow_dispatch:
    inputs:
      tag:
        description: 'Container image tag'
        required: false
        default: 'develop'
  schedule:
    # Start of the hour is the busy time. Scheule it to run 8:17am UTC
    - cron:  '17 8 * * *'

jobs:
  scan-sarif:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write

    steps:
      - name: Checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

      # Shell parameter expansion does not support directly on a step
      # Adding a separate step to set the image tag. This allows running
      # this workflow with a schedule as well as manual
      - name: Set image tag
        id: tag
        run: |
          echo "TAG=${INPUT_TAG:-develop}" >> "$GITHUB_OUTPUT"
        env:
          INPUT_TAG: ${{ inputs.tag }}

      - name: Vulnerability scanner
        id: trivy
        uses: aquasecurity/trivy-action@595be6a0f6560a0a8fc419ddf630567fc623531d
        with:
          image-ref: hyperledger/besu:${{ steps.tag.outputs.TAG }}
          format: sarif
          output: 'trivy-results.sarif'

      # Check the vulnerabilities via GitHub security tab
      - name: Upload results
        uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251
        with:
          sarif_file: 'trivy-results.sarif'


container verify

name: container verify

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Besu version'
        required: true
      verify-latest-version:
        description: 'Check latest container version'
        required: false
        type: choice
        default: "true"
        options:
          - "true"
          - "false"

jobs:
  verify:
    timeout-minutes: 4
    strategy:
      matrix:
        combination:
          - tag: ${{ inputs.version }}
            platform: ''
            runner: ubuntu-latest
          - tag: ${{ inputs.version }}-amd64
            platform: 'linux/amd64'
            runner: ubuntu-latest
          - tag: latest
            platform: ''
            runner: ubuntu-latest
          - tag: ${{ inputs.version }}-arm64
            platform: ''
            runner: besu-arm64
    runs-on: ${{ matrix.combination.runner }}
    env:
      CONTAINER_NAME: besu-check
    steps:
      - name: Checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

      - name: Start container
        run: |
          PLATFORM_OPT=""
          [[ x${{ matrix.combination.platform }} != 'x' ]] && PLATFORM_OPT="--platform ${{ matrix.combination.platform }}"
          docker run -d $PLATFORM_OPT --name ${{ env.CONTAINER_NAME }} hyperledger/besu:${{ matrix.combination.tag }}

      - name: Verify besu container
        run: bash .github/workflows/BesuContainerVerify.sh
        env:
          TAG: ${{ matrix.combination.tag }}
          VERSION: ${{ inputs.version }}
          CHECK_LATEST: ${{ inputs.verify-latest-version }}

      - name: Stop container
        run: docker stop ${{ env.CONTAINER_NAME }}


Mark stale issues and pull requests

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
---
name: Mark stale issues and pull requests

on:
  schedule:
    - cron: "0 0 * * *"

permissions:
  contents: read

jobs:
  stale:
    permissions:
      issues: write  # for actions/stale to close stale issues
      pull-requests: write  # for actions/stale to close stale PRs
    runs-on: ubuntu-latest
    if: startsWith(github.repository,'odpi/')
    steps:
      - name: check stale issues and prs
        if: startsWith(github.repository,'odpi/')
        uses: actions/stale@v9
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          stale-issue-message: >
            This issue has been automatically marked as stale because it has
            not had recent activity. It will be closed in 20 days if no
            further activity occurs. Thank you for your contributions.
          stale-pr-message: >
            This PR has been automatically marked as stale because it has not
            had recent activity. It will be closed in 20 days if no further
            activity occurs. Thank you for your contributions.
          stale-issue-label: 'no-issue-activity'
          stale-pr-label: 'no-pr-activity'
          days-before-stale: 60
          days-before-close: 20
          exempt-issue-labels: 'pinned'
          exempt-pr-labels: 'pinned'
          operations-per-run: 30


Check documentation links

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
---
name: "Check documentation links"

on:
  push:
  pull_request:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  linkChecker:
    runs-on: ubuntu-latest
    if: startsWith(github.repository,'odpi/')
    steps:
      - uses: actions/checkout@v4.1.0
      - name: Link Checker
        uses: lycheeverse/lychee-action@v1.9.3
        with:
          # Can switch to true once we run clean
          fail: false
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}


Scorecards supply-chain security

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
---
name: Scorecards supply-chain security
on:
  # Only the default branch is supported.
  branch_protection_rule:
  schedule:
    - cron: '26 9 * * 6'
  push:
    branches: ["main"]
  # Also allow for manual invocation for testing
  workflow_dispatch:

# Declare default permissions as read only.
permissions: read-all

jobs:
  analysis:
    name: Scorecards analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Used to receive a badge.
      id-token: write
      # Needs for private repositories.
      contents: read
      actions: read

    steps:
      - name: "Checkout code"
        uses: actions/checkout@v4.1.0  # tag=v3.0.0
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534  # tag=v2.3.3
        with:
          results_file: results.sarif
          results_format: sarif
          # (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
          # - you want to enable the Branch-Protection check on a *public* repository, or
          # - you are installing Scorecards on a *private* repository
          # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
          # repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}

          # Publish the results for public repositories to enable scorecard badges. For more details, see
          # https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories, `publish_results` will automatically be set to `false`, regardless
          # of the value entered here.
          publish_results: true

      # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
      # format to the repository Actions tab.
      - name: "Upload artifact"
        uses: actions/upload-artifact@v4.3.1  # tag=v3.0.0
        with:
          name: SARIF file
          path: results.sarif
          retention-days: 5

      # Upload the results to GitHub's code scanning dashboard.
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@v3.25.7  # tag=v1.0.26
        with:
          sarif_file: results.sarif


Verify PR v5

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
---
name: "Verify PR v5"

on:
  pull_request:
    branches: [main, egeria-release-5*]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    name: "Verify PR v5"
    if: startsWith(github.repository,'odpi/')
    steps:
      - uses: actions/checkout@v4.1.0
      - uses: gradle/wrapper-validation-action@v2
      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Build with Gradle
        uses: gradle/gradle-build-action@v3
        with:
          # Only cache for main build
          cache-read-only: true
          arguments: |
            build
            --scan
      - name: Upload Test coverage report
        uses: actions/upload-artifact@v4.3.1
        with:
          name: Jacoco Coverage Report
          path: build/reports/jacoco/codeCoverageReport
      - name: Upload Log of any dependency failures
        uses: actions/upload-artifact@v4.3.1
        with:
          name: Dependency Analysis Report (on failure)
          path: build/reports/dependency-analysis/build-health-report.txt
          if-no-files-found: ignore


CodeQL Analysis v5

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
#
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
---
name: "CodeQL Analysis v5"

on:
  push:
    branches: [main, egeria-release-5*]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [main, egeria-release-5*]
  workflow_dispatch:

jobs:
  analyze:
    if: ${{ github.repository == 'odpi/egeria'}}
    name: "CodeQL Build v5"
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.0
      - uses: gradle/wrapper-validation-action@v2
      - name: Setup Java JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      # Initializes the CodeQL tools for scanning.
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3.25.7
        with:
          languages: java
          queries: security-and-quality
          ram: 4096
      - name: Build
        uses: gradle/gradle-build-action@v3
        with:
          # codeQL requires a full before/after build to compare results. Caching can result in action failing
          #cache-read-only: true
          cache-disabled: true
          arguments: -x javadoc -x test build -PskipOpenTypesFVT
      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3.25.7
        with:
          ram: 4096


Merge v5

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
---
name: "Merge v5"

# Trigger after code is merged. only on main repo
# - does not run on modification (may be just text)

on:
  push:
    branches: [main, egeria-release-5*]

permissions:
  contents: read

jobs:
  build:
    permissions:
      # for gh-pages
      contents: write
    runs-on: ubuntu-latest
    name: "Merge v5"
    if: startsWith(github.repository,'odpi/')
    steps:
      - uses: actions/checkout@v4.1.0
        name: Checkout source
      - uses: gradle/wrapper-validation-action@v2
      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
      # Build first - lombok & other pre-processing may be needed. safer...
      - name: build and publish to maven central
        if: ${{ github.ref == 'refs/heads/main'}}
        uses: gradle/gradle-build-action@v3
        with:
          cache-read-only: false
          arguments: build publish
        # Import secrets needed for code signing and distribution
        env:
          OSSRH_GPG_KEYID: ${{ secrets.OSSRH_GPG_KEYID }}
          OSSRH_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }}
          OSSRH_GPG_PRIVATE_KEY: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }}
          ORG_GRADLE_PROJECT_mavenRepoPass: ${{ secrets.OSSRH_TOKEN }}
          ORG_GRADLE_PROJECT_mavenRepoUser: ${{ secrets.OSSRH_USERNAME }}
      # In other cases just build but don't publish
      - name: build (no publish to maven central)
        if: ${{ github.ref != 'refs/heads/main'}}
        uses: gradle/gradle-build-action@v3
        with:
          cache-read-only: false
          arguments: build
      # Now aggregate javadoc - main only
      - name: build
        if: ${{ github.ref == 'refs/heads/main'}}
        uses: gradle/gradle-build-action@v3
        with:
          cache-read-only: false
          arguments: aggregateJavadoc
      - name: publish aggregate javadoc
        if: ${{ github.ref == 'refs/heads/main'}}
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          branch: gh-pages
          folder: build/docs/javadoc
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to container registry (Quay.io)
        uses: docker/login-action@v3
        with:
          registry: quay.io
          username: ${{ secrets.QUAY_IO_USERNAME }}
          password: ${{ secrets.QUAY_IO_ACCESS_TOKEN }}
      - name: Login to container registry (Docker Hub)
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
      # QEMU is needed for ARM64 build for egeria-configure
      # egeria-configure needs to install utilities
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set Release version env variable
        run: |
          echo "VERSION=$(./gradlew properties --no-daemon --console=plain -q | grep '^version:' | awk '{printf $2}')" >> $GITHUB_ENV
      # Publish container images(egeria-platform) to quay.io and docker.io
      - name: Copy the distribution content to be used in docker copy command
        run: |
          cp -f container.application.properties ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform/application.properties
          mkdir -p ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform/data/servers
          cp -r ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/opt/sample-configs/*-* ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform/data/servers
          cp -r ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/opt/sample-data ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform
          cp -r ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/opt/coco-pharmaceuticals ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform
      - name: Build and push(egeria) to quay.io and docker.io (tag latest only for main!)
        if: ${{ github.ref == 'refs/heads/main'}}
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: odpi/egeria-platform:${{ env.VERSION }}, odpi/egeria-platform:latest, quay.io/odpi/egeria:${{ env.VERSION }}, quay.io/odpi/egeria:latest
          context: ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz
          platforms: linux/amd64,linux/arm64
      - name: Build and push(egeria-platform) to quay.io and docker.io (no tag latest)
        if: ${{ github.ref != 'refs/heads/main'}}
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: odpi/egeria-platform:${{ env.VERSION }}, quay.io/odpi/egeria-platform:${{ env.VERSION }}
          context: ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz
          platforms: linux/amd64,linux/arm64
      # Publish container images(egeria-configure) to quay.io and docker.io
      - name: Build and push(egeria-configure) to quay.io and docker.io (tag latest)
        if: ${{ github.ref == 'refs/heads/main'}}
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: odpi/egeria-configure:${{ env.VERSION }}, odpi/egeria-configure:latest, quay.io/odpi/egeria-configure:${{ env.VERSION }}, quay.io/odpi/egeria-configure:latest
          context: ./open-metadata-resources/open-metadata-deployment/docker/configure
          platforms: linux/amd64,linux/arm64
      # --
      # Publish container images(egeria-configure) to quay.io and docker.io
      - name: Build and push(egeria-configure) to quay.io and docker.io (no tag latest)
        if: ${{ github.ref != 'refs/heads/main'}}
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: odpi/egeria-configure:${{ env.VERSION }}, quay.io/odpi/egeria-configure:${{ env.VERSION }}
          context: ./open-metadata-resources/open-metadata-deployment/docker/configure
          platforms: linux/amd64,linux/arm64
      # --
      - name: Upload Log of any dependency failures
        uses: actions/upload-artifact@v4.3.1
        with:
          name: Dependency Analysis Report (on failure)
          path: build/reports/dependency-analysis/build-health-report.txt
          if-no-files-found: ignore
      # Mostly for verification - not published to the release itself for now
      - name: Upload assemblies
        uses: actions/upload-artifact@v4.3.1
        with:
          name: Assemblies
          path: open-metadata-distribution/omag-server-platform/build/distributions/*.gz
      - name: Upload Test coverage report
        uses: actions/upload-artifact@v4.3.1
        with:
          name: Jacoco Coverage Report
          path: build/reports/jacoco/codeCoverageReport
          if-no-files-found: ignore


Release v5

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
---
name: "Release v5"

# Trigger when a Release is created in github
# - does not run on modification (may be just text)

on:
  # No checks for branch or repo - assuming release creation is manual, controlled
  release:
    types:
      - created
    branches: [main, egeria-release-5*]

  workflow_dispatch:

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    name: "Release"
    if: startsWith(github.repository,'odpi/')
    steps:
      - uses: actions/checkout@v4.1.0
        name: Checkout source
      - uses: gradle/wrapper-validation-action@v2
      # Prep for docker builds
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to container registry (Quay.io)
        uses: docker/login-action@v3
        with:
          registry: quay.io
          username: ${{ secrets.QUAY_IO_USERNAME }}
          password: ${{ secrets.QUAY_IO_ACCESS_TOKEN }}
      - name: Login to container registry (docker.io)
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: build and publish to maven central
        uses: gradle/gradle-build-action@v3
        with:
          cache-read-only: false
          arguments: build publish -Dorg.gradle.parallel=false -Dorg.gradle.caching=false
        # Import secrets needed for code signing and distribution
        env:
          OSSRH_GPG_KEYID: ${{ secrets.OSSRH_GPG_KEYID }}
          OSSRH_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }}
          OSSRH_GPG_PRIVATE_KEY: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }}
          ORG_GRADLE_PROJECT_mavenRepoUrl: https://oss.sonatype.org/service/local/staging/deploy/maven2
          ORG_GRADLE_PROJECT_mavenRepoPass: ${{ secrets.OSSRH_TOKEN }}
          ORG_GRADLE_PROJECT_mavenRepoUser: ${{ secrets.OSSRH_USERNAME }}
      # QEMU is needed for ARM64 build for egeria-configure
      # egeria-configure needs to install utilities
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set Release version env variable
        run: |
          echo "VERSION=$(./gradlew properties --no-daemon --console=plain -q | grep '^version:' | awk '{printf $2}')" >> $GITHUB_ENV
      # Publish container images(egeria-platform) to quay.io and docker.io
      - name: Copy the distribution content to be used in docker copy command
        run: |
          cp -f container.application.properties ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform/application.properties
          mkdir -p ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform/data/servers
          cp -r ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/opt/sample-configs/*-* ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform/data/servers
          cp -r ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/opt/sample-data ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform
          cp -r ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/opt/coco-pharmaceuticals ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz/assembly/platform
      - name: Build and push(egeria-platform) to quay.io and docker.io
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: odpi/egeria-platform:${{ env.VERSION }}, odpi/egeria-platform:stable, quay.io/odpi/egeria-platform:${{ env.VERSION }}, quay.io/odpi/egeria-platform:stable
          context: ./open-metadata-distribution/omag-server-platform/build/unpacked/egeria-platform-${{ env.VERSION }}-distribution.tar.gz
          platforms: linux/amd64,linux/arm64
      # Publish container images(egeria-configure) to quay.io and docker.io
      - name: Build and push(egeria-configure) to quay.io and docker.io
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: odpi/egeria-configure:${{ env.VERSION }}, odpi/egeria-configure:stable, quay.io/odpi/egeria-configure:${{ env.VERSION }}, quay.io/odpi/egeria-configure:stable
          context: ./open-metadata-resources/open-metadata-deployment/docker/configure
          platforms: linux/amd64,linux/arm64
      # Mostly for verification - not published to the release itself for now
      - name: Upload assemblies
        uses: actions/upload-artifact@v4.3.1
        with:
          name: Assemblies
          path: open-metadata-distribution/omag-server-platform/build/distributions/*.gz


C Platform compatibility

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: "C Platform compatibility"

on:
  push:
    branches: [ "develop", "plc4c" ]
    paths:
      - code-generation/**
      - protocols/**
      - plc4c**
  pull_request:
    paths:
      - code-generation/**
      - protocols/**
      - plc4c**
  workflow_dispatch:
    inputs:
      forceUpdates:
        description: "Forces a snapshot update"
        required: false
        default: 'false'

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  test:
    strategy:
      matrix:
        # 8 not anymore supported for building
        java: [ 17 ]
        os: [ ubuntu-latest, macos-latest, windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - name: Install libpcap for Linux
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get install libpcap-dev

      - name: Install libpcap for macos
        if: matrix.os == 'macos-latest'
        run: brew install libpcap

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-package: jdk
          java-version: ${{ matrix.java }}

      - name: Cache local Maven repository
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-

      - name: Set Platform options
        id: platform_opts
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_opts', ``)
            } else if (OS.includes("macos")) {
              core.setOutput('platform_opts', `-Djna.library.path="$(find /usr/local/Cellar/libpcap/ -name lib)"`)
            } else if (OS.includes("ubuntu")) {
              core.setOutput('platform_opts', ``)
            } else {
              core.setOutput('platform_opts', ``)
            }

      - name: Calculate platform suffix
        id: platform_suffix
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_suffix', `.cmd`)
            } else {
              core.setOutput('platform_suffix', ``)
            }

      - name: Set extra options
        id: extra_options
        uses: actions/github-script@v7.0.1
        env:
          FORCE_UPDATE: ${{ github.event.inputs.forceUpdates }}
        with:
          script: |
            const { FORCE_UPDATE } = process.env
            if (FORCE_UPDATE.includes("true")) {
              core.setOutput('extra_options', `-U`)
            } else {
              core.setOutput('extra_options', ``)
            }

      # Note: due to github has no concept of recovering from a fail even if we have our fallback below we append a second un-parallel run behind this to be sure that it works with all checks. Only if that fails too we are ok with a "red" (which should be yellow) cross indicating a problem
      - name: Run mvnw
        run: |
          ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-c,enable-all-checks,update-generated-code' -pl :plc4c -am ${{ steps.platform_opts.outputs.platform_opts }} install

      - name: Run mvnv without BacNet regression tests
        if: ${{ failure() }}
        run: ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-c,skip-bacnet-regression-test,update-generated-code' -pl :plc4c -am ${{ steps.platform_opts.outputs.platform_opts }} install


Generate changelog

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: 'Generate changelog'
on:
  release:
    types: [created, edited]

jobs:
  generate-changelog:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: BobAnkh/auto-generate-changelog@v1.2.5
        with:
          ACCESS_TOKEN: ${{secrets.GITHUB_TOKEN}}
          TYPE: 'feat:Feature,fix:Bug Fixes,docs:Documentation,refactor:Refactor,perf:Performance Improvements'
          PATH: 'CHANGELOG.md'


CodeQL

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: "CodeQL"

on:
  schedule:
    - cron: '17 19 * * 3'

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        ## cpp and csharp not ready yet
        #language: [ 'cpp', 'csharp', 'go', 'java', 'python' ]
        language: [ 'go', 'java', 'python' ]

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v3

    # ℹ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3


Dependency Review

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------

# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
on: [pull_request]

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

permissions:
  contents: read

jobs:
  dependency-review:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout Repository'
        uses: actions/checkout@v4
      - name: 'Dependency Review'
        uses: actions/dependency-review-action@v4


Go Platform Test Report

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: 'Go Platform Test Report'

on:
  workflow_run:
    workflows: [ 'Go Platform compatibility' ]
    types:
      - completed

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  report:
    strategy:
      matrix:
        # 8 not anymore supported for building
        java: [ 17 ]
        os: [ ubuntu-latest, macos-latest, windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: dorny/test-reporter@v1
        with:
          artifact: "golang-test-report-${{ matrix.os }}"
          name: "Golang Tests (OS: ${{ matrix.os }})"
          path: '**/*.xml'
          reporter: java-junit


Go Platform compatibility

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: "Go Platform compatibility"

on:
  push:
    branches: [ "develop", "plc4go" ]
    paths:
      - code-generation/**
      - protocols/**
      - plc4go**
  pull_request:
    paths:
      - code-generation/**
      - protocols/**
      - plc4go**
  workflow_dispatch:
    inputs:
      forceUpdates:
        description: "Forces a snapshot update"
        required: false
        default: 'false'
      highLogPrecision:
        description: "sets the logs to nano resolution"
        required: false
        default: 'false'
      passLoggerToModel:
        description: "passes the logger to the model"
        required: false
        default: 'false'
      receiveTimeout:
        description: "sets the receive timeout to milliseconds"
        required: false
        default: '600000'
      traceTransactionManagerWorkers:
        description: "sets tracing for transaction manager workers"
        required: false
        default: 'false'
      traceTransactionManagerTransactions:
        description: "sets tracing for transaction manager transactions"
        required: false
        default: 'false'
      traceDefaultMessageCodecWorker:
        description: "sets tracing for the default message codec worker"
        required: false
        default: 'false'
      traceExecutorWorkers:
        description: "sets tracing for executor workers"
        required: false
        default: 'false'
      traceTestTransportInstance:
        description: "sets tracing for test transport instance"
        required: false
        default: 'false'

env:
  PLC4X_TEST_HIGH_TEST_LOG_PRECISION: ${{ github.event.inputs.highLogPrecision }}
  PLC4X_TEST_PASS_LOGGER_TO_MODEL: ${{ github.event.inputs.passLoggerToModel }}
  PLC4X_TEST_RECEIVE_TIMEOUT_MS: ${{ github.event.inputs.receiveTimeout }}
  PLC4X_TEST_TRACE_TRANSACTION_MANAGER_WORKERS: ${{ github.event.inputs.traceTransactionManagerWorkers }}
  PLC4X_TEST_TRACE_TRANSACTION_MANAGER_TRANSACTIONS: ${{ github.event.inputs.traceTransactionManagerTransactions }}
  PLC4X_TEST_TRACE_DEFAULT_MESSAGE_CODEC_WORKER: ${{ github.event.inputs.traceDefaultMessageCodecWorker }}
  PLC4X_TEST_TRACE_EXECUTOR_WORKERS: ${{ github.event.inputs.traceExecutorWorkers }}
  PLC4X_TEST_TEST_TRANSPORT_INSTANCE: ${{ github.event.inputs.traceTestTransportInstance }}
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  test:
    strategy:
      matrix:
        # 8 not anymore supported for building
        java: [ 17 ]
        os: [ ubuntu-latest, macos-latest, windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - name: Install libpcap for Linux
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get install libpcap-dev

      - name: Install libpcap for macos
        if: matrix.os == 'macos-latest'
        run: brew install libpcap

      - name: Install libpcap for windows
        if: matrix.os == 'windows-latest'
        run: choco install -y nmap

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-package: jdk
          java-version: ${{ matrix.java }}

      - name: Cache local Maven repository
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-

      - name: Set Platform options
        id: platform_opts
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_opts', ``)
            } else if (OS.includes("macos")) {
              core.setOutput('platform_opts', `-Djna.library.path="$(find /usr/local/Cellar/libpcap/ -name lib)"`)
            } else if (OS.includes("ubuntu")) {
              core.setOutput('platform_opts', ``)
            } else {
              core.setOutput('platform_opts', ``)
            }

      - name: Calculate platform suffix
        id: platform_suffix
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_suffix', `.cmd`)
            } else {
              core.setOutput('platform_suffix', ``)
            }

      - name: Set extra options
        id: extra_options
        uses: actions/github-script@v7.0.1
        env:
          FORCE_UPDATE: ${{ github.event.inputs.forceUpdates }}
        with:
          script: |
            const { FORCE_UPDATE } = process.env
            if (FORCE_UPDATE.includes("true")) {
              core.setOutput('extra_options', `-U`)
            } else {
              core.setOutput('extra_options', ``)
            }

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: go

      - name: Check LongPathsEnabled on Windows
        if: matrix.os == 'windows-latest'
        run: |
          (Get-ItemProperty "HKLM:System\CurrentControlSet\Control\FileSystem").LongPathsEnabled

      # Note: due to github has no concept of recovering from a fail even if we have our fallback below we append a second un-parallel run behind this to be sure that it works with all checks. Only if that fails too we are ok with a "red" (which should be yellow) cross indicating a problem
      - name: Run mvnw
        run: |
          ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-go,enable-all-checks,update-generated-code' -pl :plc4go -am ${{ steps.platform_opts.outputs.platform_opts }} install

      - name: Upload Test Report (first failure)
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: "golang-test-report-first-failure-${{ matrix.os }}"
          path: |
            **/surefire-reports/go-junit-report.xml
            **/reports/test-out-verbose.log

      - name: Run mvnv without BacNet regression tests
        if: ${{ failure() }}
        run: ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-go,skip-bacnet-regression-test,update-generated-code' -pl :plc4go -am ${{ steps.platform_opts.outputs.platform_opts }} install

      - name: Upload Test Report
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: "golang-test-report-${{ matrix.os }}"
          path: |
            **/surefire-reports/go-junit-report.xml
            **/reports/test-out-verbose.log

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3


Java Platform Test Report

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: 'Java Platform Test Report'

on:
  workflow_run:
    workflows: [ 'Java Platform compatibility' ]
    types:
      - completed

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  report:
    strategy:
      matrix:
        java: [ 11, 17, 21 ]
        # TODO: only works on windows due to https://github.com/dorny/test-reporter/issues/249
        #os: [ ubuntu-latest, macos-latest, windows-latest ]
        os: [ windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: dorny/test-reporter@v1
        with:
          artifact: "java-test-report-${{ matrix.os }}-java-${{ matrix.java }}"
          name: "Java Tests (OS: ${{ matrix.os }}, Java: ${{ matrix.java }})"
          path: '**/*.xml'
          reporter: java-junit


Java Platform compatibility

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: "Java Platform compatibility"

on:
  push:
    branches: [ "develop", "plc4j" ]
    paths:
      - code-generation/**
      - protocols/**
      - plc4j**
      - pom.xml
  pull_request:
    paths:
      - code-generation/**
      - protocols/**
      - plc4j**
      - pom.xml
  workflow_dispatch:
    inputs:
      forceUpdates:
        description: "Forces a snapshot update"
        required: false
        default: 'false'

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  test:
    strategy:
      matrix:
        # 8 not anymore supported for building
        java: [ 11, 17, 21 ]
        os: [ ubuntu-latest, macos-latest, windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - name: Install libpcap for Linux
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get install libpcap-dev

      - name: Install libpcap for macos
        if: matrix.os == 'macos-latest'
        run: brew install libpcap

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-package: jdk
          java-version: ${{ matrix.java }}

      - name: Cache local Maven repository
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-

      - name: Set Platform options
        id: platform_opts
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_opts', ``)
            } else if (OS.includes("macos")) {
              core.setOutput('platform_opts', `-Djna.library.path="$(find /usr/local/Cellar/libpcap/ -name lib)"`)
            } else if (OS.includes("ubuntu")) {
              core.setOutput('platform_opts', ``)
            } else {
              core.setOutput('platform_opts', ``)
            }

      - name: Calculate platform suffix
        id: platform_suffix
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_suffix', `.cmd`)
            } else {
              core.setOutput('platform_suffix', ``)
            }

      - name: Set extra options
        id: extra_options
        uses: actions/github-script@v7.0.1
        env:
          FORCE_UPDATE: ${{ github.event.inputs.forceUpdates }}
        with:
          script: |
            const { FORCE_UPDATE } = process.env
            if (FORCE_UPDATE.includes("true")) {
              core.setOutput('extra_options', `-U`)
            } else {
              core.setOutput('extra_options', ``)
            }

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: java

      # Note: due to github has no concept of recovering from a fail even if we have our fallback below we append a second un-parallel run behind this to be sure that it works with all checks. Only if that fails too we are ok with a "red" (which should be yellow) cross indicating a problem
      - name: Run mvnw
        run: |
          ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-java,enable-all-checks,update-generated-code' ${{ steps.platform_opts.outputs.platform_opts }} install

      - name: Upload Test Report (first failure)
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: "java-test-report-first-failure-${{ matrix.os }}-java-${{ matrix.java }}"
          path: |
            **/surefire-reports/TEST-*.xml
            **/failsafe-reports/TEST-*.xml

      - name: Run mvnv without BacNet regression tests
        if: ${{ failure() }}
        run: ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-java,skip-bacnet-regression-test,update-generated-code' ${{ steps.platform_opts.outputs.platform_opts }} install

      - name: Upload Test Report
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: "java-test-report-${{ matrix.os }}-java-${{ matrix.java }}"
          path: |
            **/surefire-reports/TEST-*.xml
            **/failsafe-reports/TEST-*.xml

#      - name: Perform CodeQL Analysis
#        uses: github/codeql-action/analyze@v3


Python Platform Compatibility

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: "Python Platform Compatibility"

on:
  push:
    branches: [ "develop", "plc4py" ]
    paths:
      - code-generation/**
      - protocols/**
      - plc4py**
  pull_request:
    branches: [ "develop", "plc4py" ]
    paths:
      - code-generation/**
      - protocols/**
      - plc4py**
  workflow_dispatch:
    inputs:
      forceUpdates:
        description: "Forces a snapshot update"
        required: false
        default: 'false'

permissions:
  contents: read

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  test:
    strategy:
      matrix:
        python-version: ['3.10', '3.11', '3.12']
        os: [ ubuntu-latest, macos-latest, windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - name: Install libpcap for Linux
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get install libpcap-dev

      - name: Install libpcap for macos
        if: matrix.os == 'macos-latest'
        run: brew install libpcap

      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '${{ matrix.python-version }}'

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-package: jdk
          java-version: 17

      - name: Set Platform options
        id: platform_opts
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_opts', ``)
            } else if (OS.includes("macos")) {
              core.setOutput('platform_opts', `-Djna.library.path="$(find /usr/local/Cellar/libpcap/ -name lib)"`)
            } else if (OS.includes("ubuntu")) {
              core.setOutput('platform_opts', ``)
            } else {
              core.setOutput('platform_opts', ``)
            }

      - name: Calculate platform suffix
        id: platform_suffix
        uses: actions/github-script@v7.0.1
        env:
          OS: ${{ matrix.os }}
        with:
          script: |
            const { OS } = process.env
            if (OS.includes("windows")) {
              core.setOutput('platform_suffix', `.cmd`)
            } else {
              core.setOutput('platform_suffix', ``)
            }

      - name: Set extra options
        id: extra_options
        uses: actions/github-script@v7.0.1
        env:
          FORCE_UPDATE: ${{ github.event.inputs.forceUpdates }}
        with:
          script: |
            const { FORCE_UPDATE } = process.env
            if (FORCE_UPDATE.includes("true")) {
              core.setOutput('extra_options', `-U`)
            } else {
              core.setOutput('extra_options', ``)
            }

      - name: Cache local Maven repository
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest

#      - name: Lint with flake8
#        run: |
#          # stop the build if there are Python syntax errors or undefined names
#          flake8 ./plc4py --count --select=E9,F63,F7,F82 --show-source --statistics
#          # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
#          flake8 ./plc4py --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

#      - name: Initialize CodeQL
#        uses: github/codeql-action/init@v2
#        with:
#          languages: python

      - name: Run mvnw
        run: |
          ./mvnw${{ steps.platform_suffix.outputs.platform_suffix }} ${{ steps.extra_options.outputs.extra_options }} -B -P'with-python,enable-all-checks,update-generated-code' -pl :plc4py -am ${{ steps.platform_opts.outputs.platform_opts }} install

#      - name: Perform CodeQL Analysis
#        uses: github/codeql-action/analyze@v2


Release Drafter

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: Release Drafter

on:
  push:
    branches:
      - develop
  # pull_request event is required only for autolabeler
  pull_request:
    # Only following types are handled by the action, but one can default to all as well
    types: [opened, reopened, synchronize]
  # pull_request_target event is required for autolabeler to support PRs from forks
  # pull_request_target:
  #   types: [opened, reopened, synchronize]

permissions:
  contents: read

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  update_release_draft:
    permissions:
      # write permission is required to create a github release
      contents: write
      # write permission is required for autolabeler
      # otherwise, read permission is required at least
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      # (Optional) GitHub Enterprise requires GHE_HOST variable set
      #- name: Set GHE_HOST
      #  run: |
      #    echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV

      # Drafts your next Release notes as Pull Requests are merged into "master"
      - uses: release-drafter/release-drafter@v6
        # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
        # with:
        #   config-name: my-config.yml
        #   disable-autolabeler: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Static Application Security Testing

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
name: Static Application Security Testing

on:
  push:
    branches:
      - develop
  pull_request:

env:
  GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }}

jobs:
  build:
    name: Trivy Scan
    runs-on: ubuntu-latest
    # Disabling this, as it keeps on randomly failing the build without providing any information helping to fix it.
    if: false
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Run Trivy vulnerability scanner in repo mode
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          ignore-unfixed: true
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL'

      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'


CodeQL

name: "CodeQL"

on:
  push:
    branches: [ 'master' ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ 'master' ]
  schedule:
    - cron: '24 4 * * *'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'java', 'javascript', 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set Java version
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '21'

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.

        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        queries: security-and-quality

    # Build with Gradle
    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@v3
      with:
        build-scan-publish: true
        build-scan-terms-of-service-url: "https://gradle.com/terms-of-service"
        build-scan-terms-of-service-agree: "yes"
    - name: Execute Gradle build
      run: ./gradlew build -x test -x jIFC

    # Autobuild attempts to build any compiled languages  (C/C++, C#, Go, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    #- name: Autobuild
    #  uses: github/codeql-action/autobuild@v3

    # ℹ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

    #   If the Autobuild fails above, remove it and uncomment the following three lines.
    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

    # - run: |
    #   echo "Run, Build Application using script"
    #   ./location_of_script_within_repo/buildscript.sh

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"


Dependency Submission

name: Dependency Submission

on:
  push:
    branches: [ 'master' ]
  schedule:
    - cron: '24 3 * * *'

permissions:
  contents: write

jobs:

  dependency-submission:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout sources
      uses: actions/checkout@v4
    - name: Set Java version
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '21'
    - name: Generate and submit dependency graph
      uses: gradle/actions/dependency-submission@v3


Check labels

name: "Check labels"

on:
  pull_request:
    branches: ["master"]
    types:
      - opened
      - synchronize
      - labeled
      - unlabeled
  merge_group:
    branches: ["master"]
    types: [checks_requested]

jobs:
  fail-by-label:
    runs-on: ubuntu-latest
    steps:
      - name: Fail if PR is labeled as "do not merge"
        if: contains(github.event.pull_request.labels.*.name, 'do not merge')
        run: |
          echo "This PR is labeled as do not merge!"
          exit 1


Closed Issue Message

name: Closed Issue Message
on:
    issues:
       types: [closed]
jobs:
    auto_comment:
        if: github.repository == 'aws/aws-sdk-java-v2'
        runs-on: ubuntu-latest
        permissions:
          issues: write
        steps:
        - uses: aws-actions/closed-issue-message@v1
          with:
            # These inputs are both required
            repo-token: "${{ secrets.GITHUB_TOKEN }}"
            message: |
              This issue is now closed. Comments on closed issues are hard for our team to see.
              If you need more assistance, please open a new issue that references this one.


AWS CodeBuild CI

name: AWS CodeBuild CI
on:
  pull_request:
  push:
    branches:
      - master
    paths-ignore:
      - '**.md'
      - '.all-contributorsrc'
      - 'docs/**'

permissions:
  id-token: write

jobs:
  jdk8-build:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run JDK8 build
        uses: aws-actions/aws-codebuild-run-build@v1
        timeout-minutes: 120
        with:
          project-name: aws-sdk-java-v2
  jdk11-build:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run JDK11 build
        uses: aws-actions/aws-codebuild-run-build@v1
        timeout-minutes: 120
        with:
          project-name: aws-sdk-java-v2-JDK11
  jdk17-build:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run JDK17 build
        uses: aws-actions/aws-codebuild-run-build@v1
        timeout-minutes: 120
        with:
          project-name: aws-sdk-java-v2-JDK17
  jdk21-build:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run JDK21 build
        uses: aws-actions/aws-codebuild-run-build@v1
        timeout-minutes: 120
        with:
          project-name: aws-java-sdk-v2-JDK21
  windows-jdk8-build:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run JDK8 windows build
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: aws-sdk-java-v2-JDK8-windows
  native-image-test:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run native image test
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: aws-sdk-java-v2-native-image-test
  sonar-cloud-build:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run sonar-cloud analysis
        uses: aws-actions/aws-codebuild-run-build@v1
        timeout-minutes: 120
        with:
          project-name: aws-sdk-java-v2-sonar
          env-vars-for-codebuild: |
            PR,
            BRANCH,
            BASE
        env:
          PR: ${{ github.event.number }}
          BRANCH: ${{ github.head_ref || 'master'}}
          BASE: ${{ github.base_ref }}
  endpoints-tests:
    if: github.repository == 'aws/aws-sdk-java-v2'
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }}
          aws-region: us-west-2
          role-duration-seconds: 7200
      - name: Run endpoints test
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: aws-sdk-java-v2-endpoints-test


HandleStaleDiscussions

name: HandleStaleDiscussions
on:
  schedule:
    - cron: '0 */4 * * *'
  discussion_comment:
    types: [created]

jobs:
  handle-stale-discussions:
    if: github.repository == 'aws/aws-sdk-java-v2'
    name: Handle stale discussions
    runs-on: ubuntu-latest
    permissions:
      discussions: write
    steps:
      - name: Stale discussions action
        uses: aws-github-ops/handle-stale-discussions@v1
        with:
          close-stale-as-answered: false
          close-answered-discussion: false
        env:
          GITHUB_TOKEN:  ${{secrets.GITHUB_TOKEN}}


Close stale issues

name: "Close stale issues"

# Controls when the action will run.
on:
  schedule:
  - cron: "0 0/3 * * *"

jobs:
  cleanup:
    if: github.repository == 'aws/aws-sdk-java-v2'
    name: Stale issue job
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
    steps:
    - uses: aws-actions/stale-issue-cleanup@v4
      with:
        # Setting messages to an empty string will cause the automation to skip
        # that category
        ancient-issue-message: This is a very old issue that is probably not getting as much
          attention as it deserves. We encourage you to check if this is still an issue in
          the latest release and if you find that this is still a problem, please feel free
          to provide a comment or open a new issue.
        stale-issue-message: It looks like this issue has not been active for more than five days.
          In the absence of more information, we will be closing this issue soon. If you find
          that this is still a problem, please add a comment to prevent automatic closure, or
          if the issue is already closed please feel free to reopen it.
        stale-pr-message: It looks like this PR has not been active for more than five days. In
          the absence of more information, we will be closing this PR soon. Please add a
          comment to prevent automatic closure, or if the PR is already closed please feel
          free to open a new one.

        # These labels are required
        stale-issue-label: closing-soon
        exempt-issue-labels: no-auto-closure, help wanted
        stale-pr-label: closing-soon
        exempt-pr-labels: no-auto-closure
        response-requested-label: response-requested

        # Don't set closed-for-staleness label to skip closing very old issues
        # regardless of label
        closed-for-staleness-label: closed-for-staleness

        # Issue timing
        days-before-stale: 10
        days-before-close: 4
        days-before-ancient: 36500

        # If you don't want to mark a issue as being ancient based on a
        # threshold of "upvotes", you can set this here. An "upvote" is
        # the total number of +1, heart, hooray, and rocket reactions
        # on an issue.
        minimum-upvotes-to-exempt: 1

        repo-token: ${{ secrets.GITHUB_TOKEN }}
        loglevel: DEBUG
        # Set dry-run to true to not perform label or close actions.
        #dry-run: true


on: [push, pull_request]

jobs:
  check_java_latest:
    runs-on: ubuntu-latest
    name: Java 17

    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'

      - name: Gradle cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-jdk17-${{ hashFiles('**/*.gradle*') }}
          restore-keys: |
            ${{ runner.os }}-gradle-jdk17

      - name: Compile with Gradle
        run: ./gradlew assemble

      - name: Slack Notification
        uses: 8398a7/action-slack@v3
        if: always() && env.SLACK_WEBHOOK_URL
        with:
          status: custom
          job_name: Java 17
          author_name: Java 17 Build
          fields: workflow,commit,repo,author,took
          # see https://action-slack.netlify.app/usecase/02-custom for custom payload info
          custom_payload: |
            {
              attachments: [{
                color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
                text: `${process.env.AS_WORKFLOW} -- (${process.env.AS_COMMIT}) of ${process.env.AS_REPO}@${{ github.head_ref || github.ref }} by ${process.env.AS_AUTHOR} ${{ job.status }} in ${process.env.AS_TOOK}`,
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  check_java11:
    runs-on: ubuntu-latest
    name: Java 11

    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: 11
          distribution: 'zulu'

      - name: Gradle cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-jdk11-${{ hashFiles('**/*.gradle*') }}
          restore-keys: |
            ${{ runner.os }}-gradle-jdk11

      - name: Compile with Gradle
        run: ./gradlew assemble

      - name: Test
        run: ./gradlew check

      - name: Code coverage
        uses: codecov/codecov-action@v3

      - name: Slack Notification
        uses: 8398a7/action-slack@v3
        if: always() && env.SLACK_WEBHOOK_URL
        with:
          status: custom
          job_name: Java 11
          author_name: Java 11 Build/Test
          fields: workflow,commit,repo,author,took
          # see https://action-slack.netlify.app/usecase/02-custom for custom payload info
          custom_payload: |
            {
              attachments: [{
                color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
                text: `${process.env.AS_WORKFLOW} -- (${process.env.AS_COMMIT}) of ${process.env.AS_REPO}@${{ github.head_ref || github.ref }} by ${process.env.AS_AUTHOR} ${{ job.status }} in ${process.env.AS_TOOK}`,
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}


on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: 11
          distribution: 'zulu'

      - name: Gradle cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-jdk11-${{ hashFiles('**/*.gradle*') }}
          restore-keys: |
            ${{ runner.os }}-gradle-jdk11

      - name: Create Artifacts
        run: |
          ./generate_samples.sh
          # delete uncompressed output, sample zips are in ./samples/
          rm -rf output/
          ./gradlew uberJar javadoc graphviz
          mkdir -p output/build/javadoc
          mv build/docs/javadoc/* output/build/javadoc

      - name: Delete Previous master-branch-latest Tag
        uses: dev-drprasad/delete-tag-and-release@v0.2.1
        with:
          delete_release: true
          tag_name: master-branch-latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Create Release
        id: create_release
        # note id is referenced below in Deploy uberJar
        uses: ncipollo/release-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          tag: master-branch-latest
          draft: false
          prerelease: true

      - name: Deploy UberJar
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          # This pulls from the CREATE RELEASE step above, referencing its ID to get its outputs object, which include a `upload_url`
          asset_path: build/libs/synthea-with-dependencies.jar
          asset_name: synthea-with-dependencies.jar
          asset_content_type: application/java-archive

        # it's necessary to add another "publish" after the upload, otherwise the release is always listed as "draft"
        # see https://github.com/actions/upload-release-asset/issues/34
      - name: Publish Release
        uses: ncipollo/release-action@v1
        with:
          allowUpdates: true
          omitBodyDuringUpdate: true
          replacesArtifacts: false
          tag: master-branch-latest
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Deploy to gh-pages
        uses: peaceiris/actions-gh-pages@v3
        # note: watch for v4 to be released
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          keep_files: true
          # do not create a .nojekyll file
          enable_jekyll: true
          publish_dir: ./output
          user_name: 'Jason Walonoski'
          user_email: 'jwalonoski@mitre.org'
          commit_message: rebuild graphs, javadoc and binary distribution at
          # note the commit SHA is appended automatically

      - name: Push samples to sample repo
        uses: cpina/github-action-push-to-another-repository@main
        env:
          SSH_DEPLOY_KEY: ${{ secrets.PUSH_SAMPLE_DATA_SSH_KEY }}
        with:
          source-directory: 'samples'
          destination-github-username: 'synthetichealth'
          destination-repository-name: 'synthea-sample-data'
          target-directory: 'downloads/latest'
          target-branch: main

      - name: Slack Notification on Failure
        uses: 8398a7/action-slack@v3
        if: failure()
        with:
          status: custom
          job_name: Deploy
          author_name: Deploy Workflow
          fields: workflow,commit,repo,author,took
          # see https://action-slack.netlify.app/usecase/02-custom for custom payload info
          custom_payload: |
            {
              attachments: [{
                color: 'danger',
                text: `${process.env.AS_WORKFLOW} -- (${process.env.AS_COMMIT}) of ${process.env.AS_REPO}@master by ${process.env.AS_AUTHOR} ${{ job.status }} in ${process.env.AS_TOOK}`,
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}


Issue labeler

---

name: Issue labeler
on:
  issues:
    types: [ opened ]

jobs:
  label-issues-policy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      issues: write

    strategy:
      matrix:
        template: [ bug_report.yml, feature_request.yml ]

    steps:
      - uses: actions/checkout@v3

      - name: Parse issue form
        uses: stefanbuck/github-issue-parser@c1a559d78bfb8dd05216dab9ffd2b91082ff5324  # v3.0.1
        id: issue-parser
        with:
          template-path: .github/ISSUE_TEMPLATE/${{ matrix.template }}

      - name: Set labels based on policy
        uses: redhat-plumbers-in-action/advanced-issue-labeler@6ee6fddfd744ee26b977e6a0436916f256896971  # v2.0.3
        with:
          issue-form: ${{ steps.issue-parser.outputs.jsonString }}
          template: ${{ matrix.template }}
          token: ${{ secrets.GITHUB_TOKEN }}


Auto Add Labels and Assignees

name: Auto Add Labels and Assignees
on:
  pull_request_target:
    types: ["opened", "reopened", "ready_for_review"]

jobs:
  add_label:
    permissions:
      contents: read
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
    - uses: actions/labeler@v4
    if: ${{ github.event.pull_request.draft == false }}
  add_assignee:
    runs-on: ubuntu-latest
    needs: add_label
    permissions:
      contents: read
      pull-requests: write
    steps:
      - name: Check out code
        uses: actions/checkout@v2
      - name: Set Assignees
        uses: actions/github-script@v4
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            let issue_number = context.payload.pull_request.number;
            let issueDetails =  await github.issues.get({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number,
               });
            let labels = issueDetails.data.labels
            const assignees = [];
            const labelsToAssignees = {
              'product: CLion': ['tpasternak'],
              'product: IntelliJ': ['mai93'],
              'product: GoLand': ['blorente'],
              'product: Android Studio': ['mai93']
            };
            for (const label of labels) {
              if (label.name in labelsToAssignees) {
                assignees.push(...labelsToAssignees[label.name]);
              }
            }
            if (assignees.length > 0) {
              await github.issues.addAssignees({
                issue_number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                assignees
              });
            }