From fd2c6ab2d7acd036344e092d5f30b029deee1e6e Mon Sep 17 00:00:00 2001 From: I-Al-Istannen Date: Tue, 29 Aug 2023 17:51:47 +0200 Subject: [PATCH] chore: Use Nix in CI where possible (#5394) --- .github/actions/setup-tests/action.yml | 29 +++ .github/workflows/jreleaser.yml | 110 +---------- .github/workflows/release-beta.yml | 12 ++ .github/workflows/release-manual.yml | 21 +++ .github/workflows/release-nightly.yml | 12 ++ .github/workflows/tests.yml | 249 +++++++------------------ .github/workflows/update-flake.yml | 30 +++ chore/release-beta.sh | 31 +++ chore/release-nightly.sh | 15 ++ chore/release.sh | 82 ++++++++ flake.lock | 27 +++ flake.nix | 205 ++++++++++++++++++++ jreleaser.yml | 1 + 13 files changed, 544 insertions(+), 280 deletions(-) create mode 100644 .github/actions/setup-tests/action.yml create mode 100644 .github/workflows/release-beta.yml create mode 100644 .github/workflows/release-manual.yml create mode 100644 .github/workflows/release-nightly.yml create mode 100644 .github/workflows/update-flake.yml create mode 100644 chore/release-beta.sh create mode 100644 chore/release-nightly.sh create mode 100644 chore/release.sh create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.github/actions/setup-tests/action.yml b/.github/actions/setup-tests/action.yml new file mode 100644 index 00000000000..eb70045ae0b --- /dev/null +++ b/.github/actions/setup-tests/action.yml @@ -0,0 +1,29 @@ +name: Setup test environment + +runs: + using: "composite" + steps: + - name: Set git user + shell: bash + run: | + git config --global user.name "GitHub Actions Bot" + git config --global user.email "<>" + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@65d7c888b2778e8cf30a07a88422ccb23499bfb8 # v4 + - uses: DeterminateSystems/magic-nix-cache-action@8a218f9e264e9c3803c9a1ee1c30d8e4ab55be63 # v2 + - name: Check Nixpkgs inputs + uses: DeterminateSystems/flake-checker-action@4b90f9fc724969ff153fe1803460917c84fe00a3 # v5 + with: + fail-mode: true + - name: Use Maven dependency cache + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + with: + path: ~/.m2/repository + # We use a unique key and restore from the base one, to ensure that + # the cache is updated every time, even if a cache hit was observed. + # See + # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache + # for more information. + key: ${{ runner.os }}-maven-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-maven diff --git a/.github/workflows/jreleaser.yml b/.github/workflows/jreleaser.yml index e1193f4d390..66d59fc43ce 100644 --- a/.github/workflows/jreleaser.yml +++ b/.github/workflows/jreleaser.yml @@ -1,127 +1,35 @@ name: Release on: - workflow_dispatch: + workflow_call: inputs: - version: - description: 'Next release version' + release-script-to-run: required: true - default: 'patch' - type: choice - options: - - major - - minor - - patch + type: string jobs: - - build: + jreleaser: runs-on: ubuntu-latest steps: -# Setups the environment - name: Checkout uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 with: fetch-depth: 0 token: ${{ secrets.JRELEASER_GITHUB_TOKEN }} - - name: Set git user - run: | - git config --global user.name "GitHub Actions Bot" - git config --global user.email "<>" - - name: Set up JDK 11 - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 - with: - java-version: '11' - distribution: 'temurin' - cache: maven - - - name: install go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 - - name: install semversion - run: go install github.com/ffurrer2/semver/cmd/semver@latest -# Get current version from pom and remove snapshot if present. - - name: Get current version from pom and remove snapshot if present. - run: echo "CURRENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout | sed 's/-SNAPSHOT//')" >> $GITHUB_ENV - - name: Get version with snapshot - run: echo "CURRENT_VERSION_WITH_SNAPSHOT=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV -# Calculate release version: -# - if `version` is patch, we just increment drop the `-SNAPSHOT` suffix -# (e.g. 10.0.1-SNAPSHOT -> 10.0.1) -# - if `version` is minor or major, we increment the minor or major version and -# set the patch version to `0` (e.g. 10.0.1-SNAPSHOT -> 11.0.0 or 10.1.0) -# -# As we are using a snapshot version, the first call to `semver next` slices -# off only the `-SNAPSHOT` suffix. We therefore run `semver next` on the -# version *without* the `-SNAPSHOT` prefix for major and minor bumps. -# -# After release, we run `semver next` once again and append the `-SNAPSHOT` -# suffix. This results in our patch version from above becoming -# `10.0.2-SNAPSHOT`. The major/minor just get the patch set to `1` and -# `-SNAPSHOT` appended. - - name: Set next version for patch - if: ${{ github.event.inputs.version == 'patch' }} - run: echo "NEXT_VERSION=$(semver next ${{ github.event.inputs.version }} $CURRENT_VERSION_WITH_SNAPSHOT)" >> $GITHUB_ENV - - name: Set next version for major/minor - if: ${{ github.event.inputs.version == 'major' || github.event.inputs.version == 'minor' }} - run: echo "NEXT_VERSION=$(semver next ${{ github.event.inputs.version }} $CURRENT_VERSION)" >> $GITHUB_ENV - - name: set branchname to next version - run: echo "BRANCH_NAME=release/$NEXT_VERSION" >> $GITHUB_ENV - - name: Set release version - run: | - mvn -f spoon-pom --no-transfer-progress --batch-mode versions:set -DnewVersion=$NEXT_VERSION -DprocessAllModules - mvn --no-transfer-progress --batch-mode versions:set -DnewVersion=$NEXT_VERSION -DprocessAllModules - mvn -f spoon-javadoc --no-transfer-progress --batch-mode versions:set -DnewVersion=$NEXT_VERSION -DprocessAllModules - - name: Commit & Push changes - run: | - git checkout -b ${{env.BRANCH_NAME}} - git commit -am "release: Releasing version ${{ env.NEXT_VERSION }}" - git push --set-upstream origin ${{ env.BRANCH_NAME }} - + - name: Setup env + uses: ./.github/actions/setup-tests - -# Now we can run the release - - name: Stage release - run: | - mvn -f spoon-pom --no-transfer-progress --batch-mode -Pjreleaser clean deploy -DaltDeploymentRepository=local::default::file:./target/staging-deploy - mvn --no-transfer-progress --batch-mode -Pjreleaser deploy:deploy-file -Dfile="./spoon-pom/pom.xml" -DpomFile="./spoon-pom/pom.xml" -Durl=file://$(mvn help:evaluate -D"expression=project.basedir" -q -DforceStdout)/target/staging-deploy - - name: Print next version - run: mvn help:evaluate -Dexpression=project.version -q -DforceStdout | sed 's/-SNAPSHOT//' - - name: Run JReleaser - uses: jreleaser/release-action@0b198089c53ad2aef0d2bff6b5e6061ead2bbb90 # v2 - with: - setup-java: false - version: 1.4.0 - arguments: full-release + - name: Do release + run: nix develop .#jReleaser --command ${{ inputs.release-script-to-run }} env: - JRELEASER_PROJECT_VERSION: ${{ env.NEXT_VERSION }} JRELEASER_GITHUB_TOKEN: ${{ secrets.JRELEASER_GITHUB_TOKEN }} JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }} JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.JRELEASER_GPG_PUBLIC_KEY }} JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }} JRELEASER_NEXUS2_MAVEN_CENTRAL_USERNAME: ${{ secrets.JRELEASER_NEXUS2_MAVEN_CENTRAL_USERNAME }} JRELEASER_NEXUS2_MAVEN_CENTRAL_PASSWORD: ${{ secrets.JRELEASER_NEXUS2_MAVEN_CENTRAL_PASSWORD }} -# Time to set the next version: The next version of any Release is a snapshot version of the next patch version - - name : Set next version (patch of release version) with -SNAPSHOT suffix - run: | - echo "NEXT_RELEASE_VERSION=$(semver next patch $NEXT_VERSION)-SNAPSHOT" >> $GITHUB_ENV - echo "NEXT_RELEASE_VERSION_WITHOUT_SNAPSHOT=$(semver next patch $NEXT_VERSION)" >> $GITHUB_ENV - - name: Set release version - run: | - mvn -f spoon-pom --no-transfer-progress --batch-mode versions:set -DnewVersion=$NEXT_RELEASE_VERSION -DprocessAllModules - mvn --no-transfer-progress --batch-mode versions:set -DnewVersion=$NEXT_RELEASE_VERSION -DprocessAllModules - mvn -f spoon-javadoc --no-transfer-progress --batch-mode versions:set -DnewVersion=$NEXT_RELEASE_VERSION -DprocessAllModules -# Commit and push changes - - name: Commit & Push changes - run: | - git commit -am "release: Setting SNAPSHOT version $NEXT_RELEASE_VERSION" - git push --set-upstream origin ${{ env.BRANCH_NAME }} - - name: Merge Fast Forward - run: | - git checkout master - git merge --ff-only ${{ env.BRANCH_NAME }} - git push origin master -# Log failure: + # Log failures - name: JReleaser release output if: always() uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3 diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml new file mode 100644 index 00000000000..8da3bbfedff --- /dev/null +++ b/.github/workflows/release-beta.yml @@ -0,0 +1,12 @@ +name: Release beta version + +on: + schedule: + - cron: '0 0 * * 0' # Sundays at 00:00 (https://crontab.guru/#0_0_*_*_0) + +jobs: + snapshot: + uses: ./.github/workflows/jreleaser.yml + with: + release-script-to-run: chore/release-beta.sh + secrets: inherit diff --git a/.github/workflows/release-manual.yml b/.github/workflows/release-manual.yml new file mode 100644 index 00000000000..f81fddd119a --- /dev/null +++ b/.github/workflows/release-manual.yml @@ -0,0 +1,21 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Next release version' + required: true + default: 'patch' + type: choice + options: + - major + - minor + - patch + +jobs: + release: + uses: ./.github/workflows/jreleaser.yml + with: + release-script-to-run: chore/release.sh ${{ github.event.inputs.version }} + secrets: inherit diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml new file mode 100644 index 00000000000..9b1f5e07b6c --- /dev/null +++ b/.github/workflows/release-nightly.yml @@ -0,0 +1,12 @@ +name: Release nightly version + +on: + schedule: + - cron: '0 0 * * *' # Every day at 00:00 UTC (https://crontab.guru/#0_0_*_*_*) + +jobs: + nightly: + uses: ./.github/workflows/jreleaser.yml + with: + release-script-to-run: chore/release-nightly.sh + secrets: inherit diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 77f7d53c59b..17e576524af 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,97 +12,74 @@ on: push: branches: - master + - chore/flakey-flakey-rise-and-shine schedule: - - cron: "0 0 * * *" + - cron: "0 0 * * *" env: - JAVA_DISTRIBUTION: temurin MAVEN_OPTS: >- -Dmaven.resolver.transport=native -Daether.connector.connectTimeout=300000 -Daether.connector.requestTimeout=300000 jobs: - build: + test-linux: runs-on: ${{ matrix.os }} + name: Tests with Java ${{ matrix.java }} on ${{ matrix.os }} strategy: matrix: java: [11, 17, 20, 21-ea] - os: [ubuntu-latest, windows-latest] - exclude: - - os: windows-latest - java: 17 - - os: windows-latest - java: 20 - - os: windows-latest - java: 21-ea - - + os: [ubuntu-latest] + steps: + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + with: + fetch-depth: 0 + - name: Setup env + uses: ./.github/actions/setup-tests + - name: Time nix setup + run: nix develop .#jdk${{ matrix.java }} --command true + - name: Test + run: nix develop .#jdk${{ matrix.java }} --command test - name: Tests with Java ${{ matrix.java }} on ${{ matrix.os }} + test-windows: + runs-on: windows-latest + name: Tests with Java 17 on windows-latest steps: - name: Disable Git's autocrlf run: git config --global core.autocrlf false - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - - uses: oracle-actions/setup-java@2c4df2930e35870536667f383d87f1246fbe613f # v1 + - name: git checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: - website: jdk.java.net - java-version: ${{ matrix.java }} - - - name: Get date for cache # see https://github.com/actions/cache README - id: get-date - run: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT - shell: bash - - name: Use Maven dependency cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + fetch-depth: 0 + - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 with: - path: ~/.m2/repository - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-maven- + distribution: 'temurin' + java-version: '17' + cache: 'maven' - - name: Use silent log config - run: mv chore/logback.xml src/test/resources/ - - name: Build - run: | - mvn -f spoon-pom -B test-compile - - name: Fetch final dependencies - # this is a hack to download the final test dependencies required to actually run the tests - run: timeout 20 mvn -f spoon-pom -B test || echo "Done fetching dependencies" - shell: bash - name: Test - run: + run: | + cp chore/logback.xml src/test/resources/ mvn -f spoon-pom test - - name: print run tests - run: cat testResults.spoon + cat testResults.spoon + coverage: runs-on: ubuntu-latest name: Test with coverage steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 - with: - java-version: 17 - distribution: ${{ env.JAVA_DISTRIBUTION }} - - - name: Get date for cache # see https://github.com/actions/cache README - id: get-date - run: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT - shell: bash - - name: Use Maven dependency cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 with: - path: ~/.m2/repository - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-maven- + fetch-depth: 0 + - name: Setup env + uses: ./.github/actions/setup-tests - - name: Use silent log config - run: mv chore/logback.xml src/test/resources/ - - name: Build - run: | - mvn -f spoon-pom -B test-compile - - name: Test with coverage - run: mvn -f spoon-pom -Pcoveralls test jacoco:report coveralls:report -DrepoToken=$GITHUB_TOKEN -DserviceName=github -DpullRequest=$PR_NUMBER --fail-never + - name: Time nix setup + run: nix develop --command true + - name: Run tests with coverage + run: nix develop --command coverage env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ github.event.number }} @@ -111,136 +88,50 @@ jobs: runs-on: ubuntu-latest name: Extra checks steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - with: - fetch-depth: 0 - - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 - with: - java-version: 11 - distribution: ${{ env.JAVA_DISTRIBUTION }} - - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 - with: - python-version: 3.11 - - name: Get date for cache # see https://github.com/actions/cache README - id: get-date - run: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT - shell: bash - - name: Use Maven dependency cache - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-maven- - - name: Use silent log config - run: mv chore/logback.xml src/test/resources/ - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 with: fetch-depth: 0 - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y python3-pip - pip3 install --user CommonMark==0.9.1 requests pygithub - - - name: Verify and Site Maven goals - run: mvn verify license:check site -DskipTests -DadditionalJOption=-Xdoclint:syntax,-missing -Dscan - - name: Install spoon-pom - working-directory: spoon-pom - run: mvn install -DskipTests - - - name: Checkstyle in src/tests - run: mvn -q checkstyle:checkstyle -Pcheckstyle-test - - - name: Check documentation links - run: python3 ./chore/check-links-in-doc.py - - - name: Analyze dependencies through DepClean in spoon-core - run: mvn -q depclean:depclean - - - name: Spoon-decompiler - working-directory: spoon-decompiler - run: | - mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon - mvn -q versions:update-parent -DallowSnapshots=true - git diff - mvn -q test - mvn -q checkstyle:checkstyle license:check - mvn -q depclean:depclean - - - name: Spoon-control-flow - working-directory: spoon-control-flow - run: | - mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon - mvn -q versions:update-parent -DallowSnapshots=true - git diff - mvn -q test - mvn -q checkstyle:checkstyle license:check - # spoon dataflow - - name: Cache downloaded file - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 - with: - path: spoon-dataflow/z3-4.8.4.d6df51951f4c-x64-ubuntu-14.04.zip - key: ${{ runner.os }}-z3-4.8.4.d6df51951f4c-x64-ubuntu-14.04.zip - restore-keys: | - ${{ runner.os }}-z3-4.8.4.d6df51951f4c-x64-ubuntu-14.04.zip - - name: Spoon-dataflow - working-directory: spoon-dataflow - run: | - wget https://projects.ow2.org/download/spoon/WebHome/z3-4.8.4.d6df51951f4c-x64-ubuntu-14.04.zip - unzip z3-4.8.4.d6df51951f4c-x64-ubuntu-14.04.zip - export LD_LIBRARY_PATH=./z3-4.8.4.d6df51951f4c-x64-ubuntu-14.04/bin - ./gradlew build - - name: Spoon-visualisation - working-directory: spoon-visualisation - run: | - mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon - mvn -q versions:update-parent -DallowSnapshots=true - git diff - mvn -q test - mvn -q depclean:depclean - - - name: Spoon-smpl - working-directory: spoon-smpl - run: | - mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon - mvn -q versions:update-parent -DallowSnapshots=true - git diff - mvn -q -Djava.src.version=11 test - mvn -q checkstyle:checkstyle license:check - mvn -q depclean:depclean - - name: Trigger extra tasks + - name: Setup env + uses: ./.github/actions/setup-tests + + - name: Time nix setup + run: nix develop .#extraChecks --command true + - name: Run extra checks + run: nix develop .#extraChecks --command extra + - name: Trigger extra remote tasks if: github.repository == 'INRIA/spoon' && github.event_name == 'pull_request' - run: | - curl https://raw.githubusercontent.com/SpoonLabs/spoon-ci-external/master/spoon-pull-request.sh | bash + run: nix develop .#extraChecks --command extra-remote - name: Run Javadoc quality check - run: ./chore/check-javadoc-regressions.py COMPARE_WITH_MASTER + run: nix develop .#extraChecks --command javadoc-quality + reproducible-builds: runs-on: ubuntu-latest name: reproducible-builds steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 with: fetch-depth: 0 - - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 - with: - java-version: 17 - distribution: ${{ env.JAVA_DISTRIBUTION }} + - name: Setup env + uses: ./.github/actions/setup-tests + + - name: Time nix setup + run: nix develop --command true - name: Check status - run: chore/check-reproducible-builds.sh + run: nix develop --command reproducible-builds + maven-central-requirements: runs-on: ubuntu-latest steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - - name: Set up JDK 11 - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3 - with: - java-version: '11' - distribution: 'temurin' - # the pom checker needs maven 3.9.0 - - name: Set up Maven - uses: stCarolas/setup-maven@07fbbe97d97ef44336b7382563d66743297e442f # v4.5 + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 with: - maven-version: 3.9.0 - # we dont enforce that the version must be non snapshot as this is not possible for SNAPSHOT versions in our workflow. + fetch-depth: 0 + - name: Setup env + uses: ./.github/actions/setup-tests + + - name: Time nix setup + run: nix develop --command true - name: Check maven pom quality - run: mvn -f spoon-pom org.kordamp.maven:pomchecker-maven-plugin:1.9.0:check-maven-central -D"checker.release=false" + run: nix develop --command maven-pom-quality diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml new file mode 100644 index 00000000000..64c6dc7e5e5 --- /dev/null +++ b/.github/workflows/update-flake.yml @@ -0,0 +1,30 @@ +name: Update flake.lock +on: + workflow_dispatch: # allows manual triggering + schedule: + - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00 + +jobs: + lockfile: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + with: + fetch-depth: 0 + - name: Setup env + uses: ./.github/actions/setup-tests + + - name: Update flake.lock + uses: DeterminateSystems/update-flake-lock@da2fd6f2563fe3e4f2af8be73b864088564e263d # v20 + id: update-flake + with: + pr-title: "chore(deps): Update flake.lock" + pr-labels: | + chore + token: ${{ secrets.GH_PAT_NIX }} + + - name: Enable Pull Request Automerge + run: 'gh pr merge --auto --squash -t "chore(deps): Update flake.lock" ${{ steps.update-flake.outputs.pull-request-number }}' + env: + GH_TOKEN: ${{ secrets.GH_PAT_NIX }} diff --git a/chore/release-beta.sh b/chore/release-beta.sh new file mode 100644 index 00000000000..a73d13e6109 --- /dev/null +++ b/chore/release-beta.sh @@ -0,0 +1,31 @@ +CURRENT_VERSION_WITH_SNAPSHOT="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" + +if [[ ! $CURRENT_VERSION_WITH_SNAPSHOT =~ .*-SNAPSHOT ]]; then + echo "Not a snapshot version, skipping" + exit 78 +fi + +# Compute next beta number +echo "::group::Computing next beta number" +LAST_BETA_NUMBER="$(curl -L "http://search.maven.org/solrsearch/select?q=a:spoon-core+g:fr.inria.gforge.spoon&rows=40&wt=json&core=gav" | jq -r ".response.docs | map(.v) | map((match(\"$CURRENT_VERSION_NO_SNAPSHOT-beta-(.*)\") | .captures[0].string) // \"0\") | .[0]")" +echo "LAST_BETA_NUMBER $LAST_BETA_NUMBER" + +NEW_BETA_NUMBER=$((LAST_BETA_NUMBER + 1)) +echo "NEW_BETA_NUMBER $NEW_BETA_NUMBER" +NEXT_VERSION="$CURRENT_VERSION_NO_SNAPSHOT-beta-$NEW_BETA_NUMBER" +echo "::endgroup::" + +echo "::group::Setting release version" +mvn -f spoon-pom --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_VERSION" -DprocessAllModules +mvn --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_VERSION" -DprocessAllModules +mvn -f spoon-javadoc --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_VERSION" -DprocessAllModules +echo "::endgroup::" + +echo "::group::Staging release" +mvn -f spoon-pom --no-transfer-progress --batch-mode -Pjreleaser clean deploy -DaltDeploymentRepository=local::default::file:./target/staging-deploy +mvn --no-transfer-progress --batch-mode -Pjreleaser deploy:deploy-file -Dfile="./spoon-pom/pom.xml" -DpomFile="./spoon-pom/pom.xml" -Durl="file://$(mvn help:evaluate -D"expression=project.basedir" -q -DforceStdout)/target/staging-deploy" +echo "::endgroup::" + +echo "::group::Running jreleaser" +JRELEASER_PROJECT_VERSION="$NEXT_VERSION" jreleaser-cli deploy +echo "::endgroup::" diff --git a/chore/release-nightly.sh b/chore/release-nightly.sh new file mode 100644 index 00000000000..d4e5598ff93 --- /dev/null +++ b/chore/release-nightly.sh @@ -0,0 +1,15 @@ +CURRENT_VERSION_WITH_SNAPSHOT="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" + +if [[ ! $CURRENT_VERSION_WITH_SNAPSHOT =~ .*-SNAPSHOT ]]; then + echo "Not a snapshot version, skipping" + exit 78 +fi + +echo "::group::Staging release" +mvn -f spoon-pom --no-transfer-progress --batch-mode -Pjreleaser clean deploy -DaltDeploymentRepository=local::default::file:./target/staging-deploy +mvn --no-transfer-progress --batch-mode -Pjreleaser deploy:deploy-file -Dfile="./spoon-pom/pom.xml" -DpomFile="./spoon-pom/pom.xml" -Durl="file://$(mvn help:evaluate -D"expression=project.basedir" -q -DforceStdout)/target/staging-deploy" +echo "::endgroup::" + +echo "::group::Running jreleaser" +JRELEASER_PROJECT_VERSION="$NEXT_VERSION" jreleaser-cli deploy +echo "::endgroup::" diff --git a/chore/release.sh b/chore/release.sh new file mode 100644 index 00000000000..0b486061d5b --- /dev/null +++ b/chore/release.sh @@ -0,0 +1,82 @@ +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Get current version from pom and remove snapshot if present. +CURRENT_VERSION="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout | sed 's/-SNAPSHOT//')" +CURRENT_VERSION_WITH_SNAPSHOT="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" + +# Calculate release version: +# - if `version` is patch, we just increment drop the `-SNAPSHOT` suffix +# (e.g. 10.0.1-SNAPSHOT -> 10.0.1) +# - if `version` is minor or major, we increment the minor or major version and +# set the patch version to `0` (e.g. 10.0.1-SNAPSHOT -> 11.0.0 or 10.1.0) +# +# As we are using a snapshot version, the first call to `semver next` slices +# off only the `-SNAPSHOT` suffix. We therefore run `semver next` on the +# version *without* the `-SNAPSHOT` prefix for major and minor bumps. +# +# After release, we run `semver next` once again and append the `-SNAPSHOT` +# suffix. This results in our patch version from above becoming +# `10.0.2-SNAPSHOT`. The major/minor just get the patch set to `1` and +# `-SNAPSHOT` appended. + +if [[ "$1" == "patch" ]]; then + NEXT_VERSION="$(semver next "$1" "$CURRENT_VERSION_WITH_SNAPSHOT")" +elif [[ "$1" == "minor" ]] || [[ "$1" == "major" ]]; then + NEXT_VERSION="$(semver next "$1" "$CURRENT_VERSION")" +else + echo "Unknown next version '$1'" + exit 1 +fi + +BRANCH_NAME="release/$NEXT_VERSION" + +echo "::group::Setting release version" +mvn -f spoon-pom --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_VERSION" -DprocessAllModules +mvn --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_VERSION" -DprocessAllModules +mvn -f spoon-javadoc --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_VERSION" -DprocessAllModules +echo "::endgroup::" + +echo "::group::Commit & Push changes" +git checkout -b "$BRANCH_NAME" +git commit -am "release: Releasing version $NEXT_VERSION" +git push --set-upstream origin "$BRANCH_NAME" +echo "::endgroup::" + +echo "::group::Staging release" +mvn -f spoon-pom --no-transfer-progress --batch-mode -Pjreleaser clean deploy -DaltDeploymentRepository=local::default::file:./target/staging-deploy +mvn --no-transfer-progress --batch-mode -Pjreleaser deploy:deploy-file \ + -Dfile="./spoon-pom/pom.xml" \ + -DpomFile="./spoon-pom/pom.xml" \ + -Durl="file://$(mvn help:evaluate -D"expression=project.basedir" -q -DforceStdout)/target/staging-deploy" +echo "::endgroup::" + +echo "::group::Next version" +mvn help:evaluate -Dexpression=project.version -q -DforceStdout | sed 's/-SNAPSHOT//' +echo "::endgroup::" + +echo "::group::Releasing" +JRELEASER_PROJECT_VERSION="$NEXT_VERSION" jreleaser-cli full-release +echo "::endgroup::" + +# Set next version (patch of release version) with -SNAPSHOT suffix +NEXT_RELEASE_VERSION="$(semver next patch "$NEXT_VERSION")-SNAPSHOT" + +echo "::group::Updating poms to next target version" +mvn -f spoon-pom --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_RELEASE_VERSION" -DprocessAllModules +mvn --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_RELEASE_VERSION" -DprocessAllModules +mvn -f spoon-javadoc --no-transfer-progress --batch-mode versions:set -DnewVersion="$NEXT_RELEASE_VERSION" -DprocessAllModules +echo "::endgroup::" + +echo "::group::Committing changes" +git commit -am "release: Setting SNAPSHOT version $NEXT_RELEASE_VERSION" +git push --set-upstream origin "$BRANCH_NAME" +echo "::endgroup::" + +echo "::group::Merging into master (fast-forward)" +git checkout master +git merge --ff-only "$BRANCH_NAME" +git push origin master +echo "::endgroup::" diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000000..f7acd894120 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1692734709, + "narHash": "sha256-SCFnyHCyYjwEmgUsHDDuU0TsbVMKeU1vwkR+r7uS2Rg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b85ed9dcbf187b909ef7964774f8847d554fab3b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000000..85c57e42245 --- /dev/null +++ b/flake.nix @@ -0,0 +1,205 @@ +{ + description = "Spoon is a metaprogramming library to analyze and transform Java source code. 🥄 is made with ❤️, 🍻 and ✨. It parses source files to build a well-designed AST with powerful analysis and transformation API."; + + # Nixpkgs / NixOS version to use. + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = { self, nixpkgs }: + let + # Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'. + forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed; + mkShell = system: { release ? false, extraChecks ? false, javaVersion }: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ + (final: prev: + let + base = rec { + jdk = if javaVersion < 21 then prev."jdk${toString javaVersion}" else jdk21-ea; + maven = prev.maven.override { inherit jdk; }; + }; + extra = with base; { + gradle = prev.gradle.override { java = jdk; }; + z3 = prev.z3.override { inherit jdk; javaBindings = true; }; + }; + in + (if extraChecks then base // extra else base)) + ]; + }; + jdk21-ea = pkgs.stdenv.mkDerivation rec { + name = "jdk21-oracle"; + version = "21+35"; + src = builtins.fetchTarball { + url = "https://download.java.net/java/GA/jdk21/fd2272bbf8e04c3dbaee13770090416c/35/GPL/openjdk-21_linux-x64_bin.tar.gz"; + sha256 = "sha256:0g3vf0kcpciixfv1kvgbk685h6cfn1s0cx2di4rhl3r7xlal217w"; + }; + installPhase = '' + cd .. + mv $sourceRoot $out + ''; + }; + semver = pkgs.buildGoModule rec { + name = "semver"; + version = "2.1.0"; + + vendorHash = "sha256-HKqZbgP7vqDJMaHUbSqfSOnBYwzOtIr9o2v/T9S+uNg="; + subPackages = [ "cmd/semver" ]; + + src = pkgs.fetchFromGitHub { + owner = "ffurrer2"; + repo = "semver"; + rev = "v${version}"; + sha256 = "sha256-i/XPA2Hr2puJFKupIeBUE/yFPJxSeVsDWcz1OepxIcU="; + }; + }; + jreleaser = pkgs.stdenv.mkDerivation rec { + pname = "jreleaser-cli"; + version = "1.7.0"; + + src = pkgs.fetchurl { + url = "https://github.com/jreleaser/jreleaser/releases/download/v${version}/jreleaser-tool-provider-${version}.jar"; + sha256 = "sha256-gr1IWisuep00xyoZWKXtHymWkQjbDhlk6+UC16bKXu0="; + }; + + nativeBuildInputs = with pkgs; [ makeWrapper ]; + + dontUnpack = true; + + installPhase = '' + mkdir -p $out/share/java/ $out/bin/ + cp $src $out/share/java/${pname}.jar + makeWrapper ${pkgs.jdk}/bin/java $out/bin/${pname} \ + --add-flags "-jar $out/share/java/${pname}.jar" + ''; + }; + in + pkgs.mkShell rec { + test = pkgs.writeScriptBin "test" '' + set -eu + # Use silent log config + cp chore/logback.xml src/test/resources/ + mvn -f spoon-pom -B test-compile + + # this is a hack to download the final test dependencies required to actually run the tests + timeout 20 mvn -f spoon-pom -B test || echo "Done fetching dependencies" + + # Execute tests + mvn -f spoon-pom test + + # print test results in log + cat testResults.spoon + ''; + coverage = pkgs.writeScriptBin "coverage" '' + set -eu + # Use silent log config + cp chore/logback.xml src/test/resources/ + mvn -f spoon-pom -B test-compile + mvn -f spoon-pom -Pcoveralls test jacoco:report coveralls:report -DrepoToken=$GITHUB_TOKEN -DserviceName=github -DpullRequest=$PR_NUMBER --fail-never + ''; + extra = pkgs.writeScriptBin "extra" (if !extraChecks then "exit 2" else '' + set -eu + # Use silent log config + cp chore/logback.xml src/test/resources/ + # Verify and Site Maven goals + mvn verify license:check site -DskipTests -DadditionalJOption=-Xdoclint:syntax,-missing -Dscan + # Install spoon-pom + pushd spoon-pom || exit 1 + mvn install -DskipTests + popd || exit 1 + + # Checkstyle in src/tests + mvn -q checkstyle:checkstyle -Pcheckstyle-test + # Check documentation links + python3 ./chore/check-links-in-doc.py + # Analyze dependencies through DepClean in spoon-core + mvn -q depclean:depclean + + pushd spoon-decompiler || exit 1 + mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon + mvn -q versions:update-parent -DallowSnapshots=true + git diff + mvn -q test + mvn -q checkstyle:checkstyle license:check + mvn -q depclean:depclean + popd || exit 1 + + pushd spoon-control-flow || exit 1 + mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon + mvn -q versions:update-parent -DallowSnapshots=true + git diff + mvn -q test + mvn -q checkstyle:checkstyle license:check + popd || exit 1 + + # Requires z3 + pushd spoon-dataflow || exit 1 + env LD_LIBRARY_PATH="${pkgs.z3.lib}/lib:${pkgs.z3.java}/lib" ./gradlew build + popd || exit 1 + + pushd spoon-visualisation || exit 1 + mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon + mvn -q versions:update-parent -DallowSnapshots=true + git diff + mvn -q test + mvn -q depclean:depclean + popd || exit 1 + + pushd spoon-smpl || exit 1 + mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon + mvn -q versions:update-parent -DallowSnapshots=true + git diff + mvn -q -Djava.src.version=11 test + mvn -q checkstyle:checkstyle license:check + mvn -q depclean:depclean + popd || exit 1 + ''); + extraRemote = pkgs.writeScriptBin "extra-remote" '' + curl https://raw.githubusercontent.com/SpoonLabs/spoon-ci-external/master/spoon-pull-request.sh | bash + ''; + mavenPomQuality = pkgs.writeScriptBin "maven-pom-quality" '' + # we dont enforce that the version must be non snapshot as this is not possible for SNAPSHOT versions in our workflow. + mvn -f spoon-pom org.kordamp.maven:pomchecker-maven-plugin:1.9.0:check-maven-central -D"checker.release=false" + ''; + reproducibleBuilds = pkgs.writeScriptBin "reproducible-builds" '' + chore/check-reproducible-builds.sh + ''; + javadocQuality = pkgs.writeScriptBin "javadoc-quality" '' + ./chore/check-javadoc-regressions.py COMPARE_WITH_MASTER + ''; + pythonEnv = + if extraChecks then + with pkgs; python311.withPackages (ps: [ + ps.requests + ps.pygithub + ps.commonmark + ]) + else [ ]; + packages = with pkgs; + [ jdk maven test coverage mavenPomQuality javadocQuality reproducibleBuilds ] + ++ (if extraChecks then [ gradle pythonEnv z3.java z3.lib extra extraRemote ] else [ ]) + ++ (if release then [ semver jreleaser ] else [ ]); + }; + in + { + devShells = + let + # We have additional options (currently EA jdks) on 64 bit linux systems + blessedSystem = "x86_64-linux"; + blessed = { jdk21-ea = mkShell blessedSystem { javaVersion = 21; }; }; + common = forAllSystems + (system: + rec { + default = jdk20; + jdk20 = mkShell system { javaVersion = 20; }; + jdk17 = mkShell system { javaVersion = 17; }; + jdk11 = mkShell system { javaVersion = 11; }; + extraChecks = mkShell system { extraChecks = true; javaVersion = 11; }; + jReleaser = mkShell system { release = true; javaVersion = 11; }; + }); + in + common // { "${blessedSystem}" = common."${blessedSystem}" // blessed; }; + }; +} diff --git a/jreleaser.yml b/jreleaser.yml index 94f0cd823f2..d15436cdc45 100644 --- a/jreleaser.yml +++ b/jreleaser.yml @@ -43,6 +43,7 @@ deploy: # Spoon is hosted on the legacy sonatype instance, see # https://central.sonatype.org/publish/publish-guide/#releasing-to-central url: https://oss.sonatype.org/service/local + snapshotUrl: https://oss.sonatype.org/content/repositories/snapshots closeRepository: true releaseRepository: true stagingRepositories: