CI

# Thanks to https://github.com/coil-kt/coil/blob/master/.github/workflows/ci.yml
name: CI

on:
  push:
    tags:
      - '*'
  pull_request:

jobs:
  publish_archives:
    name: Publish Archives
    if: startsWith(github.ref, 'refs/tags/')

    strategy:
      matrix:
        os: [macos-14, ubuntu-latest, windows-latest]

    runs-on: ${{matrix.os}}

    steps:
      - name: Checkout the repo
        uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: |
            11
            15
            17

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Cache konan
        uses: actions/cache@v4
        with:
          path: ~/.konan
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
          restore-keys: |
            gradle-${{ runner.os }}-

      - name: Prepare Gradle Publish properties
        if: matrix.os == 'ubuntu-latest'
        run: |
          echo "gradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}" >> ~/.gradle/gradle.properties
          echo "gradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}" >> ~/.gradle/gradle.properties

      - name: Release Plugin
        if: matrix.os == 'ubuntu-latest'
        run: |
          cd plugin-build
          ./gradlew publishPlugins | true

      - name: Publish the macOS artifacts
        if: matrix.os == 'macos-14'
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_USERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.NEXUS_PASSWORD }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_PRIVATE_KEY }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}
        run: |
          ./gradlew aboutlibraries-core:publishAllPublicationsToMavenCentralRepository --no-daemon -Plibrary_core_only --no-configure-on-demand --no-parallel
          ./gradlew aboutlibraries-compose-m2:publishAllPublicationsToMavenCentralRepository -x test -x lint -Plibrary_compose_only --no-configure-on-demand --no-parallel
          ./gradlew aboutlibraries-compose-m3:publishAllPublicationsToMavenCentralRepository -x test -x lint -Plibrary_compose_m3_only --no-configure-on-demand --no-parallel

      - name: Publish the windows artifact
        if: matrix.os == 'windows-latest'
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_USERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.NEXUS_PASSWORD }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_PRIVATE_KEY }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}
        run: ./gradlew aboutlibraries-core:publishMingwX64PublicationToMavenCentralRepository -Plibrary_core_only --no-configure-on-demand --no-parallel

      - name: Publish the linux artifact
        if: matrix.os == 'ubuntu-latest'
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_USERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.NEXUS_PASSWORD }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_PRIVATE_KEY }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}
        run: |
          ./gradlew aboutlibraries-core:publishLinuxX64PublicationToMavenCentralRepository -Plibrary_core_only --no-configure-on-demand --no-parallel
          ./gradlew aboutlibraries:publishAllPublicationsToMavenCentralRepository -x test -x lint -Plibrary_only --no-configure-on-demand --no-parallel

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 100

      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: |
            11
            15
            17

      - name: Validate gradle wrapper
        uses: gradle/wrapper-validation-action@v2

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Publish plugin locally
        run: |
          cd plugin-build
          ./gradlew publishToMavenLocal

      - name: Build Debug
        run: ./gradlew app:assembleDebug

      - name: Run Lint
        if: github.event_name  == 'pull_request'
        run: ./gradlew lintDebug

      - name: Setup Ruby
        if: github.event_name  == 'pull_request'
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.0'
          bundler-cache: true

      - name: Run Danger
        if: github.event_name  == 'pull_request'
        run: |
          gem install danger
          bundle exec danger --dangerfile=Dangerfile --danger_id=danger-pr
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Prepare Keystore and Local.
        if: startsWith(github.ref, 'refs/tags/')
        run: |
          echo "${{ secrets.KEYSTORE }}" > opensource.jks.asc
          gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch "opensource.jks.asc" > "app/opensource.jks"
          echo "${{ secrets.SIGNING_GRADLE }}" > signing.gradle.asc
          gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch "signing.gradle.asc" > "app/signing.gradle"
          echo "openSource.signing.file=signing.gradle" >> local.properties

      - name: Build Release App
        if: startsWith(github.ref, 'refs/tags/')
        run: ./gradlew app:assembleStaging app:assembleRelease app:bundleRelease

      - name: Collect artifacts
        run: |
          COLLECT_PWD=${PWD}
          mkdir -p "artifacts"
          find . -name "*-staging.apk" -type f -exec cp {} "artifacts" \;
          find . -name "*-release.apk" -type f -exec cp {} "artifacts" \;
          find . -name "*-release.aab" -type f -exec cp {} "artifacts" \;

      - name: Archive Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: "App-Artifacts"
          path: artifacts/*

      - name: Build Changelog
        id: github_release
        uses: mikepenz/release-changelog-builder-action@v4
        if: startsWith(github.ref, 'refs/tags/')
        with:
          configuration: ".github/config/configuration.json"
          ignorePreReleases: ${{ !contains(github.ref, '-') }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Release
        uses: mikepenz/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          body: ${{steps.github_release.outputs.changelog}}
          prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-b') || contains(github.ref, '-a') }}
          files: artifacts/*
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Gradle Dependency Submission

name: Gradle Dependency Submission
on:
  push:
    branches:
      - develop

jobs:
  gradle-dependency-detection:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: 'Checkout Repository'
        uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: |
            11
            15
            17

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Setup Gradle & Submit dependency graphs
        uses: gradle/actions/setup-gradle@v3
        with:
          dependency-graph: generate-and-submit


Deploy static content to Pages

# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
  push:
    tags:
      - '*'

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Pages
        uses: actions/configure-pages@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: |
            11
            17
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3
      - name: Build Page
        run: |
          ./gradlew :app-wasm:exportLibraryDefinitions -PaboutLibraries.exportPath=src/commonMain/composeResources/files/
          ./gradlew :app-wasm:wasmJsBrowserDistribution --no-configuration-cache

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: 'app-wasm/build/dist/wasmJs/productionExecutable'

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


Build example projects and publish them to s3


Publish preview to web (S3)

name: Publish preview to web (S3)

on: [ push, workflow_dispatch ]

env:
  branch-name: ${GITHUB_REF#refs/heads/}
  bucket-name: 'dokka-snapshots'

jobs:
  kotlinx-coroutines:
    runs-on: ubuntu-latest
    if: github.repository == 'Kotlin/dokka'
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Document coroutines
        run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxCoroutines --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m"
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/coroutines
      - name: Configure AWS credentials for S3 access
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: eu-central-1
      - name: Copy files to dokka's S3 bucket
        run: ./dokka-integration-tests/aws_sync.sh s3://${{ env.bucket-name }} coroutines ../coroutines
      - name: Print link
        run: echo https://dokka-snapshots.s3.eu-central-1.amazonaws.com/${{ env.branch-name }}/coroutines/${GITHUB_SHA::7}/index.html

  kotlinx-serialization:
    runs-on: ubuntu-latest
    if: github.repository == 'Kotlin/dokka'
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Document serialization
        run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxSerialization --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m"
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/serialization
      - name: Configure AWS credentials for S3 access
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: eu-central-1
      - name: Copy files to dokka's S3 bucket
        run: ./dokka-integration-tests/aws_sync.sh s3://${{ env.bucket-name }} serialization ../serialization
      - name: Print link
        run: echo https://dokka-snapshots.s3.eu-central-1.amazonaws.com/${{ env.branch-name }}/serialization/${GITHUB_SHA::7}/index.html

  ui-showcase:
    runs-on: ubuntu-latest
    if: github.repository == 'Kotlin/dokka'
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Generate ui-showcase documentation
        run: ./gradlew :dokka-integration-tests:gradle:testUiShowcaseProject
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/ui-showcase
      - name: Configure AWS credentials for S3 access
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: eu-central-1
      - name: Copy files to dokka's S3 bucket
        run: ./dokka-integration-tests/aws_sync.sh s3://${{ env.bucket-name }} ui-showcase ../ui-showcase
      - name: Print link
        run: echo https://dokka-snapshots.s3.eu-central-1.amazonaws.com/${{ env.branch-name }}/ui-showcase/${GITHUB_SHA::7}/index.html

  biojava:
    runs-on: ubuntu-latest
    if: github.repository == 'Kotlin/dokka'
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
          cache: 'maven'
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Document biojava-core
        run: ./gradlew :dokka-integration-tests:maven:testExternalProjectBioJava --stacktrace
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/biojava
      - name: Configure AWS credentials for S3 access
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: eu-central-1
      - name: Copy files to dokka's S3 bucket
        run: ./dokka-integration-tests/aws_sync.sh s3://${{ env.bucket-name }} biojava ../biojava
      - name: Print link
        run: echo https://dokka-snapshots.s3.eu-central-1.amazonaws.com/${{ env.branch-name }}/biojava/${GITHUB_SHA::7}/index.html


Test [smoke]

name: Test [smoke]

on: pull_request

concurrency:
  group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
  cancel-in-progress: true

env:
  JAVA_TEST_VERSION: 11

jobs:
  test-matrix:
    strategy:
      matrix:
        os: [ ubuntu-latest, windows-latest ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - name: Set longpaths support for Windows
        if: matrix.os == 'windows-latest'
        # Avoid failing tests on Windows with "cannot create directory at X. Filename too long"
        # This command will fail if run on a Linux build agent with "could not lock config file: Permission denied"
        run: git config --system core.longpaths true
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Run tests
        run: >
          ./gradlew test --stacktrace --continue
          "-Porg.jetbrains.dokka.javaToolchain.testLauncher=${{ env.JAVA_TEST_VERSION }}"


name: Publish preview to GitHub Actions Artifacts

on:
  pull_request:
  push:
    branches:
      - master
  workflow_dispatch:

jobs:
  kotlinx-coroutines:
    runs-on: ubuntu-latest
    if: >  # Run this job only for pull requests from forks because members with write access have web preview
      github.event_name != 'pull_request' ||
      (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Kotlin/dokka')
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Document coroutines
        run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxCoroutines --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m"
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/coroutines
      - name: Copy files to GitHub Actions Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dokka-coroutines
          path: /home/runner/work/dokka/coroutines
          retention-days: 7

  kotlinx-serialization:
    runs-on: ubuntu-latest
    if: >  # Run this job only for pull requests from forks because members with write access have web preview
      github.event_name != 'pull_request' ||
      (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Kotlin/dokka')
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Document serialization
        run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxSerialization --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m"
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/serialization
      - name: Copy files to GitHub Actions Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dokka-serialization
          path: /home/runner/work/dokka/serialization
          retention-days: 7

  biojava:
    runs-on: ubuntu-latest
    if: >  # Run this job only for pull requests from forks because members with write access have web preview
      github.event_name != 'pull_request' ||
      (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Kotlin/dokka')
    steps:
      - name: Checkout dokka
        uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Document biojava-core
        run: ./gradlew :dokka-integration-tests:maven:integrationTest --tests org.jetbrains.dokka.it.maven.BiojavaIntegrationTest --stacktrace
        env:
          DOKKA_TEST_OUTPUT_PATH: /home/runner/work/dokka/biojava
      - name: Copy files to GitHub Actions Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dokka-biojava
          path: /home/runner/work/dokka/biojava
          retention-days: 7


API check

name: API check

on: pull_request

concurrency:
  group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
  cancel-in-progress: true

jobs:
  apiCheck:
    name: binary compatibility
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - run: ./gradlew apiCheck --stacktrace


Gradle check

name: Gradle check

on:
  push:
    branches:
      - master
  pull_request:
    paths:
      - 'gradle/**'

jobs:
  wrapper:
    name: wrapper checksums
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: gradle/wrapper-validation-action@v2


Build examples

name: Build examples

on:
  pull_request:
    paths:
      - 'examples/**'

concurrency:
  group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
  cancel-in-progress: true

jobs:
  build:
    strategy:
      matrix:
        projects: [
          examples/gradle/dokka-gradle-example,
          examples/gradle/dokka-kotlinAsJava-example,
          examples/gradle/dokka-library-publishing-example,
          examples/gradle/dokka-multimodule-example,
          examples/gradle/dokka-multiplatform-example,
          examples/gradle/dokka-customFormat-example
        ]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - '${{ matrix.projects }}/**'
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - run: ./gradlew build --no-daemon --stacktrace
        working-directory: ${{ matrix.projects }}
        if: steps.filter.outputs.examples_changed == 'true'

  run-dokka-html:
    strategy:
      matrix:
        projects: [
          examples/gradle/dokka-gradle-example,
          examples/gradle/dokka-kotlinAsJava-example,
          examples/gradle/dokka-library-publishing-example,
          examples/gradle/dokka-multiplatform-example,
          examples/gradle/dokka-customFormat-example
        ]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - '${{ matrix.projects }}/**'
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - run: ./gradlew dokkaHtml --no-daemon --stacktrace
        working-directory: ${{ matrix.projects }}
        if: steps.filter.outputs.examples_changed == 'true'

  run-dokka-publishing:
    strategy:
      matrix:
        tasks: [ dokkaJavadocJar, dokkaHtmlJar ]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - 'examples/gradle/dokka-library-publishing-example/**'
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - run: ./gradlew ${{ matrix.tasks }} --no-daemon --stacktrace
        working-directory: examples/gradle/dokka-library-publishing-example
        if: steps.filter.outputs.examples_changed == 'true'

  run-dokka-gradle-tasks:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - task: "dokkaHtmlMultiModule"
            dir: "examples/gradle/dokka-multimodule-example"
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - '${{ matrix.dir }}/**'
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - run: ./gradlew ${{ matrix.task }} --no-daemon --stacktrace
        working-directory: ${{ matrix.dir }}
        if: steps.filter.outputs.examples_changed == 'true'

  run-dokka-maven-example:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - 'examples/maven/**'
          working-directory: examples/maven
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
          cache: 'maven'
      - run: mvn compile dokka:dokka
        working-directory: examples/maven
        if: steps.filter.outputs.examples_changed == 'true'


Deploy examples to GitHub Pages

name: Deploy examples to GitHub Pages

on:
  push:
    branches:
      - master
    paths:
      - 'examples/**'

jobs:
  build-examples:
    runs-on: ubuntu-latest
    if: github.repository == 'Kotlin/dokka'
    strategy:
      matrix:
        projects: [
          dokka-gradle-example,
          dokka-kotlinAsJava-example,
          dokka-library-publishing-example,
          dokka-multiplatform-example,
          dokka-customFormat-example
        ]
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - 'examples/gradle/${{ matrix.projects }}/**'
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Build html
        run: ./gradlew dokkaHtml --no-daemon --stacktrace
        working-directory: examples/gradle/${{ matrix.projects }}
        if: steps.filter.outputs.examples_changed == 'true'
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        if: steps.filter.outputs.examples_changed == 'true'
        with:
          name: ${{ matrix.projects }}
          path: examples/gradle/${{ matrix.projects }}/build/dokka

  build-multimodule-examples:
    runs-on: ubuntu-latest
    if: github.repository == 'Kotlin/dokka'
    strategy:
      matrix:
        projects: [
          dokka-versioning-multimodule-example,
          dokka-multimodule-example
        ]
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            examples_changed:
              - 'examples/gradle/${{ matrix.projects }}/**'
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
          cache: 'maven'
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Build html
        run: ./gradlew dokkaHtmlMultiModule --no-daemon --stacktrace
        working-directory: examples/gradle/${{ matrix.projects }}
        if: steps.filter.outputs.examples_changed == 'true'
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        if: steps.filter.outputs.examples_changed == 'true'
        with:
          name: ${{ matrix.projects }}
          path: examples/gradle/${{ matrix.projects }}/parentProject/build/dokka

  deploy-examples:
    runs-on: ubuntu-latest
    needs: [ build-examples, build-multimodule-examples ]
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: public/examples
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          keep_files: true
          publish_dir: ./public
          full_commit_message: Publish examples


Clean up S3

name: Clean up S3

on: delete

env:
  bucket-name: 'dokka-snapshots'

jobs:
  cleanup:
    name: Branch preview
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS credentials for S3 access
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: eu-central-1
      - name: Delete branch from s3
        run: aws s3 --recursive rm s3://${{ env.bucket-name }}/${{ github.event.ref }}


Test [thorough]

name: Test [thorough]

on:
  workflow_dispatch:
  push:
    branches:
      - master

jobs:
  test-matrix:
    strategy:
      matrix:
        os: [ ubuntu-latest, windows-latest, macos-latest ]
        javaVersion: [ 8, 11, 17, 21 ]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - name: Set longpaths support for Windows
        if: matrix.os == 'windows-latest'
        # Avoid failing tests on Windows with "cannot create directory at X. Filename too long"
        # This command will fail if run on a Linux build agent with "could not lock config file: Permission denied"
        run: git config --system core.longpaths true
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Run tests
        run: >
          ./gradlew test --stacktrace --continue
          "-Porg.jetbrains.dokka.javaToolchain.testLauncher=${{ matrix.javaVersion }}"


Deploy developer docs to GitHub Pages

name: Deploy developer docs to GitHub Pages

on:
  workflow_dispatch:
  push:
    branches:
      - master
    paths:
      - 'docs-developer/**'
  release:
    types: [ published ]

jobs:
  docs:
    if: github.repository == 'Kotlin/dokka'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          path: dokka
      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
      - name: Get current Dokka version
        run: echo "DOKKA_VERSION=`./gradlew :properties | grep '^version:.*' | cut -d ' ' -f 2`" >> $GITHUB_ENV
        working-directory: ./dokka
      - name: Build docs
        run: ./gradlew buildMkDocsSite -Pdokka_version=$DOKKA_VERSION --info
        working-directory: ./dokka
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dokka/docs-developer/build/mkdocs
          keep_files: true
          full_commit_message: Publish ${{ env.DOKKA_VERSION }} documentation


Qodana

name: Qodana

on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - master

concurrency:
  group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
  cancel-in-progress: true

jobs:
  inspection:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: 'Qodana Scan'
        uses: JetBrains/qodana-action@v2022.2.3
        with:
          args: --baseline,qodana.sarif.json,--fail-threshold,0,--linter,jetbrains/qodana-jvm
        env:
          QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
      - uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json


Close and Release Repository

name: Close and Release Repository
on: workflow_dispatch

jobs:
  publish:
    runs-on: [ubuntu-latest]

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

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

    - name: Close and Release Staging Repository
      run: ./gradlew closeAndReleaseStagingRepository
      env:
        ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_NEXUS_USERNAME }}
        ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_NEXUS_PASSWORD }}


Validate Gradle Wrapper

name: Validate Gradle Wrapper
on:
  push:
      branches:
      - develop
  pull_request:
    branches:
      - '*'
  workflow_dispatch:
    branches:
      - '*'

jobs:
  validation:
    name: Validation
    runs-on: ubuntu-latest
    steps:
    - name: Checkout latest code
      uses: actions/checkout@v4
    - name: Validate Gradle Wrapper
      uses: gradle/wrapper-validation-action@v3


Pre Merge Checks

name: Pre Merge Checks
on:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - '*'
  workflow_dispatch:
    branches:
      - '*'

jobs:
  test:
    runs-on: [ubuntu-latest]

    steps:
    - name: Cancel Previous Runs
      if: github.event_name == 'pull_request'
      uses: styfle/cancel-workflow-action@0.12.1
      with:
        access_token: ${{ github.token }}

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

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

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Run all the tests
      run: ./gradlew test

  detekt:
    runs-on: [ubuntu-latest]

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

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

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Run detekt
      run: ./gradlew detekt

  lint:
    runs-on: [ubuntu-latest]

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

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

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v3

      - name: Run lint
        run: ./gradlew lint

  ktlint:
    runs-on: [ubuntu-latest]

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

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

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Run ktlint
      run: ./gradlew ktlintCheck

  api-check:
    runs-on: [ubuntu-latest]

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

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

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v3

      - name: Run apiCheck
        run: ./gradlew apiCheck

  publish-artifact:
    runs-on: [ubuntu-latest]

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

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

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Publish to Maven Local
      run: ./gradlew publishToMavenLocal
      env:
        ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
        ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}

    - name: Upload Build Artifacts
      uses: actions/upload-artifact@v4
      with:
        name: 'chucker-local-artifacts'
        path: '~/.m2/repository/'


Publish Release

name: Publish Release
on:
  push:
    tags:
      - '*'

jobs:
  publish:
    if: ${{ github.repository == 'ChuckerTeam/chucker'}}
    runs-on: [ubuntu-latest]

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

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

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Publish to Maven Local
      run: ./gradlew publishToMavenLocal
      env:
        ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
        ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}

    - name: Upload Build Artifacts
      uses: actions/upload-artifact@v4
      with:
        name: 'chucker-release-artifacts'
        path: '~/.m2/repository/'

    - name: Publish to the Staging Repository
      run: ./gradlew publishReleasePublicationToStagingRepository --no-parallel
      env:
        ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
        ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
        ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_NEXUS_USERNAME }}
        ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_NEXUS_PASSWORD }}


Publish Snapshot

name: Publish Snapshot
on:
  push:
    branches:
      - main

jobs:
  publish:
    if: ${{ github.repository == 'ChuckerTeam/chucker'}}
    runs-on: [ubuntu-latest]

    steps:
    - name: Cancel Previous Runs
      uses: styfle/cancel-workflow-action@0.12.1
      with:
        access_token: ${{ github.token }}

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

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

    - name: Setup Gradle
      uses: gradle/gradle-build-action@v3

    - name: Publish to Maven Local
      run: ./gradlew publishToMavenLocal
      env:
        ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
        ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}

    - name: Upload Build Artifacts
      uses: actions/upload-artifact@v4
      with:
        name: 'chucker-snapshot-artifacts'
        path: '~/.m2/repository/'

    - name: Publish to the Snapshot Repository
      run: ./gradlew publishReleasePublicationToSnapshotRepository --no-parallel
      env:
        ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }}
        ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }}
        ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_NEXUS_USERNAME }}
        ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_NEXUS_PASSWORD }}


Pull Request Check

name: Pull Request Check

on:
  pull_request:
    branches:
      - master
      - '*.x.x'
    paths-ignore:
      - 'website/**'
      - '*.md'

jobs:
  build-libraries:
    uses: ./.github/workflows/build-libraries.yml

  plugin-integration:
    needs: build-libraries
    uses: ./.github/workflows/plugin-it.yml

  build-examples:
    needs: build-libraries
    uses: ./.github/workflows/build-examples.yml

  graalvm-integration:
    needs: build-libraries
    uses: ./.github/workflows/graalvm-integration.yml


Pull Request Check Documentation

name: Pull Request Check Documentation

on:
  pull_request:
    branches:
      - master
    paths:
      - 'website/**'

jobs:
  check-docs:
    timeout-minutes: 10
    runs-on: ubuntu-latest
    if: github.repository == 'ExpediaGroup/graphql-kotlin'

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('website/package-lock.json') }}
          restore-keys: ${{ runner.os }}-node-

      - name: Build website
        run: |
          cd website
          npm install
          npm run build


Continuous Integration

name: Continuous Integration

on:
  push:
    branches:
      - master
      - '*.x.x'
    paths-ignore:
      - 'website/**'

jobs:
  build-libraries:
    uses: ./.github/workflows/build-libraries.yml

  plugin-integration:
    needs: build-libraries
    uses: ./.github/workflows/plugin-it.yml

  build-examples:
    needs: build-libraries
    uses: ./.github/workflows/build-examples.yml

  federation-integration:
    needs: build-libraries
    uses: ./.github/workflows/federation-integration.yml

  http-spec-compliance:
    needs: build-libraries
    uses: ./.github/workflows/http-spec-compliance.yml

  graalvm-integration:
    needs: build-libraries
    uses: ./.github/workflows/graalvm-integration.yml

  release-notes:
    timeout-minutes: 10
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: read
    steps:
      - name: Release Drafter
        uses: release-drafter/release-drafter@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Publish Latest Docs

name: Publish Latest Docs

on:
  push:
    branches:
      - master
    paths:
      - 'website/**'

jobs:
  publish-docs:
    permissions:
      contents: write
    timeout-minutes: 10
    runs-on: ubuntu-latest
    if: github.repository == 'ExpediaGroup/graphql-kotlin'

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('website/package-lock.json') }}
          restore-keys: ${{ runner.os }}-node-

      - name: Build website
        run: |
          cd website
          npm install
          npm run build

      - name: Deploy GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./website/build
          user_name: eg-oss-ci
          user_email: oss@expediagroup.com


Release Code

name: Release Code

on:
  release:
    types: [ published ]

jobs:
  release-code:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    if: github.repository == 'ExpediaGroup/graphql-kotlin'

    steps:
      - uses: actions/checkout@v3

      - uses: gradle/wrapper-validation-action@v1

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

      - name: Build library with Gradle
        run: ./gradlew clean build

      - name: Publish library with Gradle
        run: |
          NEW_VERSION=$(echo "${GITHUB_REF}" | cut -d "/" -f3)
          echo "New version: ${NEW_VERSION}"
          ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository publishPlugins -Pversion=${NEW_VERSION}
        env:
          SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
          SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
          GPG_SECRET: ${{ secrets.GPG_PRIVATE_KEY }}
          GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }}
          PLUGIN_PORTAL_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
          PLUGIN_PORTAL_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}

      - name: Archive failure build reports
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: build-reports
          path: |
            ./**/build/reports
          retention-days: 7


Build and Test Examples

name: Build and Test Examples

on:
  workflow_call:

jobs:
  build:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: examples

    steps:
      - uses: actions/checkout@v3

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

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

      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2

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

      - name: Build examples with Gradle
        run: ./gradlew clean build

      - name: Archive examples failure build reports
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: build-examples-reports
          path: ./examples/**/build/reports
          retention-days: 7


Build and Test Libraries

name: Build and Test Libraries

on:
  workflow_call:

jobs:
  build:
    timeout-minutes: 30
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

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

      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2

      - name: Build libraries with Gradle
        run: ./gradlew clean build

      - name: Archive failure build reports
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: build-reports
          path: |
            ./**/build/reports
            plugins/graphql-kotlin-maven-plugin/build/integration/**/build.log
            plugins/graphql-kotlin-maven-plugin/build/integration/**/target/surefire-reports
          retention-days: 7


Pull Request Federation Check

name: Pull Request Federation Check

on:
  pull_request:
    branches:
      - master
    paths:
      - 'generator/graphql-kotlin-federation/**'
      - 'integration/federation-compatibility/**'

jobs:
  federation-integration:
    permissions:
      pull-requests: write
    uses: ./.github/workflows/federation-integration.yml
    secrets:
      token: ${{ secrets.GITHUB_TOKEN }}


Plugin Integration Tests

name: Plugin Integration Tests

on:
  workflow_call:

jobs:
  android-test:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: integration/gradle-plugin-android-test

    steps:
      - uses: actions/checkout@v3
      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1
      - name: Set up Java 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'
      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2
      - name: Android Test
        run: ./gradlew build
      - name: Archive failures
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: gradle-plugin-android-build-reports
          path: integration/gradle-plugin-android-test/**/build/reports
          retention-days: 7

  gradle-integration-tests:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: integration/gradle-plugin-integration-tests

    steps:
      - uses: actions/checkout@v3
      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1
      - name: Set up Java 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'
      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2
      - name: Integration Tests
        run: ./gradlew build
      - name: Archive failures
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: gradle-plugin-build-reports
          path: integration/gradle-plugin-integration-tests/**/build/reports
          retention-days: 7

  maven-integration-tests:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: integration/maven-plugin-integration-tests

    steps:
      - uses: actions/checkout@v3
      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1
      - name: Set up Java 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'zulu'
          cache: 'maven'
      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2
      - name: Integration Tests
        run: ./gradlew build
      - name: Archive failures
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: maven-plugin-build-reports
          path: |
            integration/maven-plugin-integration-tests/build/integration/**/build.log
            integration/maven-plugin-integration-tests/build/integration/**/target/surefire-reports
          retention-days: 7


Federation Integration Tests

name: Federation Integration Tests

on:
  workflow_call:
    secrets:
      token:
        required: false

jobs:
  composition:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: examples/federation

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

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

      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2

      - name: Build Subgraphs
        working-directory: examples
        run: ./gradlew :federation-products-subgraph:build :federation-reviews-subgraph:build

      - name: Setup rover CLI
        run: |
          curl -sSL https://rover.apollo.dev/nix/latest | sh -s -- --elv2-license accept
          echo "$HOME/.rover/bin" >> ${GITHUB_PATH}

      - name: Compose Supergraph
        run: APOLLO_ELV2_LICENSE=accept rover supergraph compose --config supergraph.yaml > supergraph.graphql

      - name: Start router
        run: docker compose up --build --detach --wait

      - name: Federation Tests
        run: |
          set -x
          echo "verify router is up"
          curl --verbose http://localhost:8088/health

          echo "sending a test query"
          curl --request POST \
            --verbose \
            --header 'content-type: application/json' \
            --url http://localhost:3000/ \
            --data '{"query":"query($productId: ID!) {\n  product(id: $productId) {\n    id\n    reviews {\n      id\n      text\n      starRating\n    }\n    name\n    description\n  }\n}","variables":{"productId":"5"}}' \
            > response.json

          echo "received GraphQL response"
          cat response.json

          echo "verifying response"
          jq -e '.data.product?.id == "5" and .data.product?.name == "Dragon" and (.data.product?.reviews | length == 2) and (.data.product?.reviews[0]?.text | length > 0)' response.json
      - name: Error Logs
        if: ${{ failure() }}
        run: docker-compose logs
      - name: Stop Supergraph
        if: ${{ always() }}
        run: docker compose down --remove-orphans

  compatibility:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: integration/federation-compatibility

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

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

      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2

      - name: Build compatibility app with Gradle
        run: ./gradlew bootJar graphqlGenerateSDL

      - name: Compatibility Test
        uses: apollographql/federation-subgraph-compatibility@v2
        with:
          compose: 'docker-compose.yaml'
          schema: 'build/schema.graphql'
          failOnWarning: true
          failOnRequired: true
          workingDirectory: 'integration/federation-compatibility'
          token: ${{ secrets.token }}


name: GraphQL over HTTP spec server compliance

on:
  workflow_call:
  pull_request:
    branches:
      - master
    paths:
      - 'servers/**'
      - 'integration/graphql-http-spec/**'

jobs:
  http-spec-compliance:
    timeout-minutes: 20
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: integration/graphql-http-spec
    strategy:
      matrix:
        server: ['spring-server', 'ktor-server']

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Setup NPM cache
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('website/package-lock.json') }}
          restore-keys: ${{ runner.os }}-node-

      - name: Install node dependencies
        run: npm install

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

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

      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2

      - name: Start server
        id: start_server
        run: |
          set -x
          echo "building server"
          ./gradlew :${server}:build

          echo "starting server"
          ./gradlew :${server}:run &
          echo "SERVER_PID=$(echo $!)" >> $GITHUB_OUTPUT
        env:
          server: ${{ matrix.server }}

      - name: Verify HTTP spec compliance
        run: |
          echo "verify server is up"
          npm run healthcheck

          echo "verify compliance"
          npm run test

      - name: Stop server
        if: ${{ always() }}
        run: |
          echo "shutting down server"
          kill -9 ${{ steps.start_server.outputs.SERVER_PID }}


GraalVM Integration Tests

name: GraalVM Integration Tests

on:
  workflow_call:
  pull_request:
    branches:
      - master
    paths:
      - 'integration/graalvm/**'

jobs:
  graalvm-integration:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: integration/graalvm
    strategy:
      max-parallel: 1
      matrix:
        server: ['ktor-graalvm-server', 'maven-graalvm-server', 'spring-graalvm-server']

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

      - name: Setup GraalVM
        uses: graalvm/setup-graalvm@v1
        with:
          java-version: '17'
          distribution: 'graalvm'
          components: 'native-image'
          native-image-job-reports: 'true'

      - name: Set up Gradle cache
        uses: gradle/gradle-build-action@v2

      - name: Build native image
        timeout-minutes: 20
        id: build_server
        run: |
          ./gradlew :${server}:buildGraalVmNativeImage
          echo "NATIVE_IMAGE=$(echo "${server}/build/native/nativeCompile/${server}")" >> $GITHUB_OUTPUT
        env:
          server: ${{ matrix.server }}

      - name: Start the native image
        id: start_server
        run: |
          set -x
          echo "starting server"
          ./${nativeImage} &
          echo "SERVER_PID=$(echo $!)" >> $GITHUB_OUTPUT
        env:
          nativeImage: ${{ steps.build_server.outputs.NATIVE_IMAGE }}

      - name: Integration Test
        run: |
          echo "sending a test query"
          curl --request POST \
            --verbose \
            --header 'content-type: application/json' \
            --url http://localhost:8080/graphql \
            --data '{"query":"query($inputArg: InputOnlyInput){ inputTypeQuery(arg: $inputArg) }","variables":{"inputArg": { "id": 123 }}}' \
            > response.json

          echo "received GraphQL response"
          cat response.json

          echo "verifying response"
          jq -e '.data.inputTypeQuery == "InputOnly(id=123)"' response.json

      - name: Stop server
        if: ${{ always() }}
        run: |
          echo "shutting down server"
          kill -9 ${{ steps.start_server.outputs.SERVER_PID }}


Bump our Calendar Version

name: Bump our Calendar Version

on:
  workflow_dispatch:
  schedule:
    - cron: '30 3 1 * *'
jobs:
  tag:
    name: Tag Monthly Release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Get Current Time
        uses: josStorer/get-current-time@v2.1.2
        id: current-time

      - name: Bump Calendar Version
        uses: rickstaa/action-create-tag@v1.7.2
        with:
          tag: ${{ steps.current-time.outputs.year }}.${{ steps.current-time.outputs.month }}.0


On Push

name: On Push

on:
  workflow_dispatch:
    inputs:
      beta:
        description: 'true if this is a beta release'
        required: false
        default: 'false'
  push:
    branches:
      - master

env:
  SUPPLY_UPLOAD_MAX_RETRIES: 5

jobs:
  app_build:
    name: Github, Firebase, and Sentry Release
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up JDK 17
        uses: actions/setup-java@v4.2.1
        with:
          distribution: 'temurin'
          java-version: '17'

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true

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

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - uses: ./.github/actions/create-release-number
        name: Create Release Number
        id: rel_number

      - uses: ./.github/actions/inflate-secrets
        name: Inflate Secrets
        with:
          keystore: ${{ secrets.ORIGINAL_KEYSTORE_FILE }}
          google-services: ${{ secrets.GOOGLESERVICES }}
          firebase-creds: ${{ secrets.FIREBASECREDS }}
          playstore-creds: ${{ secrets.PLAYSTORECREDS }}

      - uses: ./.github/actions/create-release-notes
        name: Create Release Notes
        with:
          tag-name: ${{ steps.rel_number.outputs.version }}
          gh-token: ${{ secrets.GITHUB_TOKEN }}

      - uses: ./.github/actions/download-translations
        name: Download Translations
        with:
          lokalise-project: ${{ secrets.LOKALISE_PROJECT }}
          lokalise-token: ${{ secrets.LOKALISE_TOKEN }}

      - name: Build Release
        env:
          KEYSTORE_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_FILE_PASSWORD }}
          KEYSTORE_ALIAS: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS }}
          KEYSTORE_ALIAS_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS_PASSWORD }}
          VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
        run: |
          ./gradlew :common:assemble
          ./gradlew :app:assembleRelease
          ./gradlew :wear:assembleRelease
          ./gradlew :automotive:assembleRelease

      - name: Archive Build
        uses: actions/upload-artifact@v4
        with:
          path: ./**/*.apk

      - name: Create Version File
        if: github.event.inputs.beta == 'true'
        shell: bash
        env:
          VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
        run: |
          echo $VERSION_CODE > ./app/build/outputs/version_code.txt

      - name: Create Github Pre-Release
        if: github.event.inputs.beta == 'true'
        uses: softprops/action-gh-release@v2.0.6
        with:
          tag_name: ${{ steps.rel_number.outputs.version }}
          body_path: ./app/build/outputs/changelogGithub
          draft: false
          prerelease: true
          files: |
            ./app/build/outputs/apk/full/release/app-full-release.apk
            ./app/build/outputs/apk/minimal/release/app-minimal-release.apk
            ./app/build/outputs/version_code.txt
            ./wear/build/outputs/apk/release/wear-release.apk
            ./automotive/build/outputs/apk/full/release/automotive-full-release.apk
            ./automotive/build/outputs/apk/minimal/release/automotive-minimal-release.apk

      - name: Deploy to Firebase
        env:
          KEYSTORE_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_FILE_PASSWORD }}
          KEYSTORE_ALIAS: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS }}
          KEYSTORE_ALIAS_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS_PASSWORD }}
          VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
        run: ./gradlew appDistributionUploadFullRelease

      - name: Prepare Amazon Listing
        if: github.event.inputs.beta == 'true'
        run: bundle exec fastlane prep_amazon
        env:
          AMAZON_APPSTORE_CLIENT_ID: ${{ secrets.AMAZON_APPSTORE_CLIENT_ID }}
          AMAZON_APPSTORE_CLIENT_SECRET: ${{ secrets.AMAZON_APPSTORE_CLIENT_SECRET }}
          AMAZON_APPSTORE_APP_ID: ${{ secrets.AMAZON_APPSTORE_APP_ID }}

      - name: Print `git status`
        run: git status

  play_publish:
    name: Play Publish
    runs-on: ubuntu-latest
    concurrency:
      group: playstore_deploy
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up JDK 17
        uses: actions/setup-java@v4.2.1
        with:
          distribution: 'temurin'
          java-version: '17'

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true

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

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - uses: ./.github/actions/create-release-number
        name: Create Release Number
        id: rel_number

      - uses: ./.github/actions/inflate-secrets
        name: Inflate Secrets
        with:
          keystore: ${{ secrets.UPLOAD_KEYSTORE_FILE }}
          google-services: ${{ secrets.GOOGLESERVICES }}
          firebase-creds: ${{ secrets.FIREBASECREDS }}
          playstore-creds: ${{ secrets.PLAYSTORECREDS }}

      - uses: ./.github/actions/create-release-notes
        name: Create Release Notes
        with:
          tag-name: ${{ steps.rel_number.outputs.version }}
          gh-token: ${{ secrets.GITHUB_TOKEN }}

      - uses: ./.github/actions/download-translations
        name: Download Translations
        with:
          lokalise-project: ${{ secrets.LOKALISE_PROJECT }}
          lokalise-token: ${{ secrets.LOKALISE_TOKEN }}

      - name: Build Release
        env:
          KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_FILE_PASSWORD }}
          KEYSTORE_ALIAS: ${{ secrets.UPLOAD_KEYSTORE_ALIAS }}
          KEYSTORE_ALIAS_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_ALIAS_PASSWORD }}
          VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
        run: |
          ./gradlew :common:assemble
          ./gradlew :app:bundleRelease
          ./gradlew :wear:bundleRelease
          ./gradlew :automotive:bundleRelease

      - name: Deploy to Playstore Internal
        run: bundle exec fastlane deploy_internal

      - name: Promote Internal to Beta
        if: github.event.inputs.beta == 'true'
        run: bundle exec fastlane promote_to_beta


Pull Request

name: Pull Request

on:
  pull_request:
    branches: [ master ]

jobs:
  ktlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4.2.1
        with:
          distribution: 'temurin'
          java-version: '17'

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

      - name: Mock google-services.json
        run: |
          cp .github/mock-google-services.json app/google-services.json
          cp .github/mock-google-services.json wear/google-services.json
          cp .github/mock-google-services.json automotive/google-services.json

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

      - name: Validate ktlint
        run: ./gradlew ktlintCheck

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4.2.1
        with:
          distribution: 'adopt'
          java-version: '17'

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

      - name: Mock google-services.json
        run: |
          cp .github/mock-google-services.json app/google-services.json
          cp .github/mock-google-services.json wear/google-services.json
          cp .github/mock-google-services.json automotive/google-services.json

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

      - name: Validate Lint
        run: ./gradlew lint

  pr_build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Check for modified DB schemas on branch
      run: |
        if git diff --name-only --diff-filter=DMR origin/master... | grep "^common/schemas"; then
          echo -e "\n❌ Existing database schema modified, please increase the database version instead"
          exit 1
        else
          echo -e "\n✔ No changed database schemas on branch"
        fi

    - name: Set up JDK 17
      uses: actions/setup-java@v4.2.1
      with:
        distribution: 'adopt'
        java-version: '17'

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

    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@v3

    - name: Mock google-services.json
      run: |
        cp .github/mock-google-services.json app/google-services.json
        cp .github/mock-google-services.json wear/google-services.json
        cp .github/mock-google-services.json automotive/google-services.json

    - name: Build Debug APK
      run: |
        ./gradlew :common:assemble
        ./gradlew :app:assembleDebug
        ./gradlew :wear:assembleDebug
        ./gradlew :automotive:assembleDebug

    - name: Check for missing/modified DB schemas after build
      run: |
        if [[ $(git status common/schemas --porcelain) ]]; then
          echo $(git status common/schemas --porcelain)
          echo -e "\n❌ Found uncommitted changes in database schema directory, please make sure to include all changes in your commit(s)"
          exit 1;
        else
          echo -e "\n✔ No changes in database schema directory after build"
        fi

    - name: Archive Debug Build
      uses: actions/upload-artifact@v4
      with:
        path: ./**/*.apk


Production Deploy

name: Production Deploy

on:
  workflow_dispatch:
  release:
    types: [ released ]

env:
  SUPPLY_UPLOAD_MAX_RETRIES: 5

jobs:
  play_promote_production:
    name: Play Publish Production
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true

      - uses: ./.github/actions/inflate-secrets
        name: Inflate Secrets
        with:
          keystore: ${{ secrets.ORIGINAL_KEYSTORE_FILE }}
          google-services: ${{ secrets.GOOGLESERVICES }}
          firebase-creds: ${{ secrets.FIREBASECREDS }}
          playstore-creds: ${{ secrets.PLAYSTORECREDS }}

      - name: Promote Beta to Production Play Store
        run: bundle exec fastlane promote_to_production


Tag Weekly Release

name: Tag Weekly Release

on:
  workflow_dispatch:
  schedule:
    - cron: '0 4 * * 0'
jobs:
  tag:
    name: Tag Weekly Release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up JDK 17
        uses: actions/setup-java@v4.2.1
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Tag Weekly Release
        env:
          GITHUB_TOKEN: ${{ secrets.TAG_PUSH_TOKEN }}
        run: ./gradlew :reckonTagPush -Preckon.stage=final

      - name: Trigger Workflow
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.actions.createWorkflowDispatch({
              owner: context.repo.owner,
              repo: context.repo.repo,
              workflow_id: 'onPush.yml',
              ref: 'master',
              inputs: {
                "beta": "true",
              },
            })


Build

name: Build

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  build:
    strategy:
      matrix:
        os: [ macos-14, ubuntu-latest ]
    runs-on: ${{matrix.os}}
    name: Build on ${{matrix.os}}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Install Java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17'
      - name: Install dependencies
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get update && sudo apt-get install libcurl4-openssl-dev libgtk-3-dev nodejs chromium-browser
      - name: Select Xcode version
        if: matrix.os == 'macos-14'
        uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
        with:
          xcode-version: '15.2.0'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3
        with:
          gradle-home-cache-cleanup: true
          cache-read-only: ${{ github.ref != 'refs/heads/master' }}
          cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
      - name: Validate Gradle Wrapper
        uses: gradle/wrapper-validation-action@v2
      - name: Build Linux
        if: matrix.os == 'ubuntu-latest'
        run: >
          ./gradlew
          build
          publishAllFilteredToMavenLocal
          -Ptarget=all_linux_hosted
      - name: Build macOS
        if: matrix.os == 'macos-14'
        run:
          ./gradlew
          :reaktive-annotations:build
          :utils:build
          :reaktive-testing:build
          :reaktive:build
          :coroutines-interop:build
          :sample-mpp-module:build
          publishAllFilteredToMavenLocal
          -Ptarget=all_macos_hosted
      # Do not invoke from Gradle, it creates circular dependency (Gradle invokes XCode invokes Gradle).
      - name: Build iOS app
        if: matrix.os == 'macos-14'
        working-directory: sample-ios-app
        run: >
          xcodebuild
          -project sample-ios-app.xcodeproj
          -scheme "sample-ios-app"
          -sdk "iphonesimulator"
          -arch "arm64"
      - name: Bundle the build report
        if: failure()
        run: find . -type d -name 'reports' | zip -@ -r build-reports.zip
      - name: Upload the build report
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: error-report
          path: build-reports.zip


Release

name: Release

on:
  workflow_dispatch:
  release:
    types: [ created ]

jobs:
  create-staging-repository:
    runs-on: ubuntu-latest
    name: Create staging repository
    outputs:
      repository-id: ${{ steps.create.outputs.repository_id }}
    steps:
      - id: create
        name: Create staging repository
        uses: nexus-actions/create-nexus-staging-repo@3e5e7209801629febdcf75541a4898710d28df9a
        with:
          username: ${{ secrets.SONATYPE_USERNAME }}
          password: ${{ secrets.SONATYPE_PASSWORD }}
          staging_profile_id: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }}
          description: ${{ github.repository }}/${{ github.workflow }}#${{ github.run_number }}

  publish:
    name: Publish
    runs-on: macos-14
    needs: create-staging-repository
    env:
      SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Install Java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17'
      - name: Select Xcode version
        uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
        with:
          xcode-version: '15.2.0'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3
        with:
          cache-read-only: true
          cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
      - name: Publish
        run: >
          ./gradlew
          publishAllFilteredToSonatype
          -Psigning.password=${{ secrets.SIGNING_PASSWORD }}
          -Psonatype.username=${{ secrets.SONATYPE_USERNAME }}
          -Psonatype.password=${{ secrets.SONATYPE_PASSWORD }}
          -Psonatype.repository=${{ needs.create-staging-repository.outputs.repository-id }}

  check:
    name: Check publication
    runs-on: macos-14
    needs: [ create-staging-repository, publish ]
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Install Java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17'
      - name: Select Xcode version
        uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
        with:
          xcode-version: '15.2.0'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3
        with:
          cache-read-only: true
          cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
      - name: Check publication
        run: >
          ./gradlew
          :tools:check-publication:build
          --exclude-task kotlinStoreYarnLock
          -Pcheck_publication
          -Psonatype.username=${{ secrets.SONATYPE_USERNAME }}
          -Psonatype.password=${{ secrets.SONATYPE_PASSWORD }}
          -Psonatype.repository=${{ needs.create-staging-repository.outputs.repository-id }}

  close-staging-repository:
    runs-on: ubuntu-latest
    needs: [ create-staging-repository, check ]
    if: ${{ always() && needs.create-staging-repository.result == 'success' }}
    steps:
      - name: Discard
        if: ${{ needs.check.result != 'success' }}
        uses: nexus-actions/drop-nexus-staging-repo@59443053a1b36f5f71ede68776d73294bf4bfb5e
        with:
          username: ${{ secrets.SONATYPE_USERNAME }}
          password: ${{ secrets.SONATYPE_PASSWORD }}
          staging_repository_id: ${{ needs.create-staging-repository.outputs.repository-id }}
      - name: Release
        if: ${{ needs.check.result == 'success' }}
        uses: nexus-actions/release-nexus-staging-repo@f2b4c7f64ecec2cb0d24349182c1bbeda5c4c056
        with:
          username: ${{ secrets.SONATYPE_USERNAME }}
          password: ${{ secrets.SONATYPE_PASSWORD }}
          staging_repository_id: ${{ needs.create-staging-repository.outputs.repository-id }}


Build and check

name: Build and check

on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:
  build-jvm-matrix:
    runs-on: ubuntu-latest
    steps: # https://michaelheap.com/dynamic-matrix-generation-github-actions/
      - id: set-matrix
        run: echo "::set-output name=version_matrix::$(curl https://endoflife.date/api/oracle-jdk.json | jq -c '[.[] | select(.extendedSupport > (now | strftime("%Y-%m-%d"))) | .cycle]' | sed 's/ //g')"
      - name: verify-matrix
        run: echo "The selected java versions are ${{ steps.set-matrix.outputs.version_matrix }}"
    outputs:
      version_matrix: ${{ steps.set-matrix.outputs.version_matrix }}
  build:
    needs: build-jvm-matrix
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        java_version: ${{ fromJson(needs.build-jvm-matrix.outputs.version_matrix) }}
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2
      - name: configure windows pagefile
        if: ${{ matrix.os  == 'windows-latest' }}
        uses: al-cheb/configure-pagefile-action@v1.3
        with:
          minimum-size: 8GB
          maximum-size: 8GB
          disk-root: "D:"
      - name: set up JDK
        uses: actions/setup-java@v2
        with:
          java-version: ${{ matrix.java_version }}
          distribution: 'zulu'
      - name: Restore Gradle caches
        uses: actions/cache@v2
        with:
          path: |
            ~/.gradle/caches/modules-2
            ~/.gradle/caches/files-2.1
            ~/.gradle/caches/metadata-2.96
          key: ${{ runner.os }}-gradle-cache-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('**/gradle.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-cache-
      # Inspired by https://github.com/actions/cache/issues/432#issuecomment-740376179
      - name: Restore TestKit cache
        uses: actions/cache@v2
        with:
          path: |
            plugin/.gradle-test-kit/caches/modules-2
            plugin/.gradle-test-kit/caches/files-2.1
            plugin/.gradle-test-kit/caches/metadata-2.96
          key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }}-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }}-
            ${{ runner.os }}-gradle-wrapper-
      - name: Restore Gradle wrapper
        uses: actions/cache@v2
        with:
          path: |
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }}
          restore-keys: |
            ${{ runner.os }}-gradle-wrapper-
      - name: Build plugin
        run: ./plugin/gradlew -p ./plugin assemble ensureDependenciesAreInlined test --no-daemon
      - name: Upload test results
        uses: actions/upload-artifact@v2
        if: failure()
        with:
          name: test-results-${{ runner.os }}
          path: plugin/build/reports/tests/test/
      - name: Upload Memory Dump
        uses: actions/upload-artifact@v2
        if: failure()
        with:
          name: memory-dump-${{ runner.os }}
          path: |
            hs_err_pid*
            replay_pid*
            plugin/hs_err_pid*
            plugin/replay_pid*
      - name: Check plugin codestyle
        run: ./plugin/gradlew -p ./plugin ktlintCheck --no-daemon

  check_bashisms:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v2
      - name: set up JDK 11
        uses: actions/setup-java@v2
        with:
          java-version: 11
          distribution: 'zulu'
      - name: update apt
        run: sudo apt update
      - name: Install lintian
        run: sudo apt install -qq lintian=2.114.0ubuntu1.3
      - name: Install libdistro
        run: sudo apt install -qq libdistro-info-perl
      - name: Install checkbashisms
        run: sudo apt-get install -qq devscripts
      - name: Restore Gradle caches
        uses: actions/cache@v2
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-cache-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('**/gradle.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-cache-
      - name: Restore Gradle wrapper
        uses: actions/cache@v2
        with:
          path: ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }}
          restore-keys: |
            ${{ runner.os }}-gradle-wrapper-
      - name: Check git bashisms
        run: ./gradlew addKtlintCheckGitPreCommitHook --no-daemon && checkbashisms .git/hooks/pre-commit

  check_samples:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    needs: build
    steps:
      - uses: actions/checkout@v2
      - name: set up JDK 1.8
        uses: actions/setup-java@v2
        with:
          java-version: 8
          distribution: 'zulu'
      - name: Restore Gradle caches
        uses: actions/cache@v2
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-cache-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('**/gradle.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-cache-
      - name: Restore Gradle wrapper
        uses: actions/cache@v2
        with:
          path: ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }}
          restore-keys: |
            ${{ runner.os }}-gradle-wrapper-
      - name: Check ktlint-plugin on samples
        run: ./gradlew ktlintCheck --no-daemon


changelog

name: changelog

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

jobs:
  build:
    name: Changelog Entry Check

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Grep CHANGES.md for PR number
        if: contains(github.event.pull_request.labels.*.name, 'skip news') != true
        run: |
          grep -Pz "\[(\n\s*)?#${{ github.event.pull_request.number }}(\n\s*)?\]\((\n\s*)?https://github\.com/JLLeitschuh/ktlint-gradle/pull/${{ github.event.pull_request.number }}(\n\s*)?\)" CHANGELOG.md || \
          (echo "Please add '[#${{ github.event.pull_request.number }}](https://github.com/JLLeitschuh/ktlint-gradle/pull/${{ github.event.pull_request.number }})' change line to CHANGELOG.md" && \
          exit 1)


Validate Gradle Wrapper

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

jobs:
  validation:
    name: "Validation"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: gradle/wrapper-validation-action@v1
        with:
          min-wrapper-count: 2


New plugin release

name: "New plugin release"
on:
  push:
    tags:
      - v[0-9]+.[0-9]+.[0-9]+

jobs:
  make-new-release:
    name: "Releasing plugin"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: set up JDK 1.8
        uses: actions/setup-java@v2
        with:
          java-version: 8
          distribution: 'zulu'
      - name: Restore Gradle caches
        uses: actions/cache@v2
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-cache-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('**/gradle.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-cache-
      - name: Restore Gradle wrapper
        uses: actions/cache@v2
        with:
          path: ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }}
          restore-keys: |
            ${{ runner.os }}-gradle-wrapper-
      - name: Publish plugin
        env:
          GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
          GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
          GITHUB_KEY: ${{ secrets.GithubKey }}
        run: ./plugin/gradlew -p ./plugin publishPlugins --no-daemon
      - name: Create new Github release
        env:
          GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
          GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
          GITHUB_KEY: ${{ secrets.GITHUB_TOKEN }}
        run: ./plugin/gradlew -p ./plugin githubRelease --no-daemon
      - name: Update VERSION_LATEST_RELEASE to new published version
        run: cp plugin/VERSION_CURRENT.txt plugin/VERSION_LATEST_RELEASE.txt
      - name: Update VERSION_LATEST_RELEASE
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: Update VERSION_LATEST_RELEASE to ${{ github.event.inputs.new_version }}


Perform Release

name: "Perform Release"
on:
  workflow_dispatch:
    inputs:
       new_version:

         description: "Release Version (no 'v')"
         required: true
         type: string

jobs:
  perform-release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          token: ${{ secrets.PAT }}
      - name: Update Changelog
        uses: thomaseizinger/keep-a-changelog-new-release@1.3.0
        with:
          tag: v${{ github.event.inputs.new_version }}
          version: ${{ github.event.inputs.new_version }}
      - name: Update README
        run: |
          new_version=$(echo "${{ github.event.inputs.new_version }}")
          stripped_version=$($new_version | sed -e 's/\.//g')
          formatted_date=$(date "+%Y%m%d")
          sed -i 's|\(Latest plugin version: \[\).*\(\](/CHANGELOG.md#\).*---.*)|\1'"$new_version"'\2'"$stripped_version"'---'"$formatted_date"')|' README.md
      - name: Update VERSION_CURRENT
        run: printf "${{ github.event.inputs.new_version }}\n" > plugin/VERSION_CURRENT.txt
      - name: Perform Release Tagging and Push
        # This will trigger the new release job that will take the tag and push the release to the plugin portal
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: Release version ${{ github.event.inputs.new_version }}
          tagging_message: 'v${{ github.event.inputs.new_version }}'


Scorecard supply-chain security

# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.

name: Scorecard supply-chain security
on:
  # For Branch-Protection check. Only the default branch is supported. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
  branch_protection_rule:
  # To guarantee Maintained check is occasionally updated. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
  schedule:
    - cron: '40 1 * * 0'
  push:
    branches: [ "main" ]

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

jobs:
  analysis:
    name: Scorecard analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Needed to publish results and get a badge (see publish_results below).
      id-token: write
      # Uncomment the permissions below if installing in a private repository.
      # contents: read
      # actions: read

    steps:
      - name: "Checkout code"
        uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
        with:
          persist-credentials: false

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

          # Public repositories:
          #   - Publish results to OpenSSF REST API for easy access by consumers
          #   - Allows the repository to include the Scorecard badge.
          #   - See https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories:
          #   - `publish_results` will always be set to `false`, regardless
          #     of the value entered here.
          publish_results: true

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

      # Upload the results to GitHub's code scanning dashboard.
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4
        with:
          sarif_file: results.sarif


CI

name: CI
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

  workflow_dispatch:

# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
  group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 60

    steps:
      - uses: actions/checkout@v3

      - name: set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: temurin

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2

      - name: Run all tests
        run: ./gradlew check -x :kvision-tools:kvision-gradle-plugin:check

      - name: Test Report
        uses: dorny/test-reporter@v1
        if: success() || failure()
        with:
          name: Karma JUnit Tests
          path: build/reports/junit/*.xml
          reporter: java-junit


TEST

name: TEST

on:
  push:
    branches: [ "master", "main" ]
  pull_request:

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

env:
  CI: true
  DISPLAY: ":99"
  JAVA_VERSION: 11
  JAVA_DISTRIBUTION: zulu

jobs:
  test:
    timeout-minutes: 25
    runs-on: ubuntu-latest
    steps:
      - { uses: actions/checkout@v3 }
      - { name: Set up JDK, uses: actions/setup-java@v3, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } }
      - { name: Prepare Gradle, uses: gradle/gradle-build-action@ef76a971e2fa3f867b617efd72f2fbd72cf6f8bc } # v2.8.0
      - { name: Initialize Gradle, run: ./gradlew }
      - { name: Gradle Test JVM, run: ./gradlew jvmTest }
      - { name: Gradle Test JS, run: ./gradlew jsTest }
      #- { name: Gradle Sonarqube, run: ./gradlew sonarqube, if: false }


Update DockerHub description

name: Update DockerHub description

on:
  push:
    branches:
    - master
    paths:
    - 'DOCKERHUB.md'

jobs:
  update_docker_description:
    name: Update DockerHub description
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@master
    - name: DockerHub Description
      uses: peter-evans/dockerhub-description@v4.0.0
      env:
        DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
        DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
        DOCKERHUB_REPOSITORY: gotson/komga
        README_FILEPATH: ./DOCKERHUB.md


Validate Gradle Wrapper

name: "Validate Gradle Wrapper"
on:
  pull_request:
  push:
    branches-ignore:
      - 'dependabot/**'

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


Lock threads

name: Lock threads

on:
  # Daily
  schedule:
    - cron: '0 0 * * *'
  # Manual trigger
  workflow_dispatch:
    inputs:

jobs:
  lock:
    runs-on: ubuntu-latest
    steps:
      - uses: dessant/lock-threads@v5
        with:
          github-token: ${{ github.token }}
          issue-inactive-days: '30'
          pr-inactive-days: '30'