diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 1225a7b..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,95 +0,0 @@ -version: 2.1 - -orbs: - heroku: circleci/heroku@1.1.1 - -executors: - heroku-18: - docker: - - image: heroku/heroku:18 - heroku-20: - docker: - - image: heroku/heroku:20 - heroku-22: - docker: - - image: heroku/heroku:22 - -jobs: - hatchet: - parameters: - heroku-stack: - type: enum - enum: ["heroku-18", "heroku-20", "heroku-22"] - docker: - - image: circleci/ruby:2.7 - environment: - HEROKU_TEST_STACK: << parameters.heroku-stack >> - HATCHET_BUILDPACK_BASE: https://github.com/heroku/heroku-buildpack-java - HATCHET_APP_LIMIT: 100 - HATCHET_EXPENSIVE_MODE: 1 - PARALLEL_SPLIT_TEST_PROCESSES: 8 - steps: - - checkout - - heroku/install - - run: - name: Install Ruby dependencies - command: | - gem install bundler - bundle install - - run: - name: Hatchet CI setup - command: bundle exec hatchet ci:setup - - run: - name: Execute rspec w/ parallel_split_test - command: bundle exec parallel_split_test test/spec/ - - buildpack-testrunner: - docker: - - image: circleci/openjdk:8 - environment: - SHUNIT_HOME: /tmp/shunit2-2.1.6 - # Note the missing STACK environment variable here. This works since there is a default value in the buildpack - # source. I ported this as-is from the Travis config. Given we're trying to get rid of testrunner entirely, - # it will stay like this. If we, for some reason, decide to keep testrunner, we should look into a fixed STACK env var. - steps: - - checkout - - run: - name: Install required apt packages - command: | - sudo apt-get update - sudo apt-get install file - - run: - name: Download and unpack shunit 2.1.6 - command: curl -sSf --fail --retry 3 --retry-connrefused --connect-timeout 5 https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/shunit2/shunit2-2.1.6.tgz | tar xz -C /tmp/ - - run: - name: Clone heroku-buildpack-testrunner - command: git clone https://github.com/heroku/heroku-buildpack-testrunner.git /tmp/testrunner - - run: - name: Execute buildpack-testrunner - command: /tmp/testrunner/bin/run . - - unit-tests-heroku-buildpack: - parameters: - heroku-stack: - type: enum - enum: ["heroku-18", "heroku-20", "heroku-22"] - environment: - STACK: << parameters.heroku-stack >> - executor: - name: << parameters.heroku-stack >> - steps: - - checkout - - run: test/unit - -workflows: - default-ci-workflow: - jobs: - - buildpack-testrunner - - unit-tests-heroku-buildpack: - matrix: - parameters: - heroku-stack: ["heroku-18", "heroku-20", "heroku-22"] - - hatchet: - matrix: - parameters: - heroku-stack: ["heroku-18", "heroku-20", "heroku-22"] diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8d963c4..5d7a569 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,14 @@ updates: - package-ecosystem: "bundler" directory: "/" schedule: - interval: "weekly" + interval: "monthly" + labels: + - "dependencies" + - "skip changelog" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" labels: - "dependencies" - "skip changelog" diff --git a/.github/workflows/check_changelog.yml b/.github/workflows/check_changelog.yml index fe6e66a..c590644 100644 --- a/.github/workflows/check_changelog.yml +++ b/.github/workflows/check_changelog.yml @@ -2,17 +2,21 @@ name: Check Changelog on: pull_request: - types: [opened, reopened, edited, synchronize, labeled] + types: [opened, reopened, labeled, unlabeled, synchronize] + +permissions: + contents: read jobs: - check: - runs-on: ubuntu-latest + check-changelog: + runs-on: ubuntu-22.04 if: | - !contains(github.event.pull_request.body, '[skip changelog]') && - !contains(github.event.pull_request.body, '[changelog skip]') && - !contains(github.event.pull_request.body, '[skip ci]') && - !contains(github.event.pull_request.labels.*.name, 'skip changelog') + !contains(github.event.pull_request.labels.*.name, 'skip changelog') && + !contains(github.event.pull_request.labels.*.name, 'dependencies') steps: - - uses: actions/checkout@v1 + - name: Checkout + uses: actions/checkout@v3 - name: Check that CHANGELOG is touched - run: git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md + run: | + git fetch origin ${{ github.base_ref }} --depth 1 && \ + git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5e4686e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,96 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + hatchet: + name: "Hatchet (${{ matrix.stack }})" + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + stack: ["heroku-20", "heroku-22"] + env: + HATCHET_APP_LIMIT: 100 + HATCHET_EXPENSIVE_MODE: 1 + PARALLEL_SPLIT_TEST_PROCESSES: 8 + HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }} + HEROKU_API_USER: ${{ secrets.HEROKU_API_USER }} + HEROKU_DISABLE_AUTOUPDATE: 1 + # TODO: Remove once Hatchet supports GitHub Actions natively: + # https://github.com/heroku/hatchet/pull/189 + HATCHET_BUILDPACK_BRANCH: ${{ github.head_ref || github.ref_name }} + HATCHET_BUILDPACK_BASE: https://github.com/heroku/heroku-buildpack-java + # Default stack for all Heroku apps created by Hatchet + DEFAULT_APP_STACK: ${{ matrix.stack }} + steps: + - uses: actions/checkout@v3 + - name: Install Ruby and dependencies + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: "2.7" + - name: Hatchet setup + run: bundle exec hatchet ci:setup + - name: Run Hatchet integration tests + run: bundle exec parallel_split_test test/spec/ + + buildpack-testrunner: + runs-on: ubuntu-22.04 + env: + SHUNIT_HOME: /tmp/shunit2-2.1.6 + # Note the missing STACK environment variable here. This works since there is a default value in the buildpack + # source. I ported this as-is from the Travis config. Given we're trying to get rid of testrunner entirely, + # it will stay like this. If we, for some reason, decide to keep testrunner, we should look into a fixed STACK env var. + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + distribution: zulu + java-version: 8 + - name: Download and unpack shunit 2.1.6 + run: curl -sSf --retry 3 --retry-connrefused --connect-timeout 5 https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/shunit2/shunit2-2.1.6.tgz | tar xz -C /tmp/ + - name: Clone heroku-buildpack-testrunner + run: git clone https://github.com/heroku/heroku-buildpack-testrunner.git /tmp/testrunner + - name: Apply heroku-buildpack-testrunner patches to enforce bash shell + run: | + cd /tmp/testrunner + git apply <<'EOF' + diff --git a/bin/run b/bin/run + index 0d5b790..a0ff25c 100755 + --- a/bin/run + +++ b/bin/run + @@ -101,7 +101,7 @@ for bp in ${@}; do + suite_start_time="$(date +%s)" + + echo " TEST SUITE: $(basename ${f})" + - ${SHUNIT_HOME?"'SHUNIT_HOME' environment variable must be set"}/src/shunit2 ${f} | indent + + /bin/bash ${SHUNIT_HOME?"'SHUNIT_HOME' environment variable must be set"}/src/shunit2 ${f} | indent + exit_code=$(max ${exit_code} ${PIPESTATUS[0]}) + + suite_end_time="$(date +%s)" + + EOF + - name: Execute buildpack-testrunner + run: /tmp/testrunner/bin/run . + + unit-tests: + name: "Unit Tests (${{ matrix.stack }})" + runs-on: ubuntu-22.04 + container: + image: "${{ fromJson('{ \"heroku-20\": \"heroku/heroku:20\", \"heroku-22\": \"heroku/heroku:22\" }')[matrix.stack] }}" + env: + STACK: ${{ matrix.stack }} + strategy: + matrix: + stack: ["heroku-20", "heroku-22"] + steps: + - uses: actions/checkout@v3 + - run: test/unit diff --git a/.github/workflows/hatchet_app_cleaner.yml b/.github/workflows/hatchet_app_cleaner.yml new file mode 100644 index 0000000..45d95ad --- /dev/null +++ b/.github/workflows/hatchet_app_cleaner.yml @@ -0,0 +1,31 @@ +name: Hatchet app cleaner + +on: + schedule: + # Daily at 6am UTC. + - cron: "0 6 * * *" + # Allow the workflow to be manually triggered too. + workflow_dispatch: + +permissions: + contents: read + +jobs: + hatchet-app-cleaner: + runs-on: ubuntu-latest + env: + HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }} + HEROKU_API_USER: ${{ secrets.HEROKU_API_USER }} + HEROKU_DISABLE_AUTOUPDATE: 1 + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install Ruby and dependencies + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: "2.7" + - name: Run Hatchet destroy + # Only apps older than 10 minutes are destroyed, to ensure that any + # in progress CI runs are not interrupted. + run: bundle exec hatchet destroy --older-than 10 diff --git a/CHANGELOG.md b/CHANGELOG.md index e2caf91..c18b761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## main +## v73 + +* Remove heroku-18 support ([#204](https://github.com/heroku/heroku-buildpack-java/pull/204)) +* Upgrade default Maven version to `3.9.4`. ([#207](https://github.com/heroku/heroku-buildpack-java/pull/207)) + ## v72 * Adjust curl retry and connection timeout handling diff --git a/Gemfile.lock b/Gemfile.lock index c149b4c..3aa86c2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,14 +6,14 @@ GEM excon (>= 0.47.0) multi_json erubis (2.7.0) - excon (0.84.0) + excon (0.99.0) heroics (0.1.2) erubis (~> 2.0) excon moneta multi_json (>= 1.9.2) webrick - heroku_hatchet (7.3.4) + heroku_hatchet (8.0.2) excon (~> 0) platform-api (~> 3) rrrretry (~> 1) @@ -26,23 +26,23 @@ GEM parallel_split_test (0.10.0) parallel (>= 0.5.13) rspec-core (>= 3.9.0) - platform-api (3.3.0) + platform-api (3.5.0) heroics (~> 0.1.1) moneta (~> 1.0.0) rate_throttle_client (~> 0.1.0) rate_throttle_client (0.1.2) rrrretry (1.0.0) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.1) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) + rspec-support (~> 3.12.0) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.11.1) - thor (1.1.0) + rspec-support (3.12.0) + thor (1.2.1) threaded (0.0.4) - webrick (1.7.0) + webrick (1.8.1) PLATFORMS ruby diff --git a/README.md b/README.md index 25bebea..67f286d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ![java](https://cloud.githubusercontent.com/assets/871315/20325947/f3544014-ab43-11e6-9c51-8240ce161939.png) This is the official [Scalingo buildpack](https://doc.scalingo.com/buildpacks) for Java apps. -It uses Maven 3.6.2 to build your application and OpenJDK 8 to run it. However, the JDK version can be configured as described below. +It uses Maven 3.9.4 to build your application and OpenJDK 8 to run it. However, the JDK version can be configured as described below. ## How it works @@ -119,25 +119,6 @@ and then: and you'll see the `.m2` and `.maven` directories are now present in your slug. -## Run Tests Locally - -Tests can be run and debugged locally by using the [Circle CI CLI](https://circleci.com/docs/2.0/local-cli/). - -For example, to run [Hatchet](https://github.com/heroku/hatchet) tests on `heroku-18` run: - -``` -$ circleci local execute --job hatchet-heroku-18 \ - --env HEROKU_API_USER=$(heroku whoami) \ - --env HEROKU_API_KEY=$(heroku auth:token) -``` - -Available jobs are defined in [.circleci/config.yml](.circleci/config.yml). - -### Costs - -This command uses the credentials from your local `heroku` configuration. This means your account will be billed for any -cost these tests incur. Proceed with caution. - License ------- diff --git a/buildpack.toml b/buildpack.toml index 6d2c5f5..ed0b59d 100644 --- a/buildpack.toml +++ b/buildpack.toml @@ -6,12 +6,9 @@ name = "Java" "etc/", "spec/", "test/", - "vendor/", ".gitignore", ".github/", - ".travis.yml", - "circle.yml", "hatchet.json", "Gemfile", "Gemfile.lock" - ] \ No newline at end of file + ] diff --git a/lib/common.sh b/lib/common.sh index 044e193..2a658f0 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -export DEFAULT_MAVEN_VERSION="3.6.2" +export DEFAULT_MAVEN_VERSION="3.9.4" install_maven() { local installDir=$1 @@ -13,9 +13,9 @@ install_maven() { mcount "mvn.version.${mavenVersion}" status_pending "Installing Maven ${mavenVersion}" - local mavenUrl="https://lang-jvm.s3.us-east-1.amazonaws.com/maven-${mavenVersion}.tar.gz" + local mavenUrl="https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/${mavenVersion}/apache-maven-${mavenVersion}-bin.tar.gz" if is_supported_maven_version "${mavenVersion}" "${mavenUrl}"; then - download_maven "${mavenUrl}" "${installDir}" "${mavenHome}" + download_maven "${mavenUrl}" "${mavenHome}" status_done else error_return "Error, you have defined an unsupported Maven version in the system.properties file. @@ -27,10 +27,11 @@ The default supported version is ${DEFAULT_MAVEN_VERSION}" download_maven() { local mavenUrl=$1 local installDir=$2 - local mavenHome=$3 - rm -rf $mavenHome - curl --fail --retry 3 --retry-connrefused --connect-timeout 5 --silent --max-time 60 --location "${mavenUrl}" | tar xzm -C $installDir - chmod +x $mavenHome/bin/mvn + + rm -rf $installDir + mkdir -p $installDir + curl --fail --retry 3 --retry-connrefused --connect-timeout 5 --silent --max-time 60 --location "${mavenUrl}" | tar -xzm --strip-components 1 -C $installDir + chmod +x $installDir/bin/mvn } is_supported_maven_version() { diff --git a/test/common_test.sh b/test/common_test.sh index 0a1ddb5..85fcb3b 100644 --- a/test/common_test.sh +++ b/test/common_test.sh @@ -72,17 +72,17 @@ test_detect_maven_version_with_no_file() { } test_is_supported_maven_version_default() { - capture is_supported_maven_version "$DEFAULT_MAVEN_VERSION" "https://lang-jvm.s3.us-east-1.amazonaws.com/maven-$DEFAULT_MAVEN_VERSION.tar.gz" + capture is_supported_maven_version "$DEFAULT_MAVEN_VERSION" "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/${DEFAULT_MAVEN_VERSION}/apache-maven-${DEFAULT_MAVEN_VERSION}-bin.tar.gz" assertCapturedSuccess } test_is_supported_maven_version_old() { - capture is_supported_maven_version "3.6.2" "https://lang-jvm.s3.us-east-1.amazonaws.com/maven-3.6.2.tar.gz" + capture is_supported_maven_version "3.6.2" "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.tar.gz" assertCapturedSuccess } test_is_supported_maven_version_no() { - capture is_supported_maven_version "1.1.1" "https://lang-jvm.s3.us-east-1.amazonaws.com/maven-1.1.1.tar.gz" + capture is_supported_maven_version "1.1.1" "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/1.1.1/apache-maven-1.1.1-bin.tar.gz" assertEquals 1 "${RETURN}" } diff --git a/test/compile_test.sh b/test/compile_test.sh index 1ab7343..2d610ff 100644 --- a/test/compile_test.sh +++ b/test/compile_test.sh @@ -84,7 +84,7 @@ testCustomSettingsXml() compile assertCapturedSuccess - assertCaptured "Should download from JBoss" "Downloading from jboss-no-bees: http://repository.jboss.org/nexus/content/groups/public" + assertCaptured "Should download from JBoss" "Downloading from jboss-no-bees: https://repository.jboss.org/nexus/content/groups/public" } testCustomSettingsXmlWithPath() @@ -98,7 +98,7 @@ testCustomSettingsXmlWithPath() compile assertCapturedSuccess - assertCaptured "Should download from JBoss" "Downloading from jboss-no-bees: http://repository.jboss.org/nexus/content/groups/public" + assertCaptured "Should download from JBoss" "Downloading from jboss-no-bees: https://repository.jboss.org/nexus/content/groups/public" unset MAVEN_SETTINGS_PATH } @@ -114,7 +114,7 @@ testCustomSettingsXmlWithUrl() compile assertCapturedSuccess - assertCaptured "Should download from JBoss" "Downloading from jboss-no-bees: http://repository.jboss.org/nexus/content/groups/public" + assertCaptured "Should download from JBoss" "Downloading from jboss-no-bees: https://repository.jboss.org/nexus/content/groups/public" unset MAVEN_SETTINGS_URL } diff --git a/test/helpers.sh b/test/helpers.sh index e9fde08..a1d7fef 100644 --- a/test/helpers.sh +++ b/test/helpers.sh @@ -62,7 +62,7 @@ createSettingsXml() jboss-no-bees JBoss Public Maven Repository Group - http://repository.jboss.org/nexus/content/groups/public/ + https://repository.jboss.org/nexus/content/groups/public/ @@ -115,8 +115,8 @@ _assertMaven354() { _assertMavenLatest() { local installDir="$(_mavenDir)" - assertCaptured "Wrong Maven Installed" "Installing Maven 3.6.2" - assertFileMD5 "833f5bcc6ee59f6716223f866570bc88" ${installDir}/.maven/bin/mvn + assertCaptured "Wrong Maven Installed" "Installing Maven 3.9.4" + assertFileMD5 "45ca660e83af83fa8213b55fb693326c" ${installDir}/.maven/bin/mvn assertTrue "mvn should be executable" "[ -x ${installDir}/.maven/bin/mvn ]" assertCaptured "Unexpected mvn command" "mvn -DskipTests clean dependency:list install" diff --git a/test/spec/maven_spec.rb b/test/spec/maven_spec.rb index 5f49454..5976d09 100644 --- a/test/spec/maven_spec.rb +++ b/test/spec/maven_spec.rb @@ -31,7 +31,7 @@ expect(app.output).to include("BUILD SUCCESS") expect(http_get(app)).to eq("Hello from Java!") - %w(3.6.2 3.5.4 3.3.9).each do |maven_version| + %w(3.9.4 3.6.2 3.5.4 3.3.9).each do |maven_version| set_maven_version(maven_version) app.commit! app.push! diff --git a/test/spec/spec_helper.rb b/test/spec/spec_helper.rb index 4df5cd7..3e9ddc5 100644 --- a/test/spec/spec_helper.rb +++ b/test/spec/spec_helper.rb @@ -50,5 +50,5 @@ def run(cmd) def http_get(app, options = {}) retry_limit = options[:retry_limit] || 50 path = options[:path] ? "/#{options[:path]}" : "" - Excon.get("https://#{app.name}.herokuapp.com#{path}", :idempotent => true, :expects => 200, :retry_limit => retry_limit).body + Excon.get("#{app.platform_api.app.info(app.name).fetch("web_url")}#{path}", :idempotent => true, :expects => 200, :retry_limit => retry_limit).body end diff --git a/vendor/maven/package b/vendor/maven/package deleted file mode 100755 index 2ec960d..0000000 --- a/vendor/maven/package +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash - -# fail hard -set -o pipefail -# fail harder -set -eu - -VENDOR_DIR=$(cd $(dirname $0); pwd) -TMPDIR=$(mktemp -d -t maven-build) - -echo "---> Downloading sources..." -cd $TMPDIR -for MAVEN in $(cat ${VENDOR_DIR}/sources.txt) -do - echo " $MAVEN..." - curl -O --silent --location $MAVEN -done - -for FILE in apache-maven-*.tar.gz -do - BUILD_DIR=build - NAME=$(echo $FILE | sed -e 's/.*apache-\(maven-[0-9]*.[0-9]*.[0-9]*\)-bin.tar.gz/\1/g') - TARBALL=${NAME}.tar.gz - EXISTS=$(aws s3 ls s3://lang-jvm/${TARBALL} --profile lang-jvm) - if [ -z "$EXISTS" ]; then - echo "---> Building $NAME..." - mkdir -p $BUILD_DIR/.m2/repository - - echo -n " Unpacking..." - tar xzvf $FILE -C $BUILD_DIR &> /dev/null - mv ${BUILD_DIR}/apache-maven* ${BUILD_DIR}/.maven - echo " done" - - echo -n " Priming repository cache..." - cd $BUILD_DIR - cp $VENDOR_DIR/sample_pom.xml pom.xml - .maven/bin/mvn -B -Duser.home=$BUILD_DIR clean package verify install:help &> /dev/null - cd - &> /dev/null - echo " done" - - echo -n " Packaging..." - tar -czvf ${TARBALL} -C ${BUILD_DIR} .maven .m2 &> /dev/null - echo " done" - - echo -n " Uploading..." - aws s3 cp ${TARBALL} s3://lang-jvm --profile lang-jvm --acl public-read &> /dev/null - echo " done" - rm -rf $BUILD_DIR - else - echo "---> Skipping $NAME. Package already exists." - fi -done - -# todo get rid of this and just pipe curl to tar -rm apache-maven-* diff --git a/vendor/maven/sample_pom.xml b/vendor/maven/sample_pom.xml deleted file mode 100644 index e47db73..0000000 --- a/vendor/maven/sample_pom.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - 4.0.0 - com.example - 1.0-SNAPSHOT - sampleapp - sampleapp - jar - - - 1.7 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - ${java.version} - ${java.version} - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 - - - package - copy-dependencies - - - - - - diff --git a/vendor/maven/sources.txt b/vendor/maven/sources.txt deleted file mode 100644 index b9af2f5..0000000 --- a/vendor/maven/sources.txt +++ /dev/null @@ -1,9 +0,0 @@ -https://apache.org/dist/maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.tar.gz -https://apache.org/dist/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz -https://apache.org/dist/maven/maven-3/3.2.3/binaries/apache-maven-3.2.3-bin.tar.gz -https://apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz -https://apache.org/dist/maven/maven-3/3.3.1/binaries/apache-maven-3.3.1-bin.tar.gz -https://apache.org/dist/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.tar.gz -https://apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz -https://archive.apache.org/dist/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz -https://archive.apache.org/dist/maven/maven-3/3.6.2/binaries/apache-maven-3.6.2-bin.tar.gz