From 784422ca7c1d187869ec5ab662a1df1af8083307 Mon Sep 17 00:00:00 2001 From: frantuma Date: Mon, 6 Nov 2023 14:04:44 +0100 Subject: [PATCH] port CI to GH Actions, Dependabot --- .github/dependabot.yml | 5 +- .github/workflows/dependency-review.yml | 16 +++ .github/workflows/maven-pulls.yml | 30 ++++++ .github/workflows/maven.yml | 79 +++++++++------ .github/workflows/prepare-release.yml | 66 ++++++++++++ .github/workflows/release.yml | 91 +++++++++++++++++ .github/workflows/update_dependency.yml | 96 ------------------ .github/workflows/update_from_bot.yml | 83 --------------- CI/CI.md | 85 ++++++++++++++++ CI/bump-version.sh | 10 -- CI/ghApiClient.py | 59 +++++++++++ CI/lastRelease.py | 19 ++++ CI/nextVersion.py | 14 --- CI/post-release.sh | 25 +++++ CI/pre-release.sh | 18 ++++ CI/prepare-release.sh | 47 +++++++++ CI/publishRelease.py | 27 +++++ CI/releaseNotes.py | 52 ++++++++++ LICENSE | 3 +- NOTICE | 4 + pom.xml | 128 ++++++++++++++++++++---- src/main/swagger/swagger.yaml | 2 +- 22 files changed, 707 insertions(+), 252 deletions(-) create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/maven-pulls.yml create mode 100644 .github/workflows/prepare-release.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/update_dependency.yml delete mode 100644 .github/workflows/update_from_bot.yml create mode 100644 CI/CI.md delete mode 100644 CI/bump-version.sh create mode 100755 CI/ghApiClient.py create mode 100755 CI/lastRelease.py delete mode 100644 CI/nextVersion.py create mode 100755 CI/post-release.sh create mode 100755 CI/pre-release.sh create mode 100755 CI/prepare-release.sh create mode 100755 CI/publishRelease.py create mode 100755 CI/releaseNotes.py create mode 100644 NOTICE diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4d5abe3..db9dd38 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,5 +5,6 @@ updates: directory: "/" schedule: interval: "daily" - allow: - - dependency-name: "io.swagger.parser.v3:*" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] \ No newline at end of file diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..f67f5a4 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,16 @@ +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: Dependency Review + uses: actions/dependency-review-action@v3 + with: + fail-on-severity: high diff --git a/.github/workflows/maven-pulls.yml b/.github/workflows/maven-pulls.yml new file mode 100644 index 0000000..a676dd4 --- /dev/null +++ b/.github/workflows/maven-pulls.yml @@ -0,0 +1,30 @@ +name: Build Test PR + +on: + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + java: [ 11 ] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Build with Maven and Gradle + run: | + mvn --no-transfer-progress -B install --file pom.xml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3aa8e56..918bd1d 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,30 +1,53 @@ -name: Deployment +name: Build Test Deploy master + on: - workflow_dispatch: - branches: - - master + push: + branches: [ "master" ] + jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - java: [ 11 ] - steps: - - uses: actions/checkout@v2 - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - server-id: ossrh - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - - name: Run maven deploy/release (action-maven-publish) - uses: samuelmeuli/action-maven-publish@v1 - with: - gpg_private_key: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }} - gpg_passphrase: ${{ secrets.OSSRH_GPG_PRIVATE_PASSPHRASE }} - nexus_username: ${{ secrets.OSSRH_USERNAME }} - nexus_password: ${{ secrets.OSSRH_TOKEN }} - env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + build: + + runs-on: ubuntu-latest + strategy: + matrix: + java: [ 11 ] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Build with Maven, Deploy snapshot to maven central + run: | + export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + echo "POM VERSION" ${MY_POM_VERSION} + if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; + then + mvn --no-transfer-progress -B install --file pom.xml + export MY_JAVA_VERSION=`java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1` + echo "JAVA VERSION" ${MY_JAVA_VERSION} + if [[ ${MY_JAVA_VERSION} == "11" ]]; + then + export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + echo "POM VERSION" ${MY_POM_VERSION} + mvn --no-transfer-progress -B clean deploy + else + echo "not deploying on java version: " ${MY_JAVA_VERSION} + fi + else + echo "not building and maven publishing project as it is a release version: " ${MY_JAVA_VERSION} + fi + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 0000000..54ae638 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,66 @@ +name: Prepare Release + +on: + workflow_dispatch: + branches: ["master"] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: tibdex/github-app-token@v1 + id: generate-token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Set up Java 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Run prepare release script + id: prepare-release + run: | + export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; + then + . ./CI/prepare-release.sh + echo "PREPARE_RELEASE_OK=yes" >> $GITHUB_ENV + else + echo "not preparing release for release version: " ${MY_POM_VERSION} + echo "PREPARE_RELEASE_OK=no" >> $GITHUB_ENV + fi + echo "SC_VERSION=$SC_VERSION" >> $GITHUB_ENV + echo "SC_NEXT_VERSION=$SC_NEXT_VERSION" >> $GITHUB_ENV + - name: Create Prepare Release Pull Request + uses: peter-evans/create-pull-request@v4 + if: env.PREPARE_RELEASE_OK == 'yes' + with: + token: ${{ steps.generate-token.outputs.token }} + commit-message: prepare release ${{ env.SC_VERSION }} + title: 'prepare release ${{ env.SC_VERSION }}' + branch: prepare-release-${{ env.SC_VERSION }} + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SC_VERSION: + SC_NEXT_VERSION: + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..61164f4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,91 @@ +name: Release + +on: + workflow_dispatch: + branches: ["master"] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: tibdex/github-app-token@v1 + id: generate-token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Set up Java 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Run pre release script + id: preRelease + run: | + # export GPG_TTY=$(tty) + export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` + if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; + then + echo "not releasing snapshot version: " ${MY_POM_VERSION} + echo "RELEASE_OK=no" >> $GITHUB_ENV + else + . ./CI/pre-release.sh + echo "RELEASE_OK=yes" >> $GITHUB_ENV + fi + echo "SC_VERSION=$SC_VERSION" >> $GITHUB_ENV + echo "SC_NEXT_VERSION=$SC_NEXT_VERSION" >> $GITHUB_ENV + echo "SC_LAST_RELEASE=$SC_LAST_RELEASE" >> $GITHUB_ENV + - name: configure git user email + run: | + git config --global user.email "action@github.com" + git config --global user.name "GitHub Action" + git config --global hub.protocol https + git remote set-url origin https://\${{ secrets.GITHUB_TOKEN }}:x-oauth-basic@github.com/''' + 'swagger-api/validator-badge' + '''.git + - name: Run maven deploy/release (action-maven-publish) + uses: samuelmeuli/action-maven-publish@v1 + if: env.RELEASE_OK == 'yes' + with: + gpg_private_key: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }} + gpg_passphrase: ${{ secrets.OSSRH_GPG_PRIVATE_PASSPHRASE }} + nexus_username: ${{ secrets.OSSRH_USERNAME }} + nexus_password: ${{ secrets.OSSRH_TOKEN }} + maven_profiles: "release" + - name: Run post release script + id: postRelease + if: env.RELEASE_OK == 'yes' + run: | + . ./CI/post-release.sh + - name: Create Next Snapshot Pull Request + uses: peter-evans/create-pull-request@v4 + if: env.RELEASE_OK == 'yes' + with: + token: ${{ steps.generate-token.outputs.token }} + commit-message: bump snapshot ${{ env.SC_NEXT_VERSION }}-SNAPSHOT + title: 'bump snapshot ${{ env.SC_NEXT_VERSION }}-SNAPSHOT' + branch: bump-snap-${{ env.SC_NEXT_VERSION }}-SNAPSHOT + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SC_VERSION: + SC_NEXT_VERSION: + GPG_PRIVATE_KEY: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PRIVATE_PASSPHRASE }} + GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} + GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} diff --git a/.github/workflows/update_dependency.yml b/.github/workflows/update_dependency.yml deleted file mode 100644 index ae446f5..0000000 --- a/.github/workflows/update_dependency.yml +++ /dev/null @@ -1,96 +0,0 @@ -name: Swagger Parser Dependency Update -on: - workflow_dispatch: - branches: - - master - inputs: - version: - description: 'Version to update to' - required: true -jobs: - update-swagger-parser-dependency: - runs-on: ubuntu-latest - strategy: - matrix: - java: [ 8 ] - steps: - - uses: actions/checkout@v2 - with: - token: ${{ secrets.GH_TOKEN }} - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - name: Set up Python 2.7 - uses: MatteoH2O1999/setup-python@v1 - with: - python-version: 2.7 - - name: update-dependency - run: | - mvn versions:set-property -DnewVersion=${{ inputs.version }} -Dproperty=swagger-parser-version - - name: Create PR for new dependency version - uses: peter-evans/create-pull-request@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: updating swagger-parser dependency to version ${{ inputs.version }} - title: 'update-swagger-parser-to-${{ inputs.version }}' - branch: update-swagger-parser-to-${{ inputs.version }} - delete-branch: true - - name: Merge new branch into master - run: | - git checkout master - git merge update-swagger-parser-to-${{ inputs.version }} - git push - - name: release - run: | - if [[ ${{ inputs.version }} =~ ^.*SNAPSHOT$ ]]; - then - echo "RELEASE_OK=no" >> $GITHUB_ENV - else - CURRENT_VERSION=$(CI/version.sh) - RELEASE_VERSION=${CURRENT_VERSION/-SNAPSHOT/} - mvn -q versions:set -DnewVersion="${RELEASE_VERSION}" - echo "CURRENT_VERSION=$CURRENT_VERSION" >> $GITHUB_ENV - echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV - echo "RELEASE_OK=yes" >> $GITHUB_ENV - fi - - name: Create PR for new release - uses: peter-evans/create-pull-request@v4 - if: env.RELEASE_OK == 'yes' - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: updating swagger-parser dependency to version ${{ inputs.version }} - title: 'release-to-${{ env.RELEASE_VERSION }}' - branch: release-to-${{ env.RELEASE_VERSION }} - delete-branch: true - - - name: Merge release changes branch into master - if: env.RELEASE_OK == 'yes' - run: | - git checkout master - git merge release-to-${{ env.RELEASE_VERSION }} - git push - - - name: bump up to next snapshot - if: env.RELEASE_OK == 'yes' - shell: bash - run: | - pwd - sh CI/bump-version.sh - BUMPED_VERSION=$(CI/version.sh) - echo "BUMPED_VERSION=$BUMPED_VERSION" >> $GITHUB_ENV - - name: Create PR for next snapshot - uses: peter-evans/create-pull-request@v4 - if: env.RELEASE_OK == 'yes' - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "bump to next snapshot: ${{ env.BUMPED_VERSION }}" - title: 'next-version-to-${{ env.BUMPED_VERSION }}' - branch: next-version-to-${{ env.BUMPED_VERSION }} - delete-branch: true - - name: Merge next version bumping changes into master - if: env.RELEASE_OK == 'yes' - run: | - git checkout master - git merge next-version-to-${{ env.BUMPED_VERSION }} - git push diff --git a/.github/workflows/update_from_bot.yml b/.github/workflows/update_from_bot.yml deleted file mode 100644 index c2462f4..0000000 --- a/.github/workflows/update_from_bot.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Update from Dependabot -on: pull_request - -jobs: - dependabot: - runs-on: ubuntu-latest - if: ${{ github.actor == 'dependabot[bot]' }} - strategy: - matrix: - java: [ 8 ] - steps: - - uses: actions/checkout@v2 - with: - token: ${{ secrets.GH_TOKEN }} - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - name: Set up Python 2.7 - uses: MatteoH2O1999/setup-python@v1 - with: - python-version: 2.7 - - name: Fetch Dependabot metadata - id: dependabot-metadata - uses: dependabot/fetch-metadata@v1 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - name: Merge new branch into master - run: | - git checkout master - git merge ${{ steps.dependabot-metadata.outputs.target-branch }} - git push - - name: release - run: | - if [[ ${{ steps.dependabot-metadata.outputs.target-branch }} =~ ^.*SNAPSHOT$ ]]; - then - echo "RELEASE_OK=no" >> $GITHUB_ENV - else - CURRENT_VERSION=$(CI/version.sh) - RELEASE_VERSION=${CURRENT_VERSION/-SNAPSHOT/} - mvn -q versions:set -DnewVersion="${RELEASE_VERSION}" - echo "CURRENT_VERSION=$CURRENT_VERSION" >> $GITHUB_ENV - echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV - echo "RELEASE_OK=yes" >> $GITHUB_ENV - fi - - name: Create PR for new release - uses: peter-evans/create-pull-request@v4 - if: env.RELEASE_OK == 'yes' - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: updating swagger-parser dependency to version ${{ inputs.version }} - title: 'release-to-${{ env.RELEASE_VERSION }}' - branch: release-to-${{ env.RELEASE_VERSION }} - delete-branch: true - - name: Merge release changes branch into master - if: env.RELEASE_OK == 'yes' - run: | - git checkout master - git merge release-to-${{ env.RELEASE_VERSION }} - git push - - name: bump up to next snapshot - if: env.RELEASE_OK == 'yes' - shell: bash - run: | - pwd - sh CI/bump-version.sh - BUMPED_VERSION=$(CI/version.sh) - echo "BUMPED_VERSION=$BUMPED_VERSION" >> $GITHUB_ENV - - name: Create PR for next snapshot - uses: peter-evans/create-pull-request@v4 - if: env.RELEASE_OK == 'yes' - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "bump to next snapshot: ${{ env.BUMPED_VERSION }}" - title: 'next-version-to-${{ env.BUMPED_VERSION }}' - branch: next-version-to-${{ env.BUMPED_VERSION }} - delete-branch: true - - name: Merge next version bumping changes into master - if: env.RELEASE_OK == 'yes' - run: | - git checkout master - git merge next-version-to-${{ env.BUMPED_VERSION }} - git push diff --git a/CI/CI.md b/CI/CI.md new file mode 100644 index 0000000..d2294b6 --- /dev/null +++ b/CI/CI.md @@ -0,0 +1,85 @@ +## Continuous integration + +### Build, test and deploy +Swagger Validator uses Github actions to run jobs/checks building, testing and deploying snapshots on push and PR events. + +These github actions are configured in `.github/workflows`: + +* maven.yml : Build Test Deploy master +* maven-pulls.yml Build Test PR + + +These actions use available actions in combination with short bash scripts. + +### Release + +Releases are semi-automated and consist in 2 actions using available public actions in combination with bash and python scripts. +**TODO**: Python code is used for historical reasons to execute GitHub APIs calls, in general a more consistent environment would +be more maintainable e.g. implementing a custom JavaScript or Docker Container GitHub Action and/or a bash only script(s). + +#### Workflow summary + +1. execute `prepare-release.yml` / `Prepare Release` for `master` branch +1. check and merge the Prepare Release PR pushed by previous step. Delete the branch +1. execute `release.yml` / `Release` for `master` branch +1. check and merge the next snaphot PR pushed by previous step. Delete the branch + +#### Prepare Release + +The first action to execute is `prepare-release.yml` / `Prepare Release` + +This is triggered by manually executing the action, selecting `Actions` in project GitHub UI, then `Prepare Release` workflow +and clicking `Run Workflow` + +`Prepare Release` takes care of: + +* create release notes out of merged PRs +* Draft a release with related tag +* bump versions to release, and update all affected files +* build and test maven +* push a Pull Request with the changes for human check. + +After the PR checks complete, the PR can me merged, and the second phase `Release` started. + +#### Release + +Once prepare release PR has been merged, the second phase is provided by `release.yml` / `Release` actions. + +This is triggered by manually executing the action, selecting `Actions` in project GitHub UI, then `Release` workflow +and clicking `Run Workflow` + +`Release` takes care of: + +* build and test maven +* build and test gradle plugin +* deploy/publish to maven central +* publish the previously prepared GitHub release / tag +* push PR for next snapshot + + + +### Secrets + +GitHub Actions make use of `Secrets` which can be configured either with Repo or Organization scope; the needed secrets are the following: + +* `APP_ID` and APP_PRIVATE_KEY`: these are the values provided by an account configured GitHub App, allowing to obtain a GitHub token +different from the default used in GitHub Actions (which does not allow to "chain" actions).Actions + +The GitHub App must be configured as detailed in [this doc](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens). + +See also [here](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#triggering-further-workflow-runs) + +* `OSSRH_GPG_PRIVATE_KEY` and `OSSRH_GPG_PRIVATE_PASSPHRASE` : gpg key and passphrase to be used for sonatype releases +GPG private key and passphrase defined to be used for sonatype deployments, as detailed in +https://central.sonatype.org/pages/working-with-pgp-signatures.html (I'd say with email matching the one of the sonatype account of point 1 + +* `OSSRH_USERNAME` and `OSSRH_TOKEN`: sonatype user/token + + + + + + + + + diff --git a/CI/bump-version.sh b/CI/bump-version.sh deleted file mode 100644 index bdea3d5..0000000 --- a/CI/bump-version.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -CURRENT_VERSION="$(./CI/version.sh)" - -echo "old version is: " ${CURRENT_VERSION} - -NEW_VERSION=`python ./CI/nextVersion.py "${CURRENT_VERSION}"` - -echo "pom.xml will be bumped from ${CURRENT_VERSION} to ${NEW_VERSION}" -mvn -q versions:set -DnewVersion="${NEW_VERSION}" diff --git a/CI/ghApiClient.py b/CI/ghApiClient.py new file mode 100755 index 0000000..fcec1ea --- /dev/null +++ b/CI/ghApiClient.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +import os +import time +import urllib.request, urllib.error, urllib.parse +import http.client +import json + +GH_BASE_URL = "https://api.github.com/" + +GH_TOKEN = os.environ['GH_TOKEN'] +GH_AUTH = "Bearer %s" % GH_TOKEN + +def readUrl(name): + try: + request = urllib.request.Request(GH_BASE_URL + name) + request.add_header("Authorization", GH_AUTH) + content = urllib.request.urlopen(request).read() + jcont = json.loads(content) + return jcont + except urllib.error.HTTPError as e: + print(('HTTPError = ' + str(e.code))) + raise e + except urllib.error.URLError as e: + print(('URLError = ' + str(e.reason))) + raise e + except http.client.HTTPException as e: + print(('HTTPException = ' + str(e))) + raise e + except Exception: + import traceback + print(('generic exception: ' + traceback.format_exc())) + raise IOError + +def postUrl(name, body): + global GH_BASE_URL + try: + time.sleep(0.05) + request = urllib.request.Request(GH_BASE_URL + name) + request.add_header("Authorization", GH_AUTH) + request.add_header("Accept", "application/vnd.github.v3+json") + data = body.encode('utf-8') + content = urllib.request.urlopen(request, data).read() + jcont = json.loads(content) + return jcont + except urllib.error.HTTPError as e: + print(('HTTPError = ' + str(e.code))) + print((str(e))) + raise e + except urllib.error.URLError as e: + print(('URLError = ' + str(e.reason))) + raise e + except http.client.HTTPException as e: + print(('HTTPException = ' + str(e))) + raise e + except Exception: + import traceback + print(('generic exception: ' + traceback.format_exc())) + raise IOError diff --git a/CI/lastRelease.py b/CI/lastRelease.py new file mode 100755 index 0000000..fd69ac0 --- /dev/null +++ b/CI/lastRelease.py @@ -0,0 +1,19 @@ +#!/usr/bin/python + +import ghApiClient + +def getLastReleaseTag(): + content = ghApiClient.readUrl('repos/swagger-api/validator-badge/releases') + for l in content: + draft = l["draft"] + tag = l["tag_name"] + if str(draft) != 'True' and tag.startswith("v2"): + return tag[1:] + +# main +def main(): + result = getLastReleaseTag() + print (result) + +# here start main +main() diff --git a/CI/nextVersion.py b/CI/nextVersion.py deleted file mode 100644 index 84b99e1..0000000 --- a/CI/nextVersion.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/python - -import sys - -# main -def main(tag): - if "SNAPSHOT" in tag: - tag = tag.replace("-SNAPSHOT", "") - tagParts = tag.split(".") - bumped = tagParts[0] + "." + tagParts[1] + "." + str(int(tagParts[2]) + 1) - bumped += "-SNAPSHOT" - print bumped -# here start main -main(sys.argv[1]) \ No newline at end of file diff --git a/CI/post-release.sh b/CI/post-release.sh new file mode 100755 index 0000000..1c01dbb --- /dev/null +++ b/CI/post-release.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +CUR=$(pwd) +TMPDIR="$(dirname -- "${0}")" + +SC_RELEASE_TAG="v$SC_VERSION" + +##################### +### publish pre-prepared release (tag is created) +##################### +python $CUR/CI/publishRelease.py "$SC_RELEASE_TAG" + +##################### +### update the version to next snapshot in maven project with set version +##################### +mvn versions:set -DnewVersion="${SC_NEXT_VERSION}-SNAPSHOT" +mvn versions:commit + +##################### +### update all other versions in files around to the next snapshot or new release, including readme and gradle ### +##################### + +sc_find="version\: $SC_VERSION" +sc_replace="version: $SC_NEXT_VERSION-SNAPSHOT" +sed -i -e "s/$sc_find/$sc_replace/g" $CUR/src/main/swager.yaml diff --git a/CI/pre-release.sh b/CI/pre-release.sh new file mode 100755 index 0000000..c4da53d --- /dev/null +++ b/CI/pre-release.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +CUR=$(pwd) + +export SC_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +export SC_NEXT_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +SC_QUALIFIER=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.qualifier}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +#SC_LAST_RELEASE=`mvn -q -Dexec.executable="echo" -Dexec.args='${releasedVersion.version}' --non-recursive org.codehaus.mojo:build-helper-maven-plugin:3.2.0:released-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +SC_LAST_RELEASE=`python $CUR/CI/lastRelease.py` + + +SC_RELEASE_TAG="v$SC_VERSION" + + +##################### +### build and test maven ### +##################### +mvn --no-transfer-progress -B install --file pom.xml diff --git a/CI/prepare-release.sh b/CI/prepare-release.sh new file mode 100755 index 0000000..d6f2cda --- /dev/null +++ b/CI/prepare-release.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +CUR=$(pwd) + +export SC_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +export SC_NEXT_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +SC_QUALIFIER=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.qualifier}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +#SC_LAST_RELEASE=`mvn -q -Dexec.executable="echo" -Dexec.args='${releasedVersion.version}' --non-recursive org.codehaus.mojo:build-helper-maven-plugin:3.2.0:released-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` +SC_LAST_RELEASE=`python $CUR/CI/lastRelease.py` + + + +SC_RELEASE_TITLE="Swagger Validator $SC_VERSION released!" +SC_RELEASE_TAG="v$SC_VERSION" + + +##################### +### draft release Notes with next release after last release, with tag +##################### +python $CUR/CI/releaseNotes.py "$SC_LAST_RELEASE" "$SC_RELEASE_TITLE" "$SC_RELEASE_TAG" + +##################### +### update the version to release in maven project with set version +##################### +mvn versions:set -DnewVersion=$SC_VERSION +mvn versions:commit + + +##################### +### update all other versions in files around to the new release +##################### +sc_find="swagger\-validator\-v2\:v$SC_LAST_RELEASE" +sc_replace="swagger-validator-v2:v$SC_VERSION" +sed -i -e "s/$sc_find/$sc_replace/g" $CUR/README.md + + +sc_find="version\: $SC_VERSION\-SNAPSHOT" +sc_replace="version: $SC_VERSION" +sed -i -e "s/$sc_find/$sc_replace/g" $CUR/src/main/swager.yaml + + + +##################### +### build and test maven ### +##################### +mvn --no-transfer-progress -B install --file pom.xml + diff --git a/CI/publishRelease.py b/CI/publishRelease.py new file mode 100755 index 0000000..d9c78ca --- /dev/null +++ b/CI/publishRelease.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import sys +import ghApiClient + +def lastReleaseId(tag): + content = ghApiClient.readUrl('repos/swagger-api/validator-badge/releases') + for l in content: + draft = l["draft"] + draft_tag = l["tag_name"] + if str(draft) == 'True' and tag == draft_tag: + return l["id"] + +def publishRelease(tag): + id = lastReleaseId(tag) + payload = "{\"tag_name\":\"" + tag + "\", " + payload += "\"draft\":" + "false" + ", " + payload += "\"target_commitish\":\"" + "master" + "\"}" + content = ghApiClient.postUrl('repos/swagger-api/validator-badge/releases/' + str(id), payload) + return content + +# main +def main(tag): + publishRelease (tag) + +# here start main +main(sys.argv[1]) diff --git a/CI/releaseNotes.py b/CI/releaseNotes.py new file mode 100755 index 0000000..059c034 --- /dev/null +++ b/CI/releaseNotes.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +import sys +import json +from datetime import datetime +import ghApiClient + +def allPulls(releaseDate): + + result = "" + + baseurl = "https://api.github.com/repos/swagger-api/validator-badge/pulls/" + content = ghApiClient.readUrl('repos/swagger-api/validator-badge/pulls?state=closed&base=master&per_page=100') + for l in content: + stripped = l["url"][len(baseurl):] + mergedAt = l["merged_at"] + if mergedAt is not None: + if datetime.strptime(mergedAt, '%Y-%m-%dT%H:%M:%SZ') > releaseDate: + if not l['title'].startswith("bump snap"): + result += '\n' + result += "* " + l['title'] + " (#" + stripped + ")" + return result + + +def lastReleaseDate(tag): + content = ghApiClient.readUrl('repos/swagger-api/validator-badge/releases/tags/' + tag) + publishedAt = content["published_at"] + return datetime.strptime(publishedAt, '%Y-%m-%dT%H:%M:%SZ') + + +def addRelease(release_title, tag, content): + payload = "{\"tag_name\":\"" + tag + "\", " + payload += "\"name\":" + json.dumps(release_title) + ", " + payload += "\"body\":" + json.dumps(content) + ", " + payload += "\"draft\":" + "true" + ", " + payload += "\"prerelease\":" + "false" + ", " + payload += "\"target_commitish\":\"" + "master" + "\"}" + content = ghApiClient.postUrl('repos/swagger-api/validator-badge/releases', payload) + return content + +def getReleases(): + content = ghApiClient.readUrl('repos/swagger-api/validator-badge/releases') + return content + +# main +def main(last_release, release_title, tag): + result = allPulls(lastReleaseDate('v' + last_release)) + addRelease (release_title, tag, result) + +# here start main +main(sys.argv[1], sys.argv[2], sys.argv[3]) + diff --git a/LICENSE b/LICENSE index 01abb44..afdeac5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -186,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2020 SmartBear Software Inc. + Copyright (c) 2015. SmartBear Software Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..79d259c --- /dev/null +++ b/NOTICE @@ -0,0 +1,4 @@ +Swagger Validator - ${pom.name} +Copyright (c) 2015. SmartBear Software Inc. +Swagger Validator - ${pom.name} is licensed under Apache 2.0 license. +Copy of the Apache 2.0 license can be found in `LICENSE` file. diff --git a/pom.xml b/pom.xml index c1f79c9..9e54d81 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,8 @@ swagger-validator war swagger-validator - 2.1.3 + 2.1.4-SNAPSHOT + https://github.com/swagger-api/validator-badge 2.2.0 @@ -23,6 +24,10 @@ https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + github + https://github.com/swagger-api/validator-badge/issues + Apache License, Version 2.0 @@ -31,35 +36,61 @@ - scm:git:git://github.com/swagger-api/validator-badge.git - scm:git:ssh://github.com:swagger-api/validator-badge.git - http://github.com/HugoMario/validator-badge/tree/main + scm:git:git@github.com:swagger-api/validator-badge.git + scm:git:git@github.com:swagger-api/validator-badge.git + https://github.com/swagger-api/validator-badge install target ${project.artifactId}-${project.version} + + + src/main/resources + + + META-INF + ../.. + true + + NOTICE + LICENSE + + + + + + org.jvnet.wagon-svn + wagon-svn + 1.12 + + + org.apache.maven.wagon + wagon-ssh-external + 3.5.2 + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + maven-compiler-plugin 3.10.1 - org.codehaus.mojo - build-helper-maven-plugin - 1.10 + org.apache.maven.plugins + maven-source-plugin + 3.2.1 - add-source - generate-sources + attach-sources + verify - add-source + jar-no-fork - - - src/gen/java - - @@ -199,8 +230,69 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh + https://oss.sonatype.org/ + true + 30 + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + + --pinentry-mode + loopback + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + + --pinentry-mode + loopback + + + + + sign-artifacts + verify + + sign + + + + + + + + io.swagger.parser.v3 @@ -343,7 +435,7 @@ 2.15.3 2.15.3 2.2 - 4.5.13 + 4.5.14 1.0.0 2.1.18 2.0.10 @@ -352,9 +444,11 @@ 2.0.9 3.1.2 3.2.0 - 4.13 + 4.13.2 3.24.2 2.2.14 1.0.73 + UTF-8 + https://oss.sonatype.org/content/repositories/snapshots/ diff --git a/src/main/swagger/swagger.yaml b/src/main/swagger/swagger.yaml index b3dbfc8..1a37185 100644 --- a/src/main/swagger/swagger.yaml +++ b/src/main/swagger/swagger.yaml @@ -3,7 +3,7 @@ openapi: 3.0.0 info: title: Swagger Validator Badge description: Parses and validates a Swagger/OpenAPI 2.0 or an OpenAPI 3.x definition - version: 2.1.3 + version: 2.1.4-SNAPSHOT servers: - url: "/" paths: