Publish Release

# This workflow publishes commits to Maven
name: Publish Release

on:
  workflow_dispatch:
    inputs:
      channel:
        description: 'Release channel'
        required: true
        type: string
      type:
        description: 'Release type'
        required: true
        default: 'beta'
        type: string

jobs:
  build:
    name: Build and Publish
    runs-on: ubuntu-latest
    environment: prod

    steps:
      - name: Checkout git repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Resolve release type
        id: release_type
        run: |
          case $release_type in
            "release")
              publish_maven=true
              publish_curse=true
              publish_gh_release=true
              version_format="{major}.{minor}.{patch}"
              ;;
            "beta")
              publish_maven=true
              publish_curse=true
              publish_gh_release=false
              version_format="{major}.{minor}.{patch}-beta+{increment}"
              ;;
            "alpha")
              publish_maven=true
              publish_curse=false
              publish_gh_release=false
              version_format="{major}.{minor}.{patch}-alpha+{increment}"
              ;;
            *)
              echo "::warning::Unknown release type: $release_type"
              publish_maven=false
              publish_curse=false
              publish_gh_release=false
              version_format="{major}.{minor}.{patch}-$release_type+{increment}"
          esac

          tag_format="v$release_channel-{major}.{minor}.{patch}"

          echo "release_channel=$release_channel" >> $GITHUB_OUTPUT
          echo "release_type=$release_type" >> $GITHUB_OUTPUT
          echo "publish_maven=$publish_maven" >> $GITHUB_OUTPUT
          echo "publish_curse=$publish_curse" >> $GITHUB_OUTPUT
          echo "publish_gh_release=$publish_gh_release" >> $GITHUB_OUTPUT
          echo "version_format=$version_format" >> $GITHUB_OUTPUT
          echo "tag_format=$tag_format" >> $GITHUB_OUTPUT
        env:
          release_channel: ${{ inputs.channel }}
          release_type: ${{ inputs.type }}

      # Install python and deps
      - name: Set up Python 3.12.1
        uses: actions/setup-python@v4
        with:
          python-version: 3.12.1
      - name: Cache PIP packages
        uses: actions/cache@v3
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('.github/requirements.txt') }}
      - name: Install python deps
        run: |
          python -m pip install --upgrade pip
          python -m pip install -r .github/requirements.txt

      - name: Generate version
        id: versioning
        run: |
          version=$(python .github/git_utils.py genVersion --format_str="${{ steps.release_type.outputs.version_format }}")
          version_tag=$(python .github/git_utils.py genVersion --format_str="${{ steps.release_type.outputs.tag_format }}")
          echo "version=$version"
          echo "version_tag=$version_tag"
          echo "version=$version" >> $GITHUB_OUTPUT
          echo "version_tag=$version_tag" >> $GITHUB_OUTPUT

      - name: Generate changelogs
        run: |
          python .github/git_utils.py genChangelogRaw
          python .github/git_utils.py genChangelogMd --next_tag=${{ steps.versioning.outputs.version_tag }}

      # Install JDK and build with Gradle
      - name: Set up JDK 1.8
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: '8'

      - name: Cache Gradle packages
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle2-${{ hashFiles('**/build.gradle', '**/build.properties', '**/gradle.properties', '**/gradle-wrapper.properties') }}

      - name: Build
        run: ./gradlew build
        env:
          AUTO_GENERATED_VERSION: ${{ steps.versioning.outputs.version }}

      - name: Maven publish
        if: ${{ steps.release_type.outputs.publish_maven == 'true' }}
        run: ./gradlew publish
        env:
          AUTO_GENERATED_VERSION: ${{ steps.versioning.outputs.version }}
          MAVEN_USER: ${{ secrets.MAVEN_USER }}
          MAVEN_PASS: ${{ secrets.MAVEN_PASS }}

      - name: Curse publish
        if: ${{ steps.release_type.outputs.publish_curse == 'true' }}
        run: ./gradlew curseforge
        env:
          AUTO_GENERATED_VERSION: ${{ steps.versioning.outputs.version }}
          CURSE_RELEASE_TYPE: ${{ steps.release_type.outputs.release_type }}
          CURSE_TOKEN: ${{ secrets.CURSE_TOKEN }}

      - name: Tag and Release
        if: ${{ steps.release_type.outputs.publish_gh_release == 'true' }}
        uses: softprops/action-gh-release@v0.1.15
        with:
          body_path: CHANGELOG.md
          tag_name: ${{ steps.versioning.outputs.version_tag }}
          files: |
            build/libs/*
            CHANGELOG.md
            CHANGELOG.txt

      - name: Update badge
        uses: schneegans/dynamic-badges-action@v1.6.0
        with:
          auth: ${{ secrets.GIST_SECRET }}
          gistID: 3ef501bc64c896a86fd706dfea8ba367
          filename: projectred-badge-${{ steps.release_type.outputs.release_channel }}-${{ steps.release_type.outputs.release_type }}.json
          label: Project Red ${{ steps.release_type.outputs.release_channel }}
          message: ${{ steps.versioning.outputs.version }}
          color: green
          namedLogo: CurseForge
          cacheSeconds: 300

      - name: Cleanup Gradle Cache
        # These files shouldn't be cached according to https://docs.github.com/en/actions/guides/building-and-testing-java-with-gradle
        run: |
          rm -f ~/.gradle/caches/modules-2/modules-2.lock
          rm -f ~/.gradle/caches/modules-2/gc.properties

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: project-red-${{ steps.versioning.outputs.version }}
          path: |
            '*/build/libs/ProjectRed-*.jar'
            CHANGELOG.md
            CHANGELOG.txt


Run dependency analyzer

name: Run dependency analyzer
on:
  workflow_dispatch:
    inputs:
      system:
        description: the package management system
        required: true
        type: choice
        default: maven
        options:
        - maven
      name:
        description: the name of the dependency
        required: true
        type: string
      version:
        description: the version of the dependency
        required: true
        type: string
jobs:
  Run-dependency-analyzer:
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-java@v4
      with:
        distribution: temurin
        java-version: 17
        cache: maven
    - name: Set up Maven
      uses: stCarolas/setup-maven@v4.5
      with:
        maven-version: 3.8.2
    - name: Install dependency analyzer
      shell: bash
      run: |
        mvn clean install -V --batch-mode --no-transfer-progress -DskipTests
      working-directory: java-shared-dependencies/dependency-analyzer
    - name: Check dependency information
      shell: bash
      run: |
        mvn exec:java -Ddep.system=${{ github.event.inputs.system }} -Ddep.name=${{ github.event.inputs.name }} -Ddep.version=${{ github.event.inputs.version }}
      working-directory: java-shared-dependencies/dependency-analyzer


ci

on:
  push:
    branches:
      - main
  pull_request:
name: ci
jobs:
  build:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        java: [ 11, 17]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: temurin
          cache: maven
      - run: java -version
      - name: Unit Tests
        run: |
          mvn test --batch-mode --no-transfer-progress -Dcheckstyle.skip \
              -Dfmt.skip -DenableTestCoverage
      # The `envVarTest` profile runs tests that require an environment variable
      - name: Env Var Tests
        run: |
          mvn test --batch-mode --no-transfer-progress -Dcheckstyle.skip \
              -Dfmt.skip -DenableTestCoverage -PenvVarTest
        # Set the Env Var for this step only
        env:
          GOOGLE_CLOUD_UNIVERSE_DOMAIN: random.com
      - run: bazelisk version
      - name: Install Maven modules
        run: |
          mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
      - name: Integration Tests
        run: |
          bazelisk --batch test //test/integration/...
      - name: Gradle Build Generated Storage Client Library
        run: |
          echo "Building Storage lib from generated source..."
          mkdir /tmp/java-storage
          bazelisk --batch build @com_google_googleapis//google/storage/v2:google-cloud-storage-v2-java
          tar zxvf bazel-bin/external/com_google_googleapis/google/storage/v2/google-cloud-storage-v2-java.tar.gz -C /tmp/java-storage
          pushd /tmp/java-storage/google-cloud-storage-v2-java
          ./gradlew clean build publishToMavenLocal sourcesJar allJars
          popd

      - name: Gradle Build Generated Compute Client Library
        run: |
          echo "Building Compute lib from generated source..."
          mkdir /tmp/java-compute
          bazelisk --batch build @com_google_googleapis//google/cloud/compute/v1small:google-cloud-compute-small-v1-java
          tar zxvf bazel-bin/external/com_google_googleapis/google/cloud/compute/v1small/google-cloud-compute-small-v1-java.tar.gz -C /tmp/java-compute
          pushd /tmp/java-compute/google-cloud-compute-small-v1-java
          ./gradlew clean build publishToMavenLocal sourcesJar allJars
          popd
  build-java-21:
    name: "build(21) except self-service clients"
    # Support for Java 21 is available for all use cases except self-service clients.
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: 21
          distribution: temurin
          cache: maven
      - run: java -version
      - name: Unit Tests
        run: |
          mvn test --batch-mode --no-transfer-progress -Dcheckstyle.skip \
              -Dfmt.skip -DenableTestCoverage
      # The `envVarTest` profile runs tests that require an environment variable
      - name: Env Var Tests
        run: |
          mvn test --batch-mode --no-transfer-progress -Dcheckstyle.skip \
              -Dfmt.skip -DenableTestCoverage -PenvVarTest
        # Set the Env Var for this step only
        env:
          GOOGLE_CLOUD_UNIVERSE_DOMAIN: random.com
      - run: bazelisk version
      - name: Install Maven modules
        run: |
          mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
      - name: Integration Tests
        run: |
          bazelisk --batch test //test/integration/...
  build-java8-except-gapic-generator-java:
    name: "build(8) except for gapic-generator-java"
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      # Java 8 tests uses JDK 17 to compile and JDK 8 to run tests.
      - uses: actions/setup-java@v4
        with:
          java-version: 8
          distribution: temurin
          cache: maven
      - run: echo "JAVA8_HOME=${JAVA_HOME}" >> $GITHUB_ENV
      - uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: temurin
      - name: Compile with Java 17 and run tests with Java 8
        shell: bash
        run: |
          set -x
          export JAVA_HOME=$JAVA_HOME
          export PATH=${JAVA_HOME}/bin:$PATH
          # Maven surefire plugin lets us to specify the JVM when running tests via
          # the "jvm" system property.
          mvn verify --batch-mode --no-transfer-progress -Dcheckstyle.skip \
              -Dfmt.skip \
              -Djvm="${JAVA8_HOME}/bin/java"
      # The `envVarTest` profile runs tests that require an environment variable
      - name: Compile with Java 17 and run tests with Java 8 (Env Var Tests)
        shell: bash
        run: |
          set -x
          export JAVA_HOME=$JAVA_HOME
          export PATH=${JAVA_HOME}/bin:$PATH
          # Maven surefire plugin lets us to specify the JVM when running tests via
          # the "jvm" system property.
          export GOOGLE_CLOUD_UNIVERSE_DOMAIN=random.com
          mvn test --batch-mode --no-transfer-progress -Dcheckstyle.skip \
              -Dfmt.skip -DenableTestCoverage -Dsurefire.failIfNoSpecifiedTests=false \
              -PenvVarTest
        # Set the Env Var for this step only
        env:
          GOOGLE_CLOUD_UNIVERSE_DOMAIN: random.com

  build-java8-gapic-generator-java:
    name: "build(8) for gapic-generator-java"
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: 11
          distribution: temurin
          cache: maven
      - name: Install all modules using Java 11
        shell: bash
        run: |
          mvn -V -B -ntp clean install -DskipTests
      - uses: actions/setup-java@v3
        with:
          java-version: 8
          distribution: temurin
      - run: java -version
      - name: Run tests in Java 8 with the source compiled in Java 11 for gapic-generator-java
        shell: bash
        run: |
          mvn -V -B -ntp surefire:test --projects 'gapic-generator-java'
      - run: bazelisk version
      - name: Integration Tests
        run: |
          bazelisk --batch test //test/integration/...
      - name: Gradle Build Generated Storage Client Library
        run: |
          echo "Building Storage lib from generated source..."
          mkdir /tmp/java-storage
          bazelisk --batch build @com_google_googleapis//google/storage/v2:google-cloud-storage-v2-java
          tar zxvf bazel-bin/external/com_google_googleapis/google/storage/v2/google-cloud-storage-v2-java.tar.gz -C /tmp/java-storage
          pushd /tmp/java-storage/google-cloud-storage-v2-java
          ./gradlew clean build publishToMavenLocal sourcesJar allJars
          popd

      - name: Gradle Build Generated Compute Client Library
        run: |
          echo "Building Compute lib from generated source..."
          mkdir /tmp/java-compute
          bazelisk --batch build @com_google_googleapis//google/cloud/compute/v1small:google-cloud-compute-small-v1-java
          tar zxvf bazel-bin/external/com_google_googleapis/google/cloud/compute/v1small/google-cloud-compute-small-v1-java.tar.gz -C /tmp/java-compute
          pushd /tmp/java-compute/google-cloud-compute-small-v1-java
          ./gradlew clean build publishToMavenLocal sourcesJar allJars
          popd

  lint:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: 11
          distribution: temurin
          cache: maven
      - run: java -version
      - name: Java Linter
        # Exclude the root project
        run: mvn -B -ntp fmt:check

  compatibility:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: 11
          distribution: temurin
          cache: maven
      - run: java -version
      - name: Compatibility check
        #  package jar so that gapic-generator-java module can use
        #  testlib modules of gax
        run: mvn package clirr:check -DskipTests

  showcase:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        java: [ 11, 17 ]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: temurin
      - run: mvn -version
      - name: Install Maven modules
        run: |
          mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
      - name: Java Linter
        working-directory: showcase
        run: |
          mvn -B -ntp fmt:check
      - name: Showcase golden tests
        working-directory: showcase
        run: |
          mvn test \
            -P enable-golden-tests \
            --batch-mode \
            --no-transfer-progress
      - name: Parse showcase version
        working-directory: showcase/gapic-showcase
        run: echo "SHOWCASE_VERSION=$(mvn help:evaluate -Dexpression=gapic-showcase.version -q -DforceStdout)" >> "$GITHUB_ENV"
      - name: Install showcase server
        run: |
          sudo mkdir -p /usr/src/showcase
          sudo chown -R ${USER} /usr/src/
          curl --location https://github.com/googleapis/gapic-showcase/releases/download/v${{env.SHOWCASE_VERSION}}/gapic-showcase-${{env.SHOWCASE_VERSION}}-linux-amd64.tar.gz --output /usr/src/showcase/showcase-${{env.SHOWCASE_VERSION}}-linux-amd64.tar.gz
          cd /usr/src/showcase/
          tar -xf showcase-*
          ./gapic-showcase run &
          cd -
      - name: Showcase integration tests
        working-directory: showcase
        run: |
          mvn verify \
            -P enable-integration-tests \
            --batch-mode \
            --no-transfer-progress

  showcase-native:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: graalvm/setup-graalvm@v1
        with:
          version: '22.3.2'
          java-version: '17'
          components: 'native-image'
          github-token: ${{ secrets.GITHUB_TOKEN }}
      - run: mvn -version
      - run: native-image --version
      - name: Install sdk-platform-java
        run: mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
      - name: Parse showcase version
        working-directory: showcase/gapic-showcase
        run: echo "SHOWCASE_VERSION=$(mvn help:evaluate -Dexpression=gapic-showcase.version -q -DforceStdout)" >> "$GITHUB_ENV"
      - name: Install showcase server
        run: |
          sudo mkdir -p /usr/src/showcase
          sudo chown -R ${USER} /usr/src/
          curl --location https://github.com/googleapis/gapic-showcase/releases/download/v${{env.SHOWCASE_VERSION}}/gapic-showcase-${{env.SHOWCASE_VERSION}}-linux-amd64.tar.gz --output /usr/src/showcase/showcase-${{env.SHOWCASE_VERSION}}-linux-amd64.tar.gz
          cd /usr/src/showcase/
          tar -xf showcase-*
          ./gapic-showcase run &
          cd -
      - name: Build native image
        working-directory: showcase
        run: mvn test -Pnative,-showcase -ntp -B

  showcase-clirr:
    if: ${{ github.base_ref != '' }} # Only execute on pull_request trigger event
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout @ target branch
        uses: actions/checkout@v4
        with:
          ref: ${{ github.base_ref }}
      - uses: actions/setup-java@v4
        with:
          java-version: 17
          distribution: temurin
          cache: maven
      - name: Install sdk-platform-java and showcase to local maven repository
        run: |
          mvn install -B -ntp -T 1C -DskipTests
          cd showcase
          mvn install -B -ntp -T 1C -DskipTests
          SHOWCASE_CLIENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
          echo "SHOWCASE_CLIENT_VERSION=$SHOWCASE_CLIENT_VERSION" >> "$GITHUB_ENV"
      - name: Checkout sdk-platform-java @ PR merge commit
        uses: actions/checkout@v3
      - name: Install sdk-platform-java @ PR merge commit
        run: mvn install -B -ntp -T 1C -DskipTests
        # Showcase golden test ensures that src changes are already reflected in the PR.
      - name: Clirr check
        working-directory: showcase
        run: |
          mvn versions:set -B -ntp -DnewVersion=local
          mvn clirr:check -B -ntp -Dclirr.skip=false -DcomparisonVersion=$SHOWCASE_CLIENT_VERSION

  gapic-generator-java-bom:
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-java@v4
      with:
        java-version: 11
        distribution: temurin
        cache: maven
    - name: Install Maven modules to local Maven repository
      run: |
        mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
    - name: Validate gapic-generator-java-bom
      uses: googleapis/java-cloud-bom/tests/validate-bom@59c776be18728bcdc53f868c497baf1f5039abb6
      with:
        bom-path: gapic-generator-java-bom/pom.xml

  unmanaged_dependency_check:
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v4
      with:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: actions/setup-java@v4
      with:
        java-version: 11
        distribution: temurin
    - run: mvn -version
    - name: Unit Tests
      run: |
        mvn test --batch-mode --no-transfer-progress
      working-directory: java-shared-dependencies/unmanaged-dependency-check
    - name: Install Maven modules
      run: |
        mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
    - name: Unmanaged dependency check
      uses: ./java-shared-dependencies/unmanaged-dependency-check
      with:
        bom-path: gapic-generator-java-bom/pom.xml

  dependency_analyzer_unit_test:
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v4
      with:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: actions/setup-java@v4
      with:
        java-version: 17
        distribution: temurin
    - run: mvn -version
    - name: Unit Tests
      run: |
        mvn test --batch-mode --no-transfer-progress
      working-directory: java-shared-dependencies/dependency-analyzer


Create additional tags for each release

name: Create additional tags for each release

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions: write-all
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
    - name: Set up Git
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"
    - name: Fetch all tags
      run: git fetch --tags
    - name: Create additional tags
      shell: bash
      run: |
        ARTIFACT_IDS=('google-cloud-shared-dependencies' 'api-common' 'gax')
        for ARTIFACT_ID in "${ARTIFACT_IDS[@]}"; do
          VERSION=$(grep "^${ARTIFACT_ID}:" versions.txt | cut -d':' -f2 | tr -d '[:space:]')
          TAG_NAME="${ARTIFACT_ID}/v$VERSION"
          if git show-ref --tags | grep -q "refs/tags/$TAG_NAME"; then
            echo "Tag $TAG_NAME already exists. Skipping."
            continue
          fi
          git tag $TAG_NAME
          git push origin $TAG_NAME
        done


Downstream Check

on:
  push:
    branches:
      - main
  pull_request:
    # Changes to these directories do not directly affect the downstream libraries
    paths-ignore:
      - gapic-generator-java/**
      - library_generation/**
      - showcase/**
      - test/**

name: Downstream Check
jobs:
  downstream-compatibility:
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: false
      matrix:
        repo:
          - google-cloud-java
          - java-bigtable
          - java-bigquery
          - java-bigquerystorage
          - java-datastore
          - java-firestore
          - java-logging
          - java-logging-logback
          - java-pubsub
          - java-pubsublite
          - java-spanner-jdbc
          - java-spanner
          - java-storage
          - java-storage-nio
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: temurin
      - run: mvn -version
      - name: Install xmllint
        run: |
          sudo apt-get update
          sudo apt-get -y install libxml2-utils
      - name: Test helper scripts
        run: ./.kokoro/presubmit/common_test.sh
      - name: Perform downstream compatibility testing
        run: REPOS_UNDER_TEST="${{ matrix.repo }}" ./.kokoro/presubmit/downstream-compatibility.sh


Downstream Unmanaged Dependency Check

on:
  push:
    branches:
      - main
  pull_request:
    paths:
      - .github/workflows/downstream_unmanaged_dependency_check.yaml
      - java-shared-dependencies/**

name: Downstream Unmanaged Dependency Check
jobs:
  validate:
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: false
      matrix:
        repo:
          - java-bigtable
          - java-firestore
          - java-logging
    steps:
      - name: Checkout sdk-platform-java
        uses: actions/checkout@v3
        with:
          path: sdk-platform-java
      - name: Checkout the downstream repo
        uses: actions/checkout@v4
        with:
          repository: googleapis/${{ matrix.repo }}
          path: ${{ matrix.repo }}
      - name: Check the environment
        shell: bash
        run: |
          set -euxo pipefail
          pwd
          ls -alt
      - uses: actions/setup-java@v3
        with:
          java-version: 11
          distribution: temurin
          cache: maven
      - name: Install the modules of sdk-platform-java
        shell: bash
        working-directory: sdk-platform-java
        run: |
          set -euo pipefail
          # gapic-generator-java is irrelevant
          mvn -q -B -ntp install --projects '!gapic-generator-java' \
            -Dcheckstyle.skip -Dfmt.skip -DskipTests -T 1C
      - name: Build unmanaged dependency check
        shell: bash
        working-directory: sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check
        run: |
          set -euo pipefail
          echo "Install Unmanaged Dependency Check in $(pwd)"
          mvn clean install -V --batch-mode --no-transfer-progress -DskipTests
      - name: Install the modules of the downstream repository
        shell: bash
        working-directory: ${{ matrix.repo }}
        run: |
          # No argument to build.sh installs the modules in local Maven repository
          .kokoro/build.sh
      - name: Run unmanaged dependency check
        shell: bash
        run: |
          set -euo pipefail
          set -x
          # java-bigtable has "-deps-bom" that declares its dependencies. It's not a good
          # BOM to list the artifacts generated by that repository.
          bom_dir=$(find ${{ matrix.repo }} -type d -name 'google-*-bom' ! -name '*-deps-bom')
          bom_absolute_path=$(realpath "${bom_dir}/pom.xml")
          cd sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check
          echo "Running Unmanaged Dependency Check against ${bom_absolute_path}"
          unmanaged_dependencies=$(mvn exec:java -Dexec.args="../pom.xml ${bom_absolute_path}" -q)
          if [[ "${unmanaged_dependencies}" != "[]" ]]; then
            echo "With this change, the unmanaged dependencies check installed in ${{ matrix.repo }} will start to"
            echo "fail due to ${unmanaged_dependencies}, among the artifacts listed in ${bom_absolute_path}."
            exit 1
          fi
          echo "Unmanaged dependency check passed"


# Copyright 2024 Google LLC
#
# Licensed 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
#
#      http://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.
# GitHub action job to test core java library features on
# downstream client libraries before they are released.
name: Hermetic library generation upon generation config change through pull requests
on:
  pull_request:

jobs:
  library_generation:
    # skip pull requests come from a forked repository
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
        token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}
    - name: Generate changed libraries
      shell: bash
      run: |
        set -x
        [ -z "$(git config user.email)" ] && git config --global user.email "cloud-java-bot@google.com"
        [ -z "$(git config user.name)" ] && git config --global user.name "cloud-java-bot"
        bash .github/scripts/hermetic_library_generation.sh \
          --target_branch "${base_ref}" \
          --current_branch "${head_ref}" \
          --image_tag latest
      env:
        base_ref: ${{ github.base_ref }}
        head_ref: ${{ github.head_ref }}
        GH_TOKEN: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}


Nightly

name: Nightly
on:
  workflow_dispatch:
  schedule:
    - cron: '0 1 * * *' # Nightly at 1am
defaults:
  run:
    shell: bash
jobs:
  nightly:
    strategy:
      fail-fast: false
      matrix:
        os: [ macOS-12, ubuntu-22.04, windows-2022 ]
        java: [ 11, 17 ]
    runs-on: ${{ matrix.os }}
    steps:
      - run: git config --global core.longpaths true
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: ${{ matrix.java }}
          distribution: temurin
          cache: maven
      - run: mvn -version
      - name: Install
        run: mvn install --errors --batch-mode --no-transfer-progress -Dcheckstyle.skip -T 1C
      - name: Create issue if previous step fails
        if: ${{ failure() }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh issue create \
            --title "Nightly build for Java ${{ matrix.java }} on ${{ matrix.os }} failed." \
            --body "The build has failed : https://github.com/googleapis/gapic-generator-java/actions/runs/${GITHUB_RUN_ID}"
  nightly-java8: # Compile with JDK 11. Run tests with JDK 8.
    strategy:
      fail-fast: false
      matrix:
        os: [ macOS-12, ubuntu-22.04, windows-2022 ]
    runs-on: ${{ matrix.os }}
    steps:
      - run: git config --global core.longpaths true
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: 11
          distribution: temurin
          cache: maven
      - run: mvn -version
      - name: Install with Java 11
        run: mvn install --errors --batch-mode --no-transfer-progress -Dcheckstyle.skip -DskipTests -T 1C

      - uses: actions/setup-java@v3
        with:
          java-version: 8
          distribution: temurin
      - run: mvn -version
      - name: Test with Java 8
        # Direct goal invocation ("surefire:test") prevents recompiling tests
        run: mvn surefire:test --errors --batch-mode --no-transfer-progress -T 1C
      - name: Create issue if previous step fails
        if: ${{ failure() }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh issue create \
            --title "Nightly-java8 build on ${{ matrix.os }} failed." \
            --body "The build has failed : https://github.com/googleapis/gapic-generator-java/actions/runs/${GITHUB_RUN_ID}"


Renovate Bot Config Validation

name: Renovate Bot Config Validation

on:
  pull_request:
    paths:
    - 'renovate.json'

jobs:
  config_validation:
    runs-on: ubuntu-latest

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

    - name: Set up Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '20'

    - name: Install Renovate and Config Validator
      run: |
        npm install -g npm@latest
        npm install --global renovate
        renovate-config-validator


shared-dependencies version check

on:
  push:
    branches:
    - main
  pull_request:
    paths:
    - 'gapic-generator-java-bom/**'
    - 'gapic-generator-java-pom-parent/**'
    - 'java-shared-dependencies/**'
name: shared-dependencies version check
jobs:
  upper-bound-check:
    name: Shared Dependencies BOM upper-bound check
    runs-on: ubuntu-latest
    if: github.repository_owner == 'googleapis'
    steps:
    - uses: actions/checkout@v2
    - uses: stCarolas/setup-maven@v4
      with:
        maven-version: 3.8.1
    - uses: actions/setup-java@v1
      with:
        java-version: 11
    - run: java -version
    - name: Install maven modules
      run: |
        mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip
    - name: Check the BOM content satisfies the upper-bound-check test case
      run: mvn -B -V -ntp verify -Dcheckstyle.skip
      working-directory: java-shared-dependencies/upper-bound-check


SonarCloud Build

name: SonarCloud Build
on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  build:
    name: Build
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Shallow clones should be disabled for a better relevancy of analysis
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: temurin
      - name: Cache SonarCloud packages
        uses: actions/cache@v3
        with:
          path: ~/.sonar/cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar
      - name: Cache Maven packages
        uses: actions/cache@v3
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
          restore-keys: ${{ runner.os }}-m2
      - name: Install modules to local maven
        run: |
          mvn install -T 1C -DskipTests -ntp -B
          cd showcase
          mvn install -T 1C -DskipTests -ntp -B
      - name: Parse showcase version
        working-directory: showcase/gapic-showcase
        run: echo "SHOWCASE_VERSION=$(mvn help:evaluate -Dexpression=gapic-showcase.version -q -DforceStdout)" >> "$GITHUB_ENV"
      - name: Install showcase server
        run: |
            sudo mkdir -p /usr/src/showcase
            sudo chown -R ${USER} /usr/src/
            curl --location https://github.com/googleapis/gapic-showcase/releases/download/v${{env.SHOWCASE_VERSION}}/gapic-showcase-${{env.SHOWCASE_VERSION}}-linux-amd64.tar.gz --output /usr/src/showcase/showcase-${{env.SHOWCASE_VERSION}}-linux-amd64.tar.gz
            cd /usr/src/showcase/
            tar -xf showcase-*
            ./gapic-showcase run &
            cd -
      # Intentionally do not run the Env Var Tests (no -PenvVarTests) as setting the Env Var
      # may alter the results for other tests that use Env Var in the logic. Adding a Sonar
      # step for a few tests (env var tests) may be overkill and should be better covered
      # when we can upgrade to JUnit 5 (https://github.com/googleapis/sdk-platform-java/issues/1611#issuecomment-1970079325)
      - name: Build and analyze for full test coverage
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: |
          mvn -B verify -Dcheckstyle.skip \
              -DenableFullTestCoverage \
              -Penable-integration-tests \
              org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
              -Dsonar.projectKey=googleapis_gapic-generator-java \
              -Dsonar.organization=googleapis \
              -Dsonar.host.url=https://sonarcloud.io
      - name: Build and analyze Showcase Integration Tests Coverage
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: |
          mvn -B clean verify -Dcheckstyle.skip \
              -DskipUnitTests \
              -Penable-integration-tests \
              -DenableShowcaseTestCoverage \
              org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
              -Dsonar.projectKey=googleapis_gapic-generator-java_integration_tests \
              -Dsonar.organization=googleapis \
              -Dsonar.host.url=https://sonarcloud.io \
              -Dsonar.projectName=java_showcase_integration_tests


Update googleapis commit

# Copyright 2024 Google LLC
#
# Licensed 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
#
#      http://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.
# GitHub action job to test core java library features on
# downstream client libraries before they are released.
name: Update googleapis commit
on:
  schedule:
  - cron: '0 2 * * *'
  workflow_dispatch:

jobs:
  update-googleapis-commit:
    runs-on: ubuntu-22.04
    env:
      # the branch into which the pull request is merged
      base_branch: main
    steps:
    - uses: actions/checkout@v4
      with:
        token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}
    - name: Update googleapis commit to latest
      shell: bash
      run: |
        set -x
        [ -z "$(git config user.email)" ] && git config --global user.email "cloud-java-bot@google.com"
        [ -z "$(git config user.name)" ] && git config --global user.name "cloud-java-bot"
        bash .github/scripts/update_googleapis_commit.sh \
          --base_branch "${base_branch}"\
          --repo ${{ github.repository }}
      env:
        GH_TOKEN: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}


on:
  pull_request:

name: verify_library_generation
jobs:
  should-run-library-generation-tests:
    runs-on: ubuntu-22.04
    outputs:
      should_run: ${{ steps.get_changed_directories.outputs.should_run }}
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    - name: get changed directories in the pull request
      id: get_changed_directories
      shell: bash
      run: |
        set -ex
        # PRs that come from a fork need to be handled differently
        if [[ ${head_repo_name} == ${base_repo} ]]; then
          git checkout ${base_ref}
          git checkout ${head_ref}
          changed_directories="$(git diff --name-only ${base_ref} ${head_ref})"
        else
          git remote add fork ${head_repo_url}
          git fetch fork # create a mapping of the fork
          git checkout -b "${head_ref}" fork/${head_ref}
          changed_directories="$(git diff --name-only "fork/${head_ref}" "origin/${base_ref}")"
        fi
        if [[ ${changed_directories} =~ "library_generation/" ]]; then
          echo "should_run=true" >> $GITHUB_OUTPUT
        else
          echo "should_run=false" >> $GITHUB_OUTPUT
        fi
      env:
        base_ref: ${{ github.event.pull_request.base.ref }}
        head_ref: ${{ github.event.pull_request.head.ref }}
        head_repo_url: ${{ github.event.pull_request.head.repo.html_url }}
        head_repo_name: ${{ github.event.pull_request.head.repo.full_name  }}
        base_repo: ${{ github.repository }}
  library-generation-integration-tests:
    runs-on: ubuntu-22.04
    needs: should-run-library-generation-tests
    if: needs.should-run-library-generation-tests.outputs.should_run == 'true'
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-python@v5
      with:
        python-version: 3.11
    - name: install pyenv
      shell: bash
      run: |
        set -ex
        curl https://pyenv.run | bash
        # setup environment
        export PYENV_ROOT="$HOME/.pyenv"
        export PATH="$PYENV_ROOT/bin:$PATH"
        echo "PYENV_ROOT=${PYENV_ROOT}" >> $GITHUB_ENV
        echo "PATH=${PATH}" >> $GITHUB_ENV

        set +ex
    - name: install python dependencies
      shell: bash
      run: |
        set -ex
        pushd library_generation
        pip install -r requirements.txt
        pip install .
        popd
    - name: Run integration tests
      shell: bash
      run: |
        set -x
        python -m unittest library_generation/test/integration_tests.py
  library-generation-unit-tests:
    runs-on: ${{ matrix.os }}
    needs: should-run-library-generation-tests
    if: needs.should-run-library-generation-tests.outputs.should_run == 'true'
    strategy:
      matrix:
        java: [ 8 ]
        os: [ ubuntu-22.04, macos-12 ]
    steps:
    - uses: actions/checkout@v4
    - name: install utils (macos)
      if: matrix.os == 'macos-12'
      shell: bash
      run: |
        brew update --preinstall
        brew install coreutils
    - uses: actions/setup-python@v5
      with:
        python-version: 3.11
    - name: install python dependencies
      shell: bash
      run: |
        set -ex
        pushd library_generation
        pip install -r requirements.txt
        popd
    - name: install synthtool
      shell: bash
      run: |
        set -ex
        mkdir -p /tmp/synthtool
        pushd /tmp/synthtool
        if [ ! -d "synthtool" ]; then
          git clone https://github.com/googleapis/synthtool.git
        fi
        pushd "synthtool"

        git reset --hard origin/no-java-templates

        python3 -m pip install -e .
        python3 -m pip install -r requirements.in
    - name: Run shell unit tests
      run: |
        set -x
        library_generation/test/generate_library_unit_tests.sh
    - name: Run python unit tests
      run: |
        set -x
        python -m unittest discover -s library_generation/test/ -p "*unit_tests.py"
  library-generation-lint-shell:
    runs-on: ubuntu-22.04
    needs: should-run-library-generation-tests
    if: needs.should-run-library-generation-tests.outputs.should_run == 'true'
    steps:
    - uses: actions/checkout@v4
    - name: Run ShellCheck
      uses: ludeeus/action-shellcheck@2.0.0
      with:
        scandir: 'library_generation'
        format: tty
        severity: error
  library-generation-lint-python:
    runs-on: ubuntu-22.04
    needs: should-run-library-generation-tests
    if: needs.should-run-library-generation-tests.outputs.should_run == 'true'
    steps:
    - uses: actions/checkout@v4
    - name: install python dependencies
      shell: bash
      run: |
        set -ex
        pushd library_generation
        pip install -r requirements.txt
        popd
    - name: Lint
      shell: bash
      run: |
        # exclude generated golden files
        # exclude owlbot until further refaction
        black --check library_generation --exclude "(library_generation/test/resources/goldens)"


Combine PRs

name: Combine PRs

on:
  schedule:
    - cron: '0 2 * * *' # Every day at 02:00 UTC
  workflow_dispatch: # allows you to manually trigger the workflow

# The minimum permissions required to run this Action
permissions:
  contents: write
  pull-requests: write
  checks: read

jobs:
  combine-prs:
    runs-on: ubuntu-latest
    steps:
      - name: combine-prs
        id: combine-prs
        uses: github/combine-prs@v5.0.0
        with:
          branch_regex: ^(dependa|wrapper)bot\/.*$


Validate Gradle Wrapper

name: "Validate Gradle Wrapper"
on: [push, pull_request]

jobs:
  validation:
    name: "Validation"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: gradle/actions/wrapper-validation@v3


Label Commenter

name: Label Commenter

on:
  issues:
    types: [labeled]

permissions:
  contents: read
  issues: write

jobs:
  comment:
    if: github.repository_owner == 'testng-team'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Label Commenter
        uses: peaceiris/actions-label-commenter@v1


Publish to Maven Central

# This is a basic workflow to help you get started with Actions

name: Publish to Maven Central

# Trigger this workflow whenever code is pushed to "master" branch.defaults:
# We would like to publish to maven central for both snapshot and release versions.
on:
  workflow_dispatch:
    inputs:
      release_candidate:
        description: The release candidate number
        required: true
        default: '1'
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v4

    - name: Gradle wrapper validation
      uses: gradle/actions/wrapper-validation@v3

    # FIXME Check https://github.com/allure-framework/allure2/blob/430255d8cf5c236ed29bc0df0b72dcd9389c3df9/.github/workflows/release.yaml
    - name: Publish Release Candidate
      env:
        ORG_GRADLE_PROJECT_ghGitSourceUsername: ${{ github.actor }}
        ORG_GRADLE_PROJECT_ghGitSourcePassword: ${{ secrets.GITHUB_TOKEN }}
        ORG_GRADLE_PROJECT_ghNexusUsername: ${{ secrets.NEXUS_USERNAME }}
        ORG_GRADLE_PROJECT_ghNexusPassword: ${{ secrets.NEXUS_PASSWORD }}
        ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.GPG_KEY_ID }}
        ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }}
        ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }}
        ORG_GRADLE_PROJECT_rc: ${{ github.event.inputs.release_candidate }}
      run: |
        ./gradlew -PghDryRun prepareVote

    - name: Display next step
      run: |
        echo "Now run 'release-maven-central.yml' workflow using the same Release Candidate Number (rc #)"


Publish Snapshot

name: Publish Snapshot

# Trigger this workflow whenever code is pushed to "master" branch.defaults:
# We would like to publish to maven central for both snapshot and release versions.
on:
  push:
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v4

    - name: Gradle wrapper validation
      uses: gradle/actions/wrapper-validation@v3

    - name: Publish to GitHub
      run: |
        ./gradlew -PghNexusUsername=${{ secrets.NEXUS_USERNAME }} -PghNexusPassword=${{ secrets.NEXUS_PASSWORD }} -Pgh publish


Release TestNG to Maven Central

# This is a basic workflow to help you get started with Actions

name: Release TestNG to Maven Central

# Trigger this workflow whenever code is pushed to "master" branch.defaults:
# We would like to publish to maven central for both snapshot and release versions.
on:
  workflow_dispatch:
    inputs:
      release_candidate:
        description: The release candidate number that was already published
        required: true
        default: '1'
      staging_repository_id:
        description: The staging repository ID obtained from workflow run logs of "publish-maven-central.yml" for e.g., (orgtestng-1082)
        required: true
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Gradle wrapper validation
      uses: gradle/actions/wrapper-validation@v3

    - name: Create Nexus.txt with staging repository details
      run: |
         mkdir -p build/stagingRepositories
         echo -n ${{ github.event.inputs.staging_repository_id }} > build/stagingRepositories/nexus.txt

    # FIXME Check https://github.com/allure-framework/allure2/blob/430255d8cf5c236ed29bc0df0b72dcd9389c3df9/.github/workflows/release.yaml
    - name: Publish Release Candidate
      env:
        ORG_GRADLE_PROJECT_ghGitSourceUsername: ${{ github.actor }}
        ORG_GRADLE_PROJECT_ghGitSourcePassword: ${{ secrets.GITHUB_TOKEN }}
        ORG_GRADLE_PROJECT_ghNexusUsername: ${{ secrets.NEXUS_USERNAME }}
        ORG_GRADLE_PROJECT_ghNexusPassword: ${{ secrets.NEXUS_PASSWORD }}
        ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.GPG_KEY_ID }}
        ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }}
        ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }}
        ORG_GRADLE_PROJECT_rc: ${{ github.event.inputs.release_candidate }}
      run: |
        ./gradlew -PghDryRun publishDist


Test

# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle

name: Test

on:
  push:
    branches:
      - '*'
  pull_request:
    branches: [ master ]

concurrency:
  # On master/release, we don't want any jobs cancelled so the sha is used to name the group
  # On PR branches, we cancel the job if new commits are pushed
  # More info: https://stackoverflow.com/a/68422069/253468
  group: ${{ (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release' ) && format('ci-main-{0}', github.sha) || format('ci-main-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  matrix_prep:
    name: Matrix Preparation
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    env:
      # Ask matrix.js to produce 7 jobs
      MATRIX_JOBS: 7
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1
      - id: set-matrix
        run: |
          node .github/workflows/matrix.js

  build:
    needs: matrix_prep
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
    name: '${{ matrix.name }}'
    env:
      TZ: ${{ matrix.tz }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 10
      - name: Set up Java ${{ matrix.java_version }}, oracle
        if: ${{ matrix.oracle_java_website != '' }}
        uses: oracle-actions/setup-java@83e2004a40aaa491fbc6b4697353b9a75b095efb # v1.3.4
        with:
          website: ${{ matrix.oracle_java_website }}
          release: ${{ matrix.java_version }}
      - name: Set up Java 17 and ${{ matrix.non_ea_java_version }}, ${{ matrix.java_distribution }}
        uses: actions/setup-java@v4
        with:
          # The latest one will be the default, so we use Java 17 for launching Gradle
          java-version: |
            ${{ matrix.non_ea_java_version }}
            17
          distribution: ${{ matrix.java_distribution }}
          architecture: x64
      - name: Steps to reproduce
        uses: actions/github-script@v7
        with:
          script: |
            console.log('The following command might help reproducing CI results, use Java ${{ matrix.java_version }}')
            console.log('TZ="${{ matrix.tz }}" ./gradlew build ${{ matrix.extraGradleArgs }} -Ptestng.test.extra.jvmargs="${{ matrix.testExtraJvmArgs }}" -PtestDisableCaching="${{ matrix.testDisableCaching }}"')
      - name: 'Generate unique build id'
        id: build_id
        run: echo "unique_id=$(date +%s)" >> $GITHUB_OUTPUT
      - name: Test
        id: run_test_cases
        uses: burrunan/gradle-cache-action@v1
        with:
          job-id: jdk${{ matrix.jdk.version }}
          arguments: |
            --no-parallel --no-daemon --scan
            build
            ${{ matrix.extraGradleArgs }}
          properties: |
            testng.test.extra.jvmargs=${{ matrix.testExtraJvmArgs }}
            testDisableCaching=${{ matrix.testDisableCaching }}
            jdkBuildVersion=17
            jdkTestVersion=${{ matrix.java_version }}
            jdkTestVendor=${{ matrix.java_vendor }}
            # We provision JDKs with GitHub Actions for caching purposes, so Gradle should rather fail in case JDK is not found
            org.gradle.java.installations.auto-download=false
      - name: Upload build reports
        if: ${{ failure() && steps.run_test_cases.outcome == 'failure' }}
        uses: actions/upload-artifact@v4
        with:
          name: build-reports-${{ matrix.jdk.group }}-${{ matrix.jdk.version }}-${{ steps.build_id.outputs.unique_id }}
          path: testng-core/build/reports/tests/test/**


Update Gradle Wrapper

name: Update Gradle Wrapper

on:
  schedule:
    - cron: '0 0 * * *' # Every day at 00:00 UTC

jobs:
  update-gradle-wrapper:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Update Gradle Wrapper
        uses: gradle-update/update-gradle-wrapper-action@v1


Assign Problem To Developer

# 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
#
#    http://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: Assign Problem To Developer

on:
  issues:
    types: [ opened ]

jobs:
  assign-udf-problem-to-developer:
    runs-on: ubuntu-latest
    if: contains(github.event.issue.title, 'udf') == true || contains(github.event.issue.title, 'udtf') == true || contains(github.event.issue.body, 'udaf') == true
    steps:
      - name: assign problem to developer of udf
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'add-assignees'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          assignees: gaoyan1998,zackyoungh
      - name: Assign developer Comment
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue is about UDF, so I assign it to @gaoyan1998 and @zackyoungh. If you have any questions, you can comment and reply.

            你好 @${{ github.event.issue.user.login }}, 这个 issue 是关于 UDF 的，所以我把它分配给了 @gaoyan1998 和 @zackyoungh。如有任何问题，可以评论回复。

  assign-k8s-problem-to-developer:
    runs-on: ubuntu-latest
    if: contains(github.event.issue.title, 'k8s') == true || contains(github.event.issue.title, 'kubernetes') == true || contains(github.event.issue.body, 'kubernetes') == true
    steps:
      - name: assign problem to developer of k8s
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'add-assignees'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          assignees: gaoyan1998,zackyoungh
      - name: Assign developer Comment
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue is about K8S, so I assign it to @gaoyan1998 and @zackyoungh. If you have any questions, you can comment and reply.

            你好 @${{ github.event.issue.user.login }}, 这个 issue 是关于 K8S 的，所以我把它分配给了 @gaoyan1998 和 @zackyoungh。如有任何问题，可以评论回复。

  assign-web-problem-to-developer:
    runs-on: ubuntu-latest
    if: contains(github.event.issue.title, 'web') == true || contains(github.event.issue.body, 'web') == true
    steps:
      - name: assign problem to developer of web
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'add-assignees'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          assignees: Zzm0809
      - name: Assign developer Comment
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue is about web, so I assign it to @Zzm0809. If you have any questions, you can comment and reply.

            你好 @${{ github.event.issue.user.login }}, 这个 issue 是关于 web 的，所以我把它分配给了 @Zzm0809。如有任何问题，可以评论回复。

  assign-cdc-problem-to-developer:
    runs-on: ubuntu-latest
    if: contains(github.event.issue.title, 'cdc') == true || contains(github.event.issue.title, 'cdcsource') == true || contains(github.event.issue.body, 'pipeline') == true
    steps:
      - name: assign problem to developer of cdc and cdcsource
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'add-assignees'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          assignees: aiwenmo
      - name: Assign developer Comment
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue is about CDC/CDCSOURCE, so I assign it to @aiwenmo. If you have any questions, you can comment and reply.

            你好 @${{ github.event.issue.user.login }}, 这个 issue 是关于 CDC/CDCSOURCE 的，所以我把它分配给了 @aiwenmo。如有任何问题，可以评论回复。


Release Dinky

# 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
#
#    http://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 Dinky"

on:
  workflow_dispatch:
    inputs:
      version:
        type: string
        description: 'Dinky version'
        required: true
      prerelease:
        type: boolean
        description: 'Is this a pre-release?'
        required: true
      release_notes:
        type: string
        description: 'Release notes'
        required: true

jobs:
  release:
    name: ${{ inputs.prerelease == 'true' && 'Pre Release' || 'Release' }}
    runs-on: "ubuntu-latest"

    steps:
      - name: Set up JDK 8
        uses: actions/setup-java@v2
        with:
          java-version: 8
          distribution: 'adopt'

      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: '18.x'
          registry-url: 'https://registry.npmjs.org'

      - name: "Checkout Dinky"
        uses: actions/checkout@v3

      - name: "Build Dinky ${{ inputs.version }} with Fink 1.14 Pre Release/Release Artifact"
        id: build_dinky1_14
        run: |
          ./mvnw -B clean package \
                  -Dmaven.test.skip=false \
                 -Dspotless.check.skip=true \
                 -Denforcer.skip=false \
                 -Dmaven.javadoc.skip=true \
                   -Pprod,scala-2.12,flink-single-version,flink-1.14,maven-central,web,fast \
                 --no-snapshot-updates
      - name: "Build Dinky ${{ inputs.version }} with Fink 1.15 Pre Release/Release Artifact"
        id: build_dinky1_15
        run: |
          ./mvnw -B clean package \
                  -Dmaven.test.skip=false \
                 -Dspotless.check.skip=true \
                 -Denforcer.skip=false \
                 -Dmaven.javadoc.skip=true \
                   -Pprod,scala-2.12,flink-single-version,flink-1.15,maven-central,web,fast \
                 --no-snapshot-updates

      - name: "Build Dinky ${{ inputs.version }} with Fink 1.16 Pre Release/Release Artifact"
        id: build_dinky1_16
        run: |
          ./mvnw -B clean package \
                  -Dmaven.test.skip=false \
                 -Dspotless.check.skip=true \
                 -Denforcer.skip=false \
                 -Dmaven.javadoc.skip=true \
                   -Pprod,scala-2.12,flink-single-version,flink-1.16,maven-central,web,fast \
                 --no-snapshot-updates

      - name: "Build Dinky ${{ inputs.version }} with Fink 1.17 Pre Release/Release Artifact"
        id: build_dinky1_17
        run: |
          ./mvnw -B clean package \
                  -Dmaven.test.skip=false \
                 -Dspotless.check.skip=true \
                 -Denforcer.skip=false \
                 -Dmaven.javadoc.skip=true \
                   -Pprod,scala-2.12,flink-single-version,flink-1.17,maven-central,web,fast \
                 --no-snapshot-updates

      - name: "Build Dinky ${{ inputs.version }} with Fink 1.18 Pre Release/Release Artifact"
        id: build_dinky1_18
        run: |
          ./mvnw -B clean package \
                  -Dmaven.test.skip=false \
                 -Dspotless.check.skip=true \
                 -Denforcer.skip=false \
                 -Dmaven.javadoc.skip=true \
                   -Pprod,scala-2.12,flink-single-version,flink-1.18,maven-central,web,fast \
                 --no-snapshot-updates

      - name: Automatic Upload Releases to GitHub Releases Page
        uses: "marvinpinto/action-automatic-releases@latest"
        with:
          repo_token: "${{ secrets.GITHUB_TOKEN }}"
          automatic_release_tag: "latest"
          prerelease: false
          draft: false
          upload_url: https://github.com/DataLinkDC/dinky/releases
          title: "Dinky ${{ inputs.version }} Release"
          body: |
            ${{ inputs.release_notes }}
          files: |
            ./build/dinky-release-*.tar.gz


Upstream Sync

name: Upstream Sync

permissions:
  contents: write

on:
  schedule:
    # Every day at 00:00
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  sync_latest_from_upstream:
    name: Sync latest commits from upstream repo
    runs-on: ubuntu-latest
    # only run this workflow on the main repository, not on forks (to avoid infinite loops)
    if: ${{ github.event.repository.fork && github.repository != 'DataLinkDC/dinky' }}

    steps:
      # Step 1: run a standard checkout action
      - name: Checkout target repo
        uses: actions/checkout@v3

      # Step 2: run the sync action
      - name: Sync upstream changes
        id: sync
        uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
        with:
          upstream_sync_repo: DataLinkDC/dinky
          upstream_sync_branch: dev
          target_sync_branch: dev
          target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set

          # Set test_mode true to run tests instead of the true action!!
          test_mode: false

      - name: Sync check
        if: failure()
        run: |
          echo "[Error] 由于上游仓库的 workflow 文件变更，导致 GitHub 自动暂停了本次自动更新，你需要手动 Sync Fork 一次."
          echo "[Error] Due to changes in the workflow file of the upstream warehouse, GitHub has automatically paused this automatic update. You need to manually Sync Fork once."
          exit 1


Backend

#
# 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
#
#     http://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: Backend

on:
  push:
  pull_request:
    branches:
      - dev
    paths-ignore:
      - 'docs/**'
      - '**/*.md'
      - '**/*.sql'

concurrency:
  group: backend-${{ github.event.pull_request.number || github.ref }}

jobs:
  check:
    name: Check Code
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Check Style
        run: |
          ./mvnw -T 4C -B --no-snapshot-updates clean spotless:check -P flink-all
  build_npm:
    name: Build_NPM
    runs-on: ubuntu-latest
    timeout-minutes: 30
    needs: check
    env:
      MAVEN_OPTS: -Xmx2G -Xms2G
    steps:
      - uses: actions/checkout@v3
      - uses: dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            frontend:
              - 'dinky-web/**'
      - uses: actions/setup-node@v3
        if:  steps.filter.outputs.frontend == 'true'
        with:
          node-version: 16
      - name: Get npm cache directory
        id: npm-cache-dir
        if:  steps.filter.outputs.frontend == 'true'
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@v3
        id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
        if:  steps.filter.outputs.frontend == 'true'
        with:
          path: |
            ${{ steps.npm-cache-dir.outputs.dir }}
            dinky-web/dist
          key: ${{ runner.os }}-node-${{ hashFiles('dinky-web/**/package.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
      - name: Install Dependencies
        if:  steps.filter.outputs.frontend == 'true'
        run: cd dinky-web && npm install --no-audit --progress=false --legacy-peer-deps
      - name: Npm Web Build
        if:  steps.filter.outputs.frontend == 'true'
        run: cd dinky-web && npm run build
  build_jdk:
    name: Build_JDK
    runs-on: ubuntu-latest
    needs: check
    strategy:
      fail-fast: true
      matrix:
        jdk: [8, 11]
        flink: [1.14, 1.15, 1.16, 1.17, 1.18, 1.19]

    timeout-minutes: 30
    env:
      MAVEN_OPTS: -Xmx2G -Xms2G
    steps:
      - uses: actions/checkout@v3
      # maven编译
      - name: Set up JDK ${{ matrix.jdk }}
        uses: actions/setup-java@v2
        with:
          java-version:  ${{ matrix.jdk }}
          distribution: 'adopt'
      - name: Cache local Maven repository
        uses: actions/cache@v3
        with:
          path: |
            ~/.m2/repository/*/*/*
            !~/.m2/repository/org/apache/flink
          key: ${{ runner.os }}-maven-${{ hashFiles('pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-
      - name: Cache local Flink repository
        uses: actions/cache@v3
        with:
          path: ~/.m2/repository/org/apache/flink
          key: ${{ runner.os }}-${{ matrix.flink }}-maven-${{ hashFiles('pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.flink }}-maven-
      - name: Build and Package
        run: |
          ./mvnw -B clean install \
                  -Dmaven.test.skip=false \
                 -Dspotless.check.skip=true \
                 -Denforcer.skip=false \
                 -Dmaven.javadoc.skip=true \
                 -P prod,scala-2.12,flink-single-version,flink-${{ matrix.flink }},maven-central \
                 --no-snapshot-updates

      # 检查打包的大小
      - name: Check package size
        run: |
          ./check_package_size.sh
#      - name: Run Unit tests
#        run: |
#          ./mvnw -T 2C -B clean verify -Dmaven.test.skip=false -Dgpg.skip=true --no-snapshot-updates


Code Review Robot

# 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
#
#    http://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: Code Review Robot

permissions:
  contents: read
  pull-requests: write

on:
  pull_request:
    types: [opened, reopened, synchronize]

jobs:
  code-review:
    # if: ${{ contains(github.event.*.labels.*.name, 'gpt review') }} # Optional; to run only when a label is attached
    runs-on: ubuntu-latest
    steps:
      - name: Code Review
        uses: anc95/ChatGPT-CodeReview@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          # Optional
          LANGUAGE: Chinese
          OPENAI_API_ENDPOINT: https://api.openai.com/v1
          MODEL: gpt-3.5-turbo # https://platform.openai.com/docs/models
          PROMPT: Please check if there are any confusions or irregularities in the following code diffs. If there are, please point them out. If not, please reply with "No problem". # https://platform.openai.com/docs/api-reference/completions/create#completions/create-prompt
          top_p: 1 # https://platform.openai.com/docs/api-reference/chat/create#chat/create-top_p
          temperature: 1 # https://platform.openai.com/docs/api-reference/chat/create#chat/create-temperature
          max_tokens: 10000
          MAX_PATCH_LENGTH: 10000 # if the patch/diff length is large than MAX_PATCH_LENGTH, will be ignored and won't review. By default, with no MAX_PATCH_LENGTH set, there is also no limit for the patch/diff length.


Docker Build

#
# 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
#
#     http://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: Docker Build

on:
  workflow_dispatch:
    inputs:
      dinky_version:
        description: 'dinky version'
        required: true
      docker_space:
              description: 'docker space(eg: dinky)'
              required: true

jobs:
  build_releases:
    name: build releases
    runs-on: ubuntu-latest
    strategy:
      fail-fast: true
      matrix:
        flink: [1.14,1.15,1.16,1.17,1.18,1.19]
    steps:
      # git checkout 代码
      - name: Checkout
        uses: actions/checkout@v4
      # 设置 QEMU, 后面 docker buildx 依赖此.
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      # 设置 Docker buildx, 方便构建 Multi platform 镜像
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      # 登录 docker hub
      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          # GitHub Repo => Settings => Secrets 增加 docker hub 登录密钥信息
          # DOCKERHUB_USERNAME 是 docker hub 账号名.
          # DOCKERHUB_TOKEN: docker hub => Account Setting => Security 创建.
          username: ${{ secrets.DOCKER_IO_USER  }}
          password: ${{ secrets.DOCKER_IO_PASS  }}
      # 构建 Docker 并推送到 Docker hub
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v5
        with:
          file: ./deploy/docker/Dockerfile
          # 是否 docker push
          push: true
          build-args: |
            FLINK_VERSION=${{ matrix.flink }}
            DINKY_VERSION=${{ inputs.dinky_version }}
          tags: |
            ${{inputs.docker_space}}/dinky:${{ inputs.dinky_version }}-flink${{ matrix.flink }}


Build documentation

# 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
#
#    http://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: Build documentation
on:
  schedule:
    - cron: '0 0 * * *' # Deploy every day
  workflow_dispatch:

jobs:
  build-documentation:
    if: github.repository == 'DataLinkDC/dinky'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build documentation
        run: |
          cd docs && npm install --prefer-offline --no-audit --progress=false --legacy-peer-deps --registry https://repo.huaweicloud.com/repository/npm/ \
          &&  npm run build
      - name: Upload documentation
        uses: burnett01/rsync-deployments@5.2
        with:
          switches: --archive --compress --delete-before
          path: docs/build/
          remote_path: ${{ secrets.RSYNC_PATH }}
          remote_host: ${{ secrets.RSYNC_HOST }}
          remote_port: ${{ secrets.RSYNC_PORT }}
          remote_user: ${{ secrets.RSYNC_USER }}
          remote_key: ${{ secrets.RSYNC_KEY }}


Format Code in fork repo

# 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
#
#    http://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: Format Code in fork repo

on:
  push:
    paths-ignore:
      - 'docs/**'
      - '**/*.md'
      - '**/*.sql'

concurrency:
  group: backend-${{ github.event.pull_request.number || github.ref }}

jobs:
  format:
    if: github.repository != 'DataLinkDC/dinky' && vars.FORMAT == 'true'
    name: Format Code
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
          ref: ${{ github.head_ref }}
          token: ${{ secrets.TOKEN }}
      - uses: dorny/paths-filter@v2
        id: filter
        with:
         filters: |
           frontend:
             - 'dinky-web/**'
           backend:
             - '!dinky-web/**'

      - name: Run spotless apply
        if:  steps.filter.outputs.backend == 'true'
        run : ./mvnw -T 4C -B --no-snapshot-updates clean spotless:apply -P flink-all
      - uses: actions/setup-node@v3
        if: steps.filter.outputs.frontend == 'true'
        with:
          node-version: 16
      - name: Get npm cache directory
        id: npm-cache-dir
        if: steps.filter.outputs.frontend == 'true'
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@v3
        id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
        if: steps.filter.outputs.frontend == 'true'
        with:
          path: |
            ${{ steps.npm-cache-dir.outputs.dir }}
            dinky-web/dist
          key: ${{ runner.os }}-node-${{ hashFiles('dinky-web/**/package.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
      - name: Install Dependencies
        if: steps.filter.outputs.frontend == 'true'
        run: cd dinky-web && npm install --only=dev --prefer-offline --no-audit --progress=false --legacy-peer-deps
      - name: Run frontend format
        if:  steps.filter.outputs.frontend == 'true'
        run: cd dinky-web && npm run lint:prettier

      - name: Check for modified files
        id: git-check
        run: |
          echo "modified=$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi)" >> $GITHUB_OUTPUT
      - uses: stefanzweifel/git-auto-commit-action@v4
        if: steps.git-check.outputs.modified == 'true'
        with:
          commit_message: Spotless Apply


Issue Check Inactive

# 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
#
#    http://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: Issue Check Inactive

# 定时触发：每月 1 号 UTC 0 点，即北京时间 8 点
# Timed trigger: UTC 0 on the 1st of each month.
on:
  schedule:
    - cron: "0 0 1 * *"

jobs:
  check-inactive:
    runs-on: ubuntu-latest
    steps:
      - name: check-inactive
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'check-inactive'
          token: ${{ secrets.GITHUB_TOKEN }}
          # 为 30 天不活跃的 issues 增加 inactive label，更多参数请参考：https://github.com/actions-cool/issues-helper
          # Add the inactive label to all issues that have not been active for more than 30 days. More see: https://github.com/actions-cool/issues-helper
          inactive-day: 30
          inactive-label: 'Invalid'
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue has not been active for more than 30 days. This issue will be closed in 7 days if there is no response. If you have any questions, you can comment and reply.

            你好 @${{ github.event.issue.user.login }}, 这个 issue 30 天内没有活跃，7 天后将关闭，如需回复，可以评论回复。

      - name: Add inactive labels
        if: ${{ success() }} # 代表上边的 check-inactive 成功执行 才会执行本步骤
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'add-labels'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          labels: 'Invalid'


Issue Close Require

# 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
#
#    http://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: Issue Close Require

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

permissions:
  contents: read

jobs:
  issue-close-require:
    permissions:
      issues: write  # for actions-cool/issues-helper to update issues
      pull-requests: write  # for actions-cool/issues-helper to update PRs
    runs-on: ubuntu-latest
    steps:
      - name: need reproduce
        uses: actions-cool/issues-helper@v3
        if: >-
          github.event.issue.number != 66 ||
          github.event.issue.number != 884
        with:
          actions: 'close-issues'
          labels: 'Need Reproduce'
          inactive-day: 10
          body: |
            Hi @${{ github.event.issue.user.login }}, Because this issue was marked as requiring detailed reproduction steps, no response was received for 10 days. The issue is now closed. If you have any questions, please comment and reply.

            Hi @${{ github.event.issue.user.login }}, 由于该 issue 被标记为需要提供详细复现步骤，却 10 天未收到回应。现关闭 issue，若有任何问题，可评论回复。

      - name: duplicate issue
        uses: actions-cool/issues-helper@v3
        if: >-
          github.event.issue.number != 66 ||
          github.event.issue.number != 884
        with:
          actions: 'close-issues'
          labels: 'Duplicate'
          inactive-day: 3
          body: |
            Hi @${{ github.event.issue.user.login }}, Since this issue was marked as a duplicate issue, no response was received for 3 days. The issue is now closed. If you have any questions, please comment and reply

            Hi @${{ github.event.issue.user.login }}, 由于该 issue 被标记为重复问题，却 3 天未收到回应。现关闭 issue，若有任何问题，可评论回复。

      - name: Fixed issue
        uses: actions-cool/issues-helper@v3
        if: >-
          github.event.issue.number != 66 ||
          github.event.issue.number != 884
        with:
          actions: 'close-issues'
          labels: 'Fixed'
          inactive-day: 2
          body: |
            Hi @${{ github.event.issue.user.login }}, Since this issue was marked as fixed, no response has been received for 2 days. The issue is now closed. If you have any questions, please comment and reply.

            Hi @${{ github.event.issue.user.login }}, 由于该 issue 被标记为已修复，却 2 天未收到回应。现关闭 issue，若有任何问题，可评论回复。

      - name: More Information Required
        uses: actions-cool/issues-helper@v3
        if: >-
          github.event.issue.number != 66 ||
          github.event.issue.number != 884
        with:
          actions: 'close-issues'
          labels: 'More Information Required'
          inactive-day: 7
          body: |
            Hi @${{ github.event.issue.user.login }}, Since this issue was marked as requiring more information, no response was received for 7 days. The issue is now closed. If you have any questions, please comment and reply.

            Hi @${{ github.event.issue.user.login }}, 由于该 issue 被标记为需要更多信息，却 7 天未收到回应。现关闭 issue，若有任何问题，可评论回复。


Translation Issue Robot

#
# 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
#
#     http://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: Translation Issue Robot

on:
  issues:
    types: [ opened ]
  pull_request_target:
    types: [ opened ]

jobs:
  issueRobot:
    runs-on: ubuntu-latest
    steps:
      - name: "Checkout ${{ github.ref }}"
        uses: actions/checkout@v2
        with:
          persist-credentials: false
          submodules: true

      - name: "Translation into English in issue"
        uses: ./.github/actions/translate-on-issue
        with:
          translate-title: true
          translate-body: false


Issue Reply Check

# 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
#
#    http://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: Issue Reply Check

on:
  issues:
    types: [ labeled ]

jobs:
  reply-help:
    runs-on: ubuntu-latest
    steps:
      - name: Need Provide Reproduce Steps
        if: github.event.label.name == 'Need Reproduce'
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, we need you to provide reproduction steps so that we can help you troubleshoot the problem. Issues are marked \`Need Reproduce\`.

            你好 @${{ github.event.issue.user.login }}, 我们需要你提供复现步骤以便于我们帮你排查问题，Issues 标注为 \`Need Reproduce\` 。

      - name: Action Duplicate Issue
        if: github.event.label.name == 'Duplicate'
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, thank you for your feedback, but this issue has been reported before. You can search for keywords in the Issue list to view it. Issues are marked as \`Duplicate\`.

            你好 @${{ github.event.issue.user.login }}, 感谢你的反馈, 但是此问题已经被反馈过了，你可以在 Issue 列表中搜索关键字来查看, Issues 标注为 \`Duplicate\` 。

      - name: Action Fixed Issue
        if: github.event.label.name == 'Fixed'
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, thank you for your feedback, but this issue has been fixed. You can search for keywords in the Issue list to view it. Issues are marked as \`Fixed\`.

            你好 @${{ github.event.issue.user.login }}, 感谢你的反馈, 但是此问题已经被修复了，你可以在 Issue 列表中搜索关键字来查看, Issues 标注为 \`Fixed\` 。

      - name: Action Supported Issue
        if: github.event.label.name == 'Supported'
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, thank you for your suggestion, but this function has been implemented. You can search for keywords in the Issue list to view it. Issues are marked \`Supported\`

            你好 @${{ github.event.issue.user.login }}, 感谢你的建议, 但是此功能已经实现了，你可以在 Issue 列表中搜索关键字来查看, Issues 标注为 \`Supported\` 。

      - name: Action Wont Fix Issue
        if: github.event.label.name == 'Wont Fix'
        uses: actions-cool/issues-helper@v1.7
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}, thank you for your feedback, but this issue will not be fixed. You can search for keywords in the Issue list to view it. Issues are marked \`Wont Fix\`

            你好 @${{ github.event.issue.user.login }}, 感谢你的反馈, 但是此问题不会被修复，你可以在 Issue 列表中搜索关键字来查看, Issues 标注为 \`Wont Fix\` 。


Issue Title Standard Check

name: Issue Title Standard Check

on:
  issues:
    types: [opened, edited]

jobs:
  check-issue:
    runs-on: ubuntu-latest
    steps:
      - uses: actions-cool/issues-helper@v2.2.0
        id: check
        name: Check Issue Title
        with:
          actions: 'check-issue'
          issue-number: ${{ github.event.issue.number }}
          title-excludes: '[Bug],[Feature],[Doc],[Refactor],[Optimization],[Improvement]'

      - if: steps.check.outputs.check-result == 'false' && github.event.issue.state == 'open'
        uses: actions-cool/issues-helper@v2.2.0
        name: Create Comment
        with:
          actions: 'create-comment'
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hi @${{ github.event.issue.user.login }}, It is detected that the current Issue title is not standardized. Please refer to [Issue Notes](http://www.dinky.org.cn/docs/next/developer_guide/contribution/issue) to modify it.

            你好 @${{ github.event.issue.user.login }}, 检测到当前 Issue 标题不规范, 请参考 [Issue 须知](http://www.dinky.org.cn/docs/next/developer_guide/contribution/issue) 进行修改


PR Auto Assign Reviewer

name: PR Auto Assign Reviewer

on:
  pull_request_target:
    types: [ opened ]

jobs:
  add-reviewer:
    runs-on: ubuntu-latest
    steps:
      - name: Add assignees
        uses: actions-cool/issues-helper@main
        with:
          actions: 'add-assignees'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.pull_request.number }}
          assignees: ${{ github.event.pull_request.user.login }}

      - name: Add reviewers
        uses: actions-cool/pr-welcome@main
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          pr-emoji: '+1, rocket'
          reviewers: 'zackyoungh,gaoyan1998,Zzm0809,aiwenmo'
          review-creator: false


Release Beta

name: Release Beta

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          path: './'
          fetch-depth: 0
      - name: Set up java
        uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: '17'
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
      - name: dependencies
        run: ./gradlew --no-daemon dependencies
      - name: Release to github
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          RELEASE_TARGET: ${{ github.sha }}
          PRERELEASE: true
        run: ./gradlew --no-daemon build githubRelease


Release

name: Release

on:
  workflow_dispatch:
    inputs:
      prerelease:
        description: Whether or not this is a prerelease
        type: boolean
        default: false
        required: true
#  push:
#    branches:
#      - master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          path: './'
          fetch-depth: 0
      - name: Set up java
        uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: '17'
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
      - name: dependencies
        run: ./gradlew --no-daemon dependencies
      - name: Release to github
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          USERNAME: ${{ secrets.M2_USER }}
          PASSWORD: ${{ secrets.M2_PASS }}
          # just use master
          RELEASE_TARGET: master
        run: ./gradlew --no-daemon build publish githubRelease -x test


api-gateway

name: api-gateway

on:
  push:
    paths:
      - "api-gateway/**"
    branches: [main]
  pull_request:
    paths:
      - "api-gateway/**"
    types:
      - opened
      - synchronize
      - reopened

jobs:
  build:
    name: Run Unit & Integration Tests with jdk  ${{ matrix.java }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: "api-gateway"
    strategy:
      matrix:
        java: ["21"]
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

      - uses: graalvm/setup-graalvm@v1
        with:
          distribution: 'graalvm'
          java-version: ${{ matrix.java }}
          cache: "maven"

      - name: Printing versions
        run: |
          echo "GRAALVM_HOME: $GRAALVM_HOME"
          echo "JAVA_HOME: $JAVA_HOME"
          java --version
          native-image --version

      - name: Build and analyze
        run: ./mvnw clean verify

      - if: ${{ github.ref == 'refs/heads/main' }}
        name: Build Image and push to docker
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
          DOCKER_PASSCODE: ${{secrets.DOCKER_PASSCODE}}
        run: ./mvnw spring-boot:build-image -DskipTests -DCI_DOCKER_PASSWORD=${DOCKER_PASSCODE} -DCI_DOCKER_USERNAME=dockertmt -Dspring-boot.build-image.publish=true


order-service

name: order-service

on:
  push:
    paths:
      - "order-service/**"
    branches: [main]
  pull_request:
    paths:
      - "order-service/**"
    types:
      - opened
      - synchronize
      - reopened

jobs:
  build:
    name: Order Service with jdk  ${{ matrix.java }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: "order-service"
    strategy:
      matrix:
        java: ["21"]
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

      - uses: graalvm/setup-graalvm@v1
        with:
          distribution: 'graalvm'
          java-version: ${{ matrix.java }}
          cache: "maven"

      - name: Printing versions
        run: |
          echo "GRAALVM_HOME: $GRAALVM_HOME"
          echo "JAVA_HOME: $JAVA_HOME"
          java --version
          native-image --version

      - name: Build and analyze
        run: ./mvnw clean verify

      - if: ${{ github.ref == 'refs/heads/main' }}
        name: Build Image and push to docker
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
          DOC_PASSCODE: ${{secrets.DOCKER_PASSCODE}}
          DOC_USERNAME: ${{secrets.DOCKER_USERNAME}}
        run: ./mvnw spring-boot:build-image -DskipTests -DCI_DOCKER_PASSWORD=${DOC_PASSCODE} -DCI_DOCKER_USERNAME=${DOC_USERNAME} -Dspring-boot.build-image.publish=true


catalog-service

name: catalog-service

on:
  push:
    paths:
      - "catalog-service/**"
    branches: [main]
  pull_request:
    paths:
      - "catalog-service/**"
    types:
      - opened
      - synchronize
      - reopened

jobs:
  build:
    name: Run Unit & Integration Tests with jdk  ${{ matrix.java }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: "catalog-service"
    strategy:
      matrix:
        java: ["21"]
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

      - uses: graalvm/setup-graalvm@v1
        with:
          distribution: 'graalvm'
          java-version: ${{ matrix.java }}
          cache: "maven"

      - name: Printing versions
        run: |
          echo "GRAALVM_HOME: $GRAALVM_HOME"
          echo "JAVA_HOME: $JAVA_HOME"
          java --version
          native-image --version

      - name: Build and analyze
        run: ./mvnw clean verify

      - if: ${{ github.ref == 'refs/heads/main' }}
        name: Build Image and push to docker
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
          DOCKER_PASSCODE: ${{secrets.DOCKER_PASSCODE}}
          DOC_USERNAME: ${{secrets.DOCKER_USERNAME}}
        run: ./mvnw spring-boot:build-image -DskipTests -DCI_DOCKER_PASSWORD=${DOCKER_PASSCODE} -DCI_DOCKER_USERNAME=${DOC_USERNAME}


config-server

name: config-server

on:
  push:
    paths:
      - "config-server/**"
    branches: [main]
  pull_request:
    paths:
      - "config-server/**"
    types:
      - opened
      - synchronize
      - reopened

jobs:
  build:
    name: Config Server with jdk  ${{ matrix.java }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: "config-server"
    strategy:
      matrix:
        java: ["21"]
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

      - uses: graalvm/setup-graalvm@v1
        with:
          distribution: 'graalvm'
          java-version: ${{ matrix.java }}
          cache: "maven"

      - name: Printing versions
        run: |
          echo "GRAALVM_HOME: $GRAALVM_HOME"
          echo "JAVA_HOME: $JAVA_HOME"
          java --version
          native-image --version

      - name: Build and analyze
        run: ./mvnw clean verify

      - if: ${{ github.ref == 'refs/heads/main' }}
        name: Build Image and push to docker
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
          DOCKER_PASSCODE: ${{secrets.DOCKER_PASSCODE}}
          DOC_USERNAME: ${{secrets.DOCKER_USERNAME}}
        run: ./mvnw spring-boot:build-image -Dspring-boot.build-image.publish=true -DCI_DOCKER_PASSWORD=${DOCKER_PASSCODE} -DCI_DOCKER_USERNAME=${DOC_USERNAME}