├── .gitattributes ├── .github ├── java.json └── workflows │ ├── licensed.yml │ ├── test-nightly.yml │ └── workflow.yml ├── .gitignore ├── .licensed.yml ├── .licenses └── npm │ ├── @actions │ ├── core.dep.yml │ ├── exec.dep.yml │ ├── http-client-1.0.11.dep.yml │ ├── http-client-2.0.1.dep.yml │ ├── io.dep.yml │ └── tool-cache.dep.yml │ ├── @oozcitak │ ├── dom.dep.yml │ ├── infra.dep.yml │ ├── url.dep.yml │ └── util.dep.yml │ ├── @types │ └── node.dep.yml │ ├── argparse.dep.yml │ ├── esprima.dep.yml │ ├── js-yaml.dep.yml │ ├── semver.dep.yml │ ├── sprintf-js.dep.yml │ ├── tunnel.dep.yml │ ├── uuid.dep.yml │ └── xmlbuilder2.dep.yml ├── .prettierrc.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── __tests__ ├── auth.test.ts ├── gpg.test.ts ├── installer.test.ts ├── util.test.ts ├── verify-java.ps1 └── verify-java.sh ├── action.yml ├── dist ├── cleanup │ └── index.js └── setup │ ├── index.js │ └── unzip ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── auth.ts ├── cleanup-java.ts ├── constants.ts ├── gpg.ts ├── installer.ts ├── setup-java.ts ├── setup-jdk.ts └── util.ts ├── tsconfig.json └── yaml-lint-config.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | dist/index.js -diff -merge 2 | dist/index.js linguist-generated=true 3 | .licenses/** -diff linguist-generated=true 4 | -------------------------------------------------------------------------------- /.github/java.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "java", 5 | "pattern": [ 6 | { 7 | "regexp": "^Exception in thread \"(.*)\" (.*): (.*)$", 8 | "code": 2, 9 | "message": 3 10 | } 11 | ] 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /.github/workflows/licensed.yml: -------------------------------------------------------------------------------- 1 | name: Licensed 2 | 3 | on: 4 | push: {branches: main} 5 | pull_request: {branches: main} 6 | 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | name: Check licenses 11 | steps: 12 | - uses: actions/checkout@v2 13 | - run: npm ci 14 | - name: Install licensed 15 | run: | 16 | cd $RUNNER_TEMP 17 | curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.1.0/licensed-3.1.0-linux-x64.tar.gz 18 | sudo tar -xzf licensed.tar.gz 19 | sudo mv licensed /usr/local/bin/licensed 20 | - run: licensed status 21 | -------------------------------------------------------------------------------- /.github/workflows/test-nightly.yml: -------------------------------------------------------------------------------- 1 | name: 'nightly' 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | jobs: 6 | run: 7 | name: Run 8 | runs-on: ${{ matrix.operating-system }} 9 | strategy: 10 | matrix: 11 | operating-system: [ubuntu-latest, macOS-latest, windows-latest] 12 | java-version: [8, 11, 16] 13 | architecture: ['x64', 'x32'] 14 | exclude: 15 | - operating-system: ubuntu-latest 16 | architecture: 'x32' 17 | - operating-system: macOS-latest 18 | architecture: 'x32' 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v2 22 | - name: Set Node.js 12.x 23 | uses: actions/setup-node@v1 24 | with: 25 | node-version: 12.x 26 | - name: npm install 27 | run: npm install 28 | - name: Clear tool cache 29 | if: runner.os != 'windows' 30 | run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" 31 | - name: Clear tool cache (Windows) 32 | if: runner.os == 'windows' 33 | run: move "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" 34 | - name: Setup Java ${{ matrix.java-version}} 35 | id: setup-java 36 | uses: ./ 37 | with: 38 | java-version: ${{ matrix.java-version }} 39 | architecture: ${{ matrix.architecture }} 40 | - name: Verify Java ${{ matrix.java-version}} 41 | if: runner.os != 'windows' 42 | run: __tests__/verify-java.sh "${{ matrix.java-version }}" "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}" 43 | - name: Verify Java ${{ matrix.java-version}} (Windows) 44 | if: runner.os == 'windows' 45 | run: __tests__/verify-java.ps1 "${{ matrix.java-version }}" "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}" 46 | -------------------------------------------------------------------------------- /.github/workflows/workflow.yml: -------------------------------------------------------------------------------- 1 | name: Main workflow 2 | on: 3 | pull_request: 4 | paths-ignore: 5 | - '**.md' 6 | push: 7 | branches: 8 | - master 9 | - releases/* 10 | paths-ignore: 11 | - '**.md' 12 | jobs: 13 | build: 14 | runs-on: ${{ matrix.operating-system }} 15 | strategy: 16 | matrix: 17 | operating-system: [ubuntu-latest, macOS-latest, windows-latest] 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | - name: Setup Node.js 12 22 | uses: actions/setup-node@v1 23 | with: 24 | node-version: 12.x 25 | - name: npm install 26 | run: npm install 27 | - name: Lint 28 | run: npm run format-check 29 | - name: npm test 30 | run: npm test 31 | 32 | test: 33 | runs-on: ${{ matrix.operating-system }} 34 | strategy: 35 | matrix: 36 | operating-system: [ubuntu-latest, macOS-latest, windows-latest] 37 | java-version: [8, 11, 16] 38 | architecture: ['x64', 'x32'] 39 | exclude: 40 | - operating-system: ubuntu-latest 41 | architecture: 'x32' 42 | - operating-system: macOS-latest 43 | architecture: 'x32' 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@v2 47 | - name: Clear tool cache 48 | if: runner.os != 'windows' 49 | run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" 50 | - name: Clear tool cache (Windows) 51 | if: runner.os == 'windows' 52 | run: move "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" 53 | - name: Setup Java ${{ matrix.java-version}} 54 | id: setup-java 55 | uses: ./ 56 | with: 57 | java-version: ${{ matrix.java-version }} 58 | architecture: ${{ matrix.architecture }} 59 | - name: Verify Java ${{ matrix.java-version}} 60 | if: runner.os != 'windows' 61 | run: __tests__/verify-java.sh "${{ matrix.java-version }}" "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}" 62 | - name: Verify Java ${{ matrix.java-version}} (Windows) 63 | if: runner.os == 'windows' 64 | run: __tests__/verify-java.ps1 "${{ matrix.java-version }}" "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}" 65 | 66 | test-proxy: 67 | runs-on: ubuntu-latest 68 | container: 69 | image: ubuntu:latest 70 | options: --dns 127.0.0.1 71 | services: 72 | squid-proxy: 73 | image: datadog/squid:latest 74 | ports: 75 | - 3128:3128 76 | env: 77 | https_proxy: http://squid-proxy:3128 78 | steps: 79 | - uses: actions/checkout@v2 80 | - name: Clear tool cache 81 | run: rm -rf $RUNNER_TOOL_CACHE/* 82 | - name: Setup Java 11 83 | id: setup-java 84 | uses: ./ 85 | with: 86 | java-version: 11 87 | - name: Verify Java 11 88 | run: __tests__/verify-java.sh 11 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}" 89 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore node_modules, ncc is used to compile nodejs modules into a single file 2 | node_modules/ 3 | __tests__/runner/* 4 | 5 | # Ignore js files that are transpiled from ts files in src/ 6 | lib/ 7 | 8 | # Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore 9 | # Logs 10 | logs 11 | *.log 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | lerna-debug.log* 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 19 | 20 | # Runtime data 21 | pids 22 | *.pid 23 | *.seed 24 | *.pid.lock 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | *.lcov 32 | 33 | # nyc test coverage 34 | .nyc_output 35 | 36 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | bower_components 41 | 42 | # node-waf configuration 43 | .lock-wscript 44 | 45 | # Compiled binary addons (https://nodejs.org/api/addons.html) 46 | build/Release 47 | 48 | # Dependency directories 49 | jspm_packages/ 50 | 51 | # TypeScript v1 declaration files 52 | typings/ 53 | 54 | # TypeScript cache 55 | *.tsbuildinfo 56 | 57 | # Optional npm cache directory 58 | .npm 59 | 60 | # Optional eslint cache 61 | .eslintcache 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | 76 | # parcel-bundler cache (https://parceljs.org/) 77 | .cache 78 | 79 | # next.js build output 80 | .next 81 | 82 | # nuxt.js build output 83 | .nuxt 84 | 85 | # vuepress build output 86 | .vuepress/dist 87 | 88 | # Serverless directories 89 | .serverless/ 90 | 91 | # FuseBox cache 92 | .fusebox/ 93 | 94 | # DynamoDB Local files 95 | .dynamodb/ 96 | .vscode/ 97 | -------------------------------------------------------------------------------- /.licensed.yml: -------------------------------------------------------------------------------- 1 | sources: 2 | npm: true 3 | 4 | allowed: 5 | - apache-2.0 6 | - bsd-2-clause 7 | - bsd-3-clause 8 | - isc 9 | - mit 10 | - cc0-1.0 11 | - unlicense 12 | 13 | reviewed: 14 | npm: 15 | # bsd-3-clause 16 | - sprintf-js 17 | -------------------------------------------------------------------------------- /.licenses/npm/@actions/core.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@actions/core" 3 | version: 1.8.2 4 | type: npm 5 | summary: Actions core lib 6 | homepage: https://github.com/actions/toolkit/tree/main/packages/core 7 | license: mit 8 | licenses: 9 | - sources: LICENSE.md 10 | text: |- 11 | The MIT License (MIT) 12 | 13 | Copyright 2019 GitHub 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | notices: [] 21 | -------------------------------------------------------------------------------- /.licenses/npm/@actions/exec.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@actions/exec" 3 | version: 1.1.0 4 | type: npm 5 | summary: 6 | homepage: 7 | license: mit 8 | licenses: 9 | - sources: LICENSE.md 10 | text: |- 11 | The MIT License (MIT) 12 | 13 | Copyright 2019 GitHub 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | notices: [] 21 | -------------------------------------------------------------------------------- /.licenses/npm/@actions/http-client-1.0.11.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@actions/http-client" 3 | version: 1.0.11 4 | type: npm 5 | summary: Actions Http Client 6 | homepage: https://github.com/actions/http-client#readme 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | Actions Http Client for Node.js 12 | 13 | Copyright (c) GitHub, Inc. 14 | 15 | All rights reserved. 16 | 17 | MIT License 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 20 | associated documentation files (the "Software"), to deal in the Software without restriction, 21 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 22 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 23 | subject to the following conditions: 24 | 25 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 28 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 29 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 31 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/@actions/http-client-2.0.1.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@actions/http-client" 3 | version: 2.0.1 4 | type: npm 5 | summary: Actions Http Client 6 | homepage: https://github.com/actions/toolkit/tree/main/packages/http-client 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | Actions Http Client for Node.js 12 | 13 | Copyright (c) GitHub, Inc. 14 | 15 | All rights reserved. 16 | 17 | MIT License 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 20 | associated documentation files (the "Software"), to deal in the Software without restriction, 21 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 22 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 23 | subject to the following conditions: 24 | 25 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 28 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 29 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 31 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/@actions/io.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@actions/io" 3 | version: 1.1.1 4 | type: npm 5 | summary: 6 | homepage: 7 | license: mit 8 | licenses: 9 | - sources: LICENSE.md 10 | text: |- 11 | The MIT License (MIT) 12 | 13 | Copyright 2019 GitHub 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | notices: [] 21 | -------------------------------------------------------------------------------- /.licenses/npm/@actions/tool-cache.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@actions/tool-cache" 3 | version: 1.7.1 4 | type: npm 5 | summary: 6 | homepage: 7 | license: mit 8 | licenses: 9 | - sources: LICENSE.md 10 | text: |- 11 | The MIT License (MIT) 12 | 13 | Copyright 2019 GitHub 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | notices: [] 21 | -------------------------------------------------------------------------------- /.licenses/npm/@oozcitak/dom.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@oozcitak/dom" 3 | version: 1.15.8 4 | type: npm 5 | summary: A modern DOM implementation 6 | homepage: http://github.com/oozcitak/dom 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2019 Ozgur Ozcitak 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/@oozcitak/infra.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@oozcitak/infra" 3 | version: 1.0.8 4 | type: npm 5 | summary: An implementation of the Infra Living Standard 6 | homepage: http://github.com/oozcitak/infra 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2019 Ozgur Ozcitak 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/@oozcitak/url.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@oozcitak/url" 3 | version: 1.0.4 4 | type: npm 5 | summary: An implementation of the URL Living Standard 6 | homepage: http://github.com/oozcitak/url 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2019 Ozgur Ozcitak 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/@oozcitak/util.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@oozcitak/util" 3 | version: 8.3.8 4 | type: npm 5 | summary: Utility functions 6 | homepage: http://github.com/oozcitak/util 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2019 Ozgur Ozcitak 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/@types/node.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "@types/node" 3 | version: 12.20.18 4 | type: npm 5 | summary: TypeScript definitions for Node.js 6 | homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: |2 11 | MIT License 12 | 13 | Copyright (c) Microsoft Corporation. 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/argparse.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: argparse 3 | version: 1.0.10 4 | type: npm 5 | summary: Very powerful CLI arguments parser. Native port of argparse - python's options 6 | parsing library 7 | homepage: 8 | license: mit 9 | licenses: 10 | - sources: LICENSE 11 | text: | 12 | (The MIT License) 13 | 14 | Copyright (C) 2012 by Vitaly Puzrin 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy 17 | of this software and associated documentation files (the "Software"), to deal 18 | in the Software without restriction, including without limitation the rights 19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the Software is 21 | furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in 24 | all copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 32 | THE SOFTWARE. 33 | - sources: README.md 34 | text: |- 35 | Copyright (c) 2012 [Vitaly Puzrin](https://github.com/puzrin). 36 | Released under the MIT license. See 37 | [LICENSE](https://github.com/nodeca/argparse/blob/master/LICENSE) for details. 38 | notices: [] 39 | -------------------------------------------------------------------------------- /.licenses/npm/esprima.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: esprima 3 | version: 4.0.1 4 | type: npm 5 | summary: ECMAScript parsing infrastructure for multipurpose analysis 6 | homepage: http://esprima.org 7 | license: bsd-2-clause 8 | licenses: 9 | - sources: LICENSE.BSD 10 | text: | 11 | Copyright JS Foundation and other contributors, https://js.foundation/ 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/js-yaml.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: js-yaml 3 | version: 3.14.0 4 | type: npm 5 | summary: YAML 1.2 parser and serializer 6 | homepage: https://github.com/nodeca/js-yaml 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | (The MIT License) 12 | 13 | Copyright (C) 2011-2015 by Vitaly Puzrin 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.licenses/npm/semver.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: semver 3 | version: 6.3.0 4 | type: npm 5 | summary: The semantic version parser used by npm. 6 | homepage: https://github.com/npm/node-semver#readme 7 | license: isc 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | The ISC License 12 | 13 | Copyright (c) Isaac Z. Schlueter and Contributors 14 | 15 | Permission to use, copy, modify, and/or distribute this software for any 16 | purpose with or without fee is hereby granted, provided that the above 17 | copyright notice and this permission notice appear in all copies. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 20 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 21 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 22 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 23 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 24 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 25 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 26 | notices: [] 27 | -------------------------------------------------------------------------------- /.licenses/npm/sprintf-js.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: sprintf-js 3 | version: 1.0.3 4 | type: npm 5 | summary: JavaScript sprintf implementation 6 | homepage: 7 | license: other 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | Copyright (c) 2007-2014, Alexandru Marasteanu 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of this software nor the names of its contributors may be 22 | used to endorse or promote products derived from this software without 23 | specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 29 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | - sources: README.md 36 | text: "**sprintf.js** is licensed under the terms of the 3-clause BSD license." 37 | notices: [] 38 | -------------------------------------------------------------------------------- /.licenses/npm/tunnel.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: tunnel 3 | version: 0.0.6 4 | type: npm 5 | summary: Node HTTP/HTTPS Agents for tunneling proxies 6 | homepage: https://github.com/koichik/node-tunnel/ 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | The MIT License (MIT) 12 | 13 | Copyright (c) 2012 Koichi Kobayashi 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | - sources: README.md 33 | text: Licensed under the [MIT](https://github.com/koichik/node-tunnel/blob/master/LICENSE) 34 | license. 35 | notices: [] 36 | -------------------------------------------------------------------------------- /.licenses/npm/uuid.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: uuid 3 | version: 3.4.0 4 | type: npm 5 | summary: RFC4122 (v1, v4, and v5) UUIDs 6 | homepage: 7 | license: mit 8 | licenses: 9 | - sources: LICENSE.md 10 | text: | 11 | The MIT License (MIT) 12 | 13 | Copyright (c) 2010-2016 Robert Kieffer and other contributors 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: 33 | - sources: AUTHORS 34 | text: |- 35 | Robert Kieffer 36 | Christoph Tavan 37 | AJ ONeal 38 | Vincent Voyer 39 | Roman Shtylman 40 | -------------------------------------------------------------------------------- /.licenses/npm/xmlbuilder2.dep.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: xmlbuilder2 3 | version: 2.4.1 4 | type: npm 5 | summary: 6 | homepage: 7 | license: mit 8 | licenses: 9 | - sources: LICENSE 10 | text: | 11 | MIT License 12 | 13 | Copyright (c) 2019 Ozgur Ozcitak 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | notices: [] 33 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "none", 8 | "bracketSpacing": false, 9 | "arrowParens": "avoid", 10 | "parser": "typescript" 11 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | ### Checkin 4 | 5 | - Do checkin source (src) 6 | - Do checkin a single index.js file after running `ncc` 7 | - Do not checking node_modules 8 | 9 | ### NCC 10 | 11 | In order to avoid uploading `node_modules` to the repository, we use [zeit/ncc](https://github.com/zeit/ncc) to create multiple `index.js` files that gets saved under `dist/`. 12 | There are two main files that get created 13 | - `dist/setup/index.js` 14 | - Core `setup-java` logic that downloads and installs an appropriate version of Java 15 | - Handling creating a `settings.xml` file to make it easier to publish packages 16 | - `dist/cleanup/index/js` 17 | - Extra cleanup script that is used to remove GPG keys (needed for certain self-hosted runner scenarios) 18 | 19 | If you're developing locally, after doing `npm install`, you can use the following commands 20 | ```yaml 21 | npm run build # runs tsc along with ncc 22 | npm run format # runs prettier --write 23 | npm run format-check # runs prettier --check 24 | npm run test # runs jest 25 | npm run release # add all the necessary ncc files under dist/* to the git staging area 26 | ``` 27 | 28 | Any files generated using `tsc` will be added to `lib/*`, however those files also are not uploaded to the repository and are excluded using `.gitignore`. 29 | 30 | ### Testing 31 | 32 | Tests are included under `_tests_/*` and can be run using `npm run-script test`. 33 | 34 | We ask that you include a link to a successful run that utilizes the changes you are working on. For example, if your changes are in the branch `newAwesomeFeature`, then show an example run that uses `setup-python@newAwesomeFeature` or `my-fork@newAwesomeFeature`. This will help speed up testing and help us confirm that there are no breaking changes or bugs. 35 | 36 | ### Licensed 37 | 38 | This repository uses a tool called [Licensed](https://github.com/github/licensed) to verify third party dependencies. You may need to locally install licensed and run `licensed cache` to update the dependency cache if you install or update a production dependency. If licensed cache is unable to determine the dependency, you may need to modify the cache file yourself to put the correct license. You should still verify the dependency, licensed is a tool to help, but is not a substitute for human review of dependencies. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 GitHub, Inc. and contributors, Jochen Schalanda 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚨 Notice 2 | 3 | The joschi/setup-jdk GitHub Action is deprecated. 4 | 5 | Please consider switching to the official [actions/setup-java](https://github.com/actions/setup-java) action v2 or later which also supports AdoptOpenJDK and its successor Eclipse Temurin: 6 | 7 | https://github.com/actions/setup-java/tree/v2.5.0#basic 8 | 9 | In order to migrate to [actions/setup-java](https://github.com/actions/setup-java) it is sufficient to replace the name of the action and set the `distribution` parameter to `temurin`. 10 | 11 | **Before:** 12 | 13 | ```yaml 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: joschi/setup-jdk@v2 17 | with: 18 | java-version: '11' # The OpenJDK version to make available on the path 19 | architecture: 'x64' # defaults to 'x64' 20 | - run: java -cp java HelloWorldApp 21 | ``` 22 | 23 | **After:** 24 | 25 | ```yaml 26 | steps: 27 | - uses: actions/checkout@v2 28 | - uses: actions/setup-java@v3 29 | with: 30 | distribution: 'temurin' # See 'Supported distributions' for available options 31 | java-version: '11' 32 | architecture: 'x64' # defaults to 'x64' 33 | - run: java -cp java HelloWorldApp 34 | ``` 35 | 36 | # setup-jdk 37 | 38 |

39 | GitHub Actions status 40 |

41 | 42 | This action sets up a Java development environment with the OpenJDK distribution from [AdoptOpenJDK](https://adoptopenjdk.net/) for use in actions by: 43 | 44 | - Downloading and caching a version of the OpenJDK by version and adding to `PATH`. Downloads from [AdoptOpenJDK](https://adoptopenjdk.net/). 45 | - Registering problem matchers for error output. 46 | 47 | The action is based on [actions/setup-java](https://github.com/actions/setup-java) and is using the [AdoptOpenJDK API](https://api.adoptopenjdk.net/) for fetching the JDK binaries. 48 | 49 | # Usage 50 | 51 | See [action.yml](action.yml) 52 | 53 | ## Basic 54 | ```yaml 55 | steps: 56 | - uses: actions/checkout@v2 57 | - uses: joschi/setup-jdk@v2 58 | with: 59 | java-version: '11' # The OpenJDK version to make available on the path 60 | architecture: 'x64' # defaults to 'x64' 61 | - run: java -cp java HelloWorldApp 62 | ``` 63 | 64 | Examples of version specifications that the java-version parameter will accept: 65 | 66 | - A major Java version 67 | 68 | e.g. ```6, 7, 8, 9, 10, 11, 12, 13, ...``` 69 | 70 | ## Local file 71 | ```yaml 72 | steps: 73 | - uses: actions/checkout@v2 74 | - uses: joschi/setup-jdk@v2 75 | with: 76 | java-version: '4.0.0' 77 | architecture: x64 78 | jdkFile: # Optional - jdkFile to install java from. Useful for versions not found on Zulu Community CDN 79 | - run: java -cp java HelloWorldApp 80 | ``` 81 | 82 | ## Matrix Testing 83 | ```yaml 84 | jobs: 85 | build: 86 | runs-on: ubuntu-latest 87 | strategy: 88 | matrix: 89 | java: [ '8', '11', '13' ] 90 | name: Java ${{ matrix.java }} sample 91 | steps: 92 | - uses: actions/checkout@v2 93 | - name: Setup java 94 | uses: joschi/setup-jdk@v2 95 | with: 96 | java-version: ${{ matrix.java }} 97 | architecture: x64 98 | - run: java -cp java HelloWorldApp 99 | ``` 100 | 101 | ## Publishing using Apache Maven 102 | ```yaml 103 | jobs: 104 | build: 105 | 106 | runs-on: ubuntu-latest 107 | 108 | steps: 109 | - uses: actions/checkout@v2 110 | - name: Set up JDK 1.8 111 | uses: joschi/setup-jdk@v2 112 | with: 113 | java-version: '8' 114 | 115 | - name: Build with Maven 116 | run: mvn -B package --file pom.xml 117 | 118 | - name: Publish to GitHub Packages Apache Maven 119 | run: mvn deploy 120 | env: 121 | GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password 122 | 123 | - name: Set up Apache Maven Central 124 | uses: joschi/setup-jdk@v2 125 | with: # running setup-jdk again overwrites the settings.xml 126 | java-version: '8' 127 | server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml 128 | server-username: MAVEN_USERNAME # env variable for username in deploy 129 | server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy 130 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import 131 | gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase 132 | 133 | - name: Publish to Apache Maven Central 134 | run: mvn deploy 135 | env: 136 | MAVEN_USERNAME: maven_username123 137 | MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} 138 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 139 | ``` 140 | 141 | The two `settings.xml` files created from the above example look like the following. 142 | 143 | `settings.xml` file created for the first deploy to GitHub Packages 144 | ```xml 145 | 148 | 149 | 150 | github 151 | ${env.GITHUB_ACTOR} 152 | ${env.GITHUB_TOKEN} 153 | 154 | 155 | gpg.passphrase 156 | ${env.GPG_PASSPHRASE} 157 | 158 | 159 | 160 | ``` 161 | 162 | `settings.xml` file created for the second deploy to Apache Maven Central 163 | ```xml 164 | 167 | 168 | 169 | maven 170 | ${env.MAVEN_USERNAME} 171 | ${env.MAVEN_CENTRAL_TOKEN} 172 | 173 | 174 | gpg.passphrase 175 | ${env.MAVEN_GPG_PASSPHRASE} 176 | 177 | 178 | 179 | ``` 180 | 181 | ***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.*** 182 | 183 | If you don't want to overwrite the `settings.xml` file, you can set `overwrite-settings: false`. 184 | 185 | If `gpg-private-key` input is provided, the private key will be written to a file in the runner's temp directory, the private key file will be imported into the GPG keychain, and then the file will be promptly removed before proceeding with the rest of the setup process. A cleanup step will remove the imported private key from the GPG keychain after the job completes regardless of the job status. This ensures that the private key is no longer accessible on self-hosted runners and cannot "leak" between jobs (hosted runners are always clean instances). 186 | 187 | See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. 188 | 189 | ## Publishing using Gradle 190 | ```yaml 191 | jobs: 192 | 193 | build: 194 | runs-on: ubuntu-latest 195 | 196 | steps: 197 | - uses: actions/checkout@v2 198 | 199 | - name: Set up JDK 1.8 200 | uses: joschi/setup-jdk@v2 201 | 202 | - name: Build with Gradle 203 | run: gradle build 204 | 205 | - name: Publish to GitHub Packages 206 | run: gradle publish 207 | env: 208 | USERNAME: ${{ github.actor }} 209 | PASSWORD: ${{ secrets.GITHUB_TOKEN }} 210 | ``` 211 | 212 | ***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.*** 213 | 214 | See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. 215 | 216 | ## Apache Maven with a settings path 217 | 218 | When using an Actions self-hosted runner with multiple shared runners the default `$HOME` directory can be shared by a number runners at the same time which could overwrite existing settings file. Setting the `settings-path` variable allows you to choose a unique location for your settings file. 219 | 220 | ```yaml 221 | jobs: 222 | build: 223 | 224 | runs-on: ubuntu-latest 225 | 226 | steps: 227 | - uses: actions/checkout@v2 228 | - name: Set up JDK 1.8 for Shared Runner 229 | uses: joschi/setup-jdk@v2 230 | with: 231 | java-version: '8' 232 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 233 | settings-path: ${{ github.workspace }} # location for the settings.xml file 234 | 235 | - name: Build with Maven 236 | run: mvn -B package --file pom.xml 237 | 238 | - name: Publish to GitHub Packages Apache Maven 239 | run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml 240 | env: 241 | GITHUB_TOKEN: ${{ github.token }} 242 | ``` 243 | 244 | # License 245 | 246 | The scripts and documentation in this project are released under the [MIT License](LICENSE) 247 | 248 | # Contributions 249 | 250 | Contributions are welcome! See [Contributor's Guide](docs/contributors.md) 251 | -------------------------------------------------------------------------------- /__tests__/auth.test.ts: -------------------------------------------------------------------------------- 1 | import io = require('@actions/io'); 2 | import fs = require('fs'); 3 | import os = require('os'); 4 | import path = require('path'); 5 | 6 | // make the os.homedir() call be local to the tests 7 | jest.doMock('os', () => { 8 | return { 9 | homedir: jest.fn(() => __dirname) 10 | }; 11 | }); 12 | 13 | import * as auth from '../src/auth'; 14 | 15 | const m2Dir = path.join(__dirname, auth.M2_DIR); 16 | const settingsFile = path.join(m2Dir, auth.SETTINGS_FILE); 17 | 18 | describe('auth tests', () => { 19 | beforeEach(async () => { 20 | await io.rmRF(m2Dir); 21 | }, 300000); 22 | 23 | afterAll(async () => { 24 | try { 25 | await io.rmRF(m2Dir); 26 | } catch { 27 | console.log('Failed to remove test directories'); 28 | } 29 | }, 100000); 30 | 31 | it('creates settings.xml in alternate locations', async () => { 32 | const id = 'packages'; 33 | const username = 'UNAMI'; 34 | const password = 'TOLKIEN'; 35 | 36 | const altHome = path.join(__dirname, 'runner', 'settings'); 37 | const altSettingsFile = path.join(altHome, auth.SETTINGS_FILE); 38 | process.env[`INPUT_SETTINGS-PATH`] = altHome; 39 | await io.rmRF(altHome); // ensure it doesn't already exist 40 | 41 | await auth.configAuthentication(id, username, password); 42 | 43 | expect(fs.existsSync(m2Dir)).toBe(false); 44 | expect(fs.existsSync(settingsFile)).toBe(false); 45 | 46 | expect(fs.existsSync(altHome)).toBe(true); 47 | expect(fs.existsSync(altSettingsFile)).toBe(true); 48 | expect(fs.readFileSync(altSettingsFile, 'utf-8')).toEqual( 49 | auth.generate(id, username, password) 50 | ); 51 | 52 | delete process.env[`INPUT_SETTINGS-PATH`]; 53 | await io.rmRF(altHome); 54 | }, 100000); 55 | 56 | it('creates settings.xml with minimal configuration', async () => { 57 | const id = 'packages'; 58 | const username = 'UNAME'; 59 | const password = 'TOKEN'; 60 | 61 | await auth.configAuthentication(id, username, password); 62 | 63 | expect(fs.existsSync(m2Dir)).toBe(true); 64 | expect(fs.existsSync(settingsFile)).toBe(true); 65 | expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( 66 | auth.generate(id, username, password) 67 | ); 68 | }, 100000); 69 | 70 | it('creates settings.xml with additional configuration', async () => { 71 | const id = 'packages'; 72 | const username = 'UNAME'; 73 | const password = 'TOKEN'; 74 | const gpgPassphrase = 'GPG'; 75 | 76 | await auth.configAuthentication( 77 | id, 78 | username, 79 | password, 80 | true, 81 | gpgPassphrase 82 | ); 83 | 84 | expect(fs.existsSync(m2Dir)).toBe(true); 85 | expect(fs.existsSync(settingsFile)).toBe(true); 86 | expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( 87 | auth.generate(id, username, password, gpgPassphrase) 88 | ); 89 | }, 100000); 90 | 91 | it('does not overwrite existing settings.xml files', async () => { 92 | const id = 'packages'; 93 | const username = 'USERNAME'; 94 | const password = 'PASSWORD'; 95 | 96 | fs.mkdirSync(m2Dir, {recursive: true}); 97 | fs.writeFileSync(settingsFile, 'FAKE FILE'); 98 | expect(fs.existsSync(m2Dir)).toBe(true); 99 | expect(fs.existsSync(settingsFile)).toBe(true); 100 | 101 | await auth.configAuthentication(id, username, password, false); 102 | 103 | expect(fs.existsSync(m2Dir)).toBe(true); 104 | expect(fs.existsSync(settingsFile)).toBe(true); 105 | expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual('FAKE FILE'); 106 | }, 100000); 107 | 108 | it('overwrites existing settings.xml files', async () => { 109 | const id = 'packages'; 110 | const username = 'USERNAME'; 111 | const password = 'PASSWORD'; 112 | 113 | fs.mkdirSync(m2Dir, {recursive: true}); 114 | fs.writeFileSync(settingsFile, 'FAKE FILE'); 115 | expect(fs.existsSync(m2Dir)).toBe(true); 116 | expect(fs.existsSync(settingsFile)).toBe(true); 117 | 118 | await auth.configAuthentication(id, username, password); 119 | 120 | expect(fs.existsSync(m2Dir)).toBe(true); 121 | expect(fs.existsSync(settingsFile)).toBe(true); 122 | expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( 123 | auth.generate(id, username, password) 124 | ); 125 | }, 100000); 126 | 127 | it('generates valid settings.xml with minimal configuration', () => { 128 | const id = 'packages'; 129 | const username = 'USER'; 130 | const password = '&<>"\'\'"><&'; 131 | 132 | const expectedSettings = ` 135 | 136 | 137 | ${id} 138 | \${env.${username}} 139 | \${env.&<>"''"><&} 140 | 141 | 142 | `; 143 | 144 | expect(auth.generate(id, username, password)).toEqual(expectedSettings); 145 | }); 146 | 147 | it('generates valid settings.xml with additional configuration', () => { 148 | const id = 'packages'; 149 | const username = 'USER'; 150 | const password = '&<>"\'\'"><&'; 151 | const gpgPassphrase = 'PASSPHRASE'; 152 | 153 | const expectedSettings = ` 156 | 157 | 158 | ${id} 159 | \${env.${username}} 160 | \${env.&<>"''"><&} 161 | 162 | 163 | gpg.passphrase 164 | \${env.${gpgPassphrase}} 165 | 166 | 167 | `; 168 | 169 | expect(auth.generate(id, username, password, gpgPassphrase)).toEqual( 170 | expectedSettings 171 | ); 172 | }); 173 | }); 174 | -------------------------------------------------------------------------------- /__tests__/gpg.test.ts: -------------------------------------------------------------------------------- 1 | import path = require('path'); 2 | import io = require('@actions/io'); 3 | import exec = require('@actions/exec'); 4 | 5 | jest.mock('@actions/exec', () => { 6 | return { 7 | exec: jest.fn() 8 | }; 9 | }); 10 | 11 | const tempDir = path.join(__dirname, 'runner', 'temp'); 12 | process.env['RUNNER_TEMP'] = tempDir; 13 | 14 | import gpg = require('../src/gpg'); 15 | 16 | describe('gpg tests', () => { 17 | beforeEach(async () => { 18 | await io.mkdirP(tempDir); 19 | }); 20 | 21 | afterAll(async () => { 22 | try { 23 | await io.rmRF(tempDir); 24 | } catch { 25 | console.log('Failed to remove test directories'); 26 | } 27 | }); 28 | 29 | describe('importKey', () => { 30 | it('attempts to import private key and returns null key id on failure', async () => { 31 | const privateKey = 'KEY CONTENTS'; 32 | const keyId = await gpg.importKey(privateKey); 33 | 34 | expect(keyId).toBeNull(); 35 | 36 | expect(exec.exec).toHaveBeenCalledWith( 37 | 'gpg', 38 | expect.anything(), 39 | expect.anything() 40 | ); 41 | }); 42 | }); 43 | 44 | describe('deleteKey', () => { 45 | it('deletes private key', async () => { 46 | const keyId = 'asdfhjkl'; 47 | await gpg.deleteKey(keyId); 48 | 49 | expect(exec.exec).toHaveBeenCalledWith( 50 | 'gpg', 51 | expect.anything(), 52 | expect.anything() 53 | ); 54 | }); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /__tests__/installer.test.ts: -------------------------------------------------------------------------------- 1 | import io = require('@actions/io'); 2 | import fs = require('fs'); 3 | import path = require('path'); 4 | import child_process = require('child_process'); 5 | 6 | const toolName = 'AdoptOpenJDK'; 7 | const toolDir = path.join(__dirname, 'runner', 'tools'); 8 | const tempDir = path.join(__dirname, 'runner', 'temp'); 9 | const javaDir = path.join(__dirname, 'runner', 'java'); 10 | 11 | process.env['RUNNER_TOOL_CACHE'] = toolDir; 12 | process.env['RUNNER_TEMP'] = tempDir; 13 | import * as installer from '../src/installer'; 14 | 15 | let javaFilePath = ''; 16 | let javaUrl = ''; 17 | let os = ''; 18 | if (process.platform === 'win32') { 19 | javaFilePath = path.join(javaDir, 'java_win.zip'); 20 | javaUrl = 21 | 'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_windows-x64_bin.zip'; 22 | os = 'windows'; 23 | } else if (process.platform === 'darwin') { 24 | javaFilePath = path.join(javaDir, 'java_mac.tar.gz'); 25 | javaUrl = 26 | 'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_osx-x64_bin.tar.gz'; 27 | os = 'mac'; 28 | } else { 29 | javaFilePath = path.join(javaDir, 'java_linux.tar.gz'); 30 | javaUrl = 31 | 'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_linux-x64_bin.tar.gz'; 32 | os = 'linux'; 33 | } 34 | 35 | jest.setTimeout(10000); 36 | 37 | describe('installer tests', () => { 38 | beforeAll(async () => { 39 | await io.rmRF(toolDir); 40 | await io.rmRF(tempDir); 41 | if (!fs.existsSync(`${javaFilePath}.complete`)) { 42 | // Download java 43 | await io.mkdirP(javaDir); 44 | 45 | console.log('Downloading java'); 46 | child_process.execSync(`curl "${javaUrl}" > "${javaFilePath}"`); 47 | // Write complete file so we know it was successful 48 | fs.writeFileSync(`${javaFilePath}.complete`, 'content'); 49 | } 50 | }, 300000); 51 | 52 | afterAll(async () => { 53 | try { 54 | await io.rmRF(toolDir); 55 | await io.rmRF(tempDir); 56 | } catch { 57 | console.log('Failed to remove test directories'); 58 | } 59 | }, 100000); 60 | 61 | it('Installs version of Java from jdkFile if no matching version is installed', async () => { 62 | await installer.getJava('12', 'x64', javaFilePath, 'jdk'); 63 | const JavaDir = path.join(toolDir, 'jdk', '12.0.0', 'x64'); 64 | 65 | expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true); 66 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 67 | }, 100000); 68 | 69 | it('Throws if invalid directory to jdk', async () => { 70 | let thrown = false; 71 | try { 72 | await installer.getJava('1000', 'x64', 'bad path', 'jdk'); 73 | } catch { 74 | thrown = true; 75 | } 76 | expect(thrown).toBe(true); 77 | }); 78 | 79 | it('Downloads java if no file given', async () => { 80 | await installer.getJava('8.0.102', 'x64', '', 'jdk'); 81 | const JavaDir = path.join(toolDir, 'jdk', '8.0.102', 'x64'); 82 | 83 | expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true); 84 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 85 | }, 100000); 86 | 87 | it('Downloads java with 1.x syntax', async () => { 88 | await installer.getJava('1.10', 'x64', '', 'jdk'); 89 | const JavaDir = path.join(toolDir, 'jdk', '10.0.2', 'x64'); 90 | 91 | expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true); 92 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 93 | }, 100000); 94 | 95 | it('Downloads java with normal semver syntax', async () => { 96 | await installer.getJava('9.0.x', 'x64', '', 'jdk'); 97 | const JavaDir = path.join(toolDir, 'jdk', '9.0.7', 'x64'); 98 | 99 | expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true); 100 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 101 | }, 100000); 102 | 103 | it('Downloads java if package is jre', async () => { 104 | await installer.getJava('8.0.222', 'x64', '', 'jre'); 105 | const JavaDir = path.join(toolDir, 'jre', '8.0.222', 'x64'); 106 | 107 | expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true); 108 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 109 | }, 100000); 110 | 111 | it('Downloads java if package is jdk+fx', async () => { 112 | await installer.getJava('8.0.222', 'x64', '', 'jdk+fx'); 113 | const JavaDir = path.join(toolDir, 'jdk+fx', '8.0.222', 'x64'); 114 | 115 | expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true); 116 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 117 | }, 100000); 118 | 119 | it('Throws if invalid java package is specified', async () => { 120 | let thrown = false; 121 | try { 122 | await installer.getJava('8.0.222', 'x64', '', 'bad jdk'); 123 | } catch { 124 | thrown = true; 125 | } 126 | expect(thrown).toBe(true); 127 | }); 128 | 129 | it('Throws if invalid directory to jdk', async () => { 130 | let thrown = false; 131 | try { 132 | await installer.getJava('1000', 'x64', 'bad path', 'jdk'); 133 | } catch { 134 | thrown = true; 135 | } 136 | expect(thrown).toBe(true); 137 | }); 138 | 139 | it('Uses version of Java installed in cache', async () => { 140 | const JavaDir: string = path.join(toolDir, 'jdk', '250.0.0', 'x64'); 141 | await io.mkdirP(JavaDir); 142 | fs.writeFileSync(`${JavaDir}.complete`, 'hello'); 143 | // This will throw if it doesn't find it in the cache (because no such version exists) 144 | await installer.getJava( 145 | '250', 146 | 'x64', 147 | 'path shouldnt matter, found in cache', 148 | 'jdk' 149 | ); 150 | return; 151 | }); 152 | 153 | it('Throws if invalid release_type', async () => { 154 | let thrown = false; 155 | try { 156 | await installer.getAdoptOpenJDK( 157 | 'invalid-release-type', 158 | '11', 159 | 'jdk', 160 | 'hotspot', 161 | 'x64', 162 | 'normal', 163 | 'latest', 164 | '' 165 | ); 166 | } catch { 167 | thrown = true; 168 | } 169 | expect(thrown).toBe(true); 170 | }); 171 | 172 | it('Throws if invalid version', async () => { 173 | let thrown = false; 174 | try { 175 | await installer.getAdoptOpenJDK( 176 | 'ga', 177 | 'invalid-version', 178 | 'jdk', 179 | 'hotspot', 180 | 'x64', 181 | 'normal', 182 | 'latest', 183 | '' 184 | ); 185 | } catch { 186 | thrown = true; 187 | } 188 | expect(thrown).toBe(true); 189 | }); 190 | 191 | it('Throws if invalid image_type', async () => { 192 | let thrown = false; 193 | try { 194 | await installer.getAdoptOpenJDK( 195 | 'ga', 196 | '11', 197 | 'invalid-image_type', 198 | 'hotspot', 199 | 'x64', 200 | 'normal', 201 | 'latest', 202 | '' 203 | ); 204 | } catch { 205 | thrown = true; 206 | } 207 | expect(thrown).toBe(true); 208 | }); 209 | 210 | it('Throws if invalid openjdk_impl', async () => { 211 | let thrown = false; 212 | try { 213 | await installer.getAdoptOpenJDK( 214 | 'ga', 215 | '11', 216 | 'jdk', 217 | 'invalid-openjdk_impl', 218 | 'x64', 219 | 'normal', 220 | 'latest', 221 | '' 222 | ); 223 | } catch { 224 | thrown = true; 225 | } 226 | expect(thrown).toBe(true); 227 | }); 228 | 229 | it('Throws if invalid arch', async () => { 230 | let thrown = false; 231 | try { 232 | await installer.getAdoptOpenJDK( 233 | 'ga', 234 | '11', 235 | 'jdk', 236 | 'hotspot', 237 | 'invalid-arch', 238 | 'normal', 239 | 'latest', 240 | '' 241 | ); 242 | } catch { 243 | thrown = true; 244 | } 245 | expect(thrown).toBe(true); 246 | }); 247 | 248 | it('Downloads JDK with normal syntax', async () => { 249 | await installer.getAdoptOpenJDK( 250 | 'ga', 251 | '11', 252 | 'jdk', 253 | 'hotspot', 254 | 'x64', 255 | 'normal', 256 | 'jdk-11.0.4+11', 257 | '' 258 | ); 259 | const JavaDir = path.join( 260 | toolDir, 261 | toolName, 262 | `1.0.0-ga-11-jdk-hotspot-${os}-x64-normal-jdk-11.0.4`, 263 | 'x64' 264 | ); 265 | 266 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 267 | }, 100000); 268 | 269 | it('Downloads JDK with architecture alias x86_64', async () => { 270 | await installer.getAdoptOpenJDK( 271 | 'ga', 272 | '11', 273 | 'jdk', 274 | 'hotspot', 275 | 'x86_64', 276 | 'normal', 277 | 'jdk-11.0.6+10', 278 | '' 279 | ); 280 | const JavaDir = path.join( 281 | toolDir, 282 | toolName, 283 | `1.0.0-ga-11-jdk-hotspot-${os}-x64-normal-jdk-11.0.6`, 284 | 'x64' 285 | ); 286 | 287 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 288 | }, 100000); 289 | 290 | it('Downloads JRE with normal syntax', async () => { 291 | await installer.getAdoptOpenJDK( 292 | 'ga', 293 | '11', 294 | 'jre', 295 | 'hotspot', 296 | 'x64', 297 | 'normal', 298 | 'jdk-11.0.4+11', 299 | '' 300 | ); 301 | const JavaDir = path.join( 302 | toolDir, 303 | toolName, 304 | `1.0.0-ga-11-jdk-hotspot-${os}-x64-normal-jdk-11.0.4`, 305 | 'x64' 306 | ); 307 | 308 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 309 | }, 100000); 310 | 311 | it('Uses version of JDK installed in cache', async () => { 312 | const JavaDir: string = path.join( 313 | toolDir, 314 | toolName, 315 | `1.0.0-ga-my-custom-version-jdk-hotspot-${os}-x64-normal-123.4.5`, 316 | 'x64' 317 | ); 318 | await io.mkdirP(JavaDir); 319 | fs.writeFileSync(`${JavaDir}.complete`, 'hello'); 320 | // This will throw if it doesn't find it in the cache (because no such version exists) 321 | await installer.getAdoptOpenJDK( 322 | 'ga', 323 | 'my-custom-version', 324 | 'jdk', 325 | 'hotspot', 326 | 'x64', 327 | 'normal', 328 | '123.4.5', 329 | '' 330 | ); 331 | return; 332 | }); 333 | 334 | it('Doesnt use version of Java that was only partially installed in cache', async () => { 335 | const JavaDir: string = path.join(toolDir, 'jdk', '251.0.0', 'x64'); 336 | await io.mkdirP(JavaDir); 337 | let thrown = false; 338 | try { 339 | // This will throw if it doesn't find it in the cache (because no such version exists) 340 | await installer.getJava('251', 'x64', 'bad path', 'jdk'); 341 | } catch { 342 | thrown = true; 343 | } 344 | expect(thrown).toBe(true); 345 | return; 346 | }); 347 | 348 | it('GitHub issue #9: Allow openjdk[0-9]+ as Java release version', async () => { 349 | await installer.getAdoptOpenJDK( 350 | 'ga', 351 | 'openjdk14', 352 | 'jdk', 353 | 'hotspot', 354 | 'x64', 355 | 'normal', 356 | 'latest', 357 | '' 358 | ); 359 | const JavaDir = path.join( 360 | toolDir, 361 | toolName, 362 | `1.0.0-ga-14-jdk-hotspot-${os}-x64-normal-latest`, 363 | 'x64' 364 | ); 365 | 366 | expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true); 367 | }, 100000); 368 | }); 369 | -------------------------------------------------------------------------------- /__tests__/util.test.ts: -------------------------------------------------------------------------------- 1 | import path = require('path'); 2 | 3 | const env = process.env; 4 | 5 | describe('util tests', () => { 6 | beforeEach(() => { 7 | const tempEnv = Object.assign({}, env); 8 | delete tempEnv.RUNNER_TEMP; 9 | delete tempEnv.USERPROFILE; 10 | process.env = tempEnv; 11 | Object.defineProperty(process, 'platform', {value: 'linux'}); 12 | }); 13 | 14 | describe('getTempDir', () => { 15 | it('gets temp dir using env', () => { 16 | process.env['RUNNER_TEMP'] = 'defaulttmp'; 17 | const util = require('../src/util'); 18 | 19 | const tempDir = util.getTempDir(); 20 | 21 | expect(tempDir).toEqual(process.env['RUNNER_TEMP']); 22 | }); 23 | 24 | it('gets temp dir for windows using userprofile', () => { 25 | Object.defineProperty(process, 'platform', {value: 'win32'}); 26 | process.env['USERPROFILE'] = 'winusertmp'; 27 | const util = require('../src/util'); 28 | 29 | const tempDir = util.getTempDir(); 30 | 31 | expect(tempDir).toEqual( 32 | path.join(process.env['USERPROFILE'], 'actions', 'temp') 33 | ); 34 | }); 35 | 36 | it('gets temp dir for windows using c drive', () => { 37 | Object.defineProperty(process, 'platform', {value: 'win32'}); 38 | const util = require('../src/util'); 39 | 40 | const tempDir = util.getTempDir(); 41 | 42 | expect(tempDir).toEqual(path.join('C:\\', 'actions', 'temp')); 43 | }); 44 | 45 | it('gets temp dir for mac', () => { 46 | Object.defineProperty(process, 'platform', {value: 'darwin'}); 47 | const util = require('../src/util'); 48 | 49 | const tempDir = util.getTempDir(); 50 | 51 | expect(tempDir).toEqual(path.join('/Users', 'actions', 'temp')); 52 | }); 53 | 54 | it('gets temp dir for linux', () => { 55 | const util = require('../src/util'); 56 | const tempDir = util.getTempDir(); 57 | 58 | expect(tempDir).toEqual(path.join('/home', 'actions', 'temp')); 59 | }); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /__tests__/verify-java.ps1: -------------------------------------------------------------------------------- 1 | if (!$args.Count -or !$args[0]) 2 | { 3 | throw "Must supply java version argument" 4 | } 5 | 6 | $java_version = & cmd.exe /c "java -version 2>&1" | Out-String 7 | Write-Host "Found java version: $java_version" 8 | if (!$java_version -contains $args[0]) 9 | { 10 | throw "Unexpected version" 11 | } 12 | 13 | if ($args.Count -lt 2 -or !$args[1]) 14 | { 15 | throw "Must supply java path argument" 16 | } 17 | 18 | if ($args[1] -ne $Env:JAVA_HOME) 19 | { 20 | throw "Unexpected path" 21 | } 22 | 23 | if ($args.Count -lt 3 -or !$args[2]) 24 | { 25 | throw "Must supply java version argument" 26 | } 27 | 28 | if ($args[0] -ne $args[2]) 29 | { 30 | throw "Unexpected version" 31 | } 32 | -------------------------------------------------------------------------------- /__tests__/verify-java.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -z "$1" ]; then 4 | echo "::error::Must supply java version argument" 5 | exit 1 6 | fi 7 | 8 | java_version="$(java -version 2>&1)" 9 | echo "Found java version: $java_version" 10 | if [ -z "$(echo $java_version | grep --fixed-strings $1)" ]; then 11 | echo "::error::Unexpected version" 12 | exit 1 13 | fi 14 | 15 | if [ -z "$2" ]; then 16 | echo "::error::Must supply java path argument" 17 | exit 1 18 | fi 19 | 20 | if [ "$2" != "$JAVA_HOME" ]; then 21 | echo "::error::Unexpected path" 22 | exit 1 23 | fi 24 | 25 | if [ -z "$3" ]; then 26 | echo "::error::Must supply java version argument" 27 | exit 1 28 | fi 29 | 30 | if [ "$1" != "$3" ]; then 31 | echo "::error::Unexpected version" 32 | exit 1 33 | fi 34 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup AdoptOpenJDK' 2 | description: 'DEPRECATED: Please use actions/setup-java v2 or later to set up OpenJDK from AdoptOpenJDK or Eclipse Temurin.' 3 | author: 'Jochen Schalanda' 4 | inputs: 5 | release_type: 6 | description: 'Type of release. Either a release version, known as 7 | General Availability ("ga") or an Early Access ("ea"). Default: "ga"' 8 | required: false 9 | default: 'ga' 10 | java-version: 11 | description: 'OpenJDK feature release version you wish to download. 12 | Feature versions are whole numbers, example 8, 11, 15' 13 | required: true 14 | java-package: 15 | description: 'The package type (jre, jdk). Default: "jdk"' 16 | required: false 17 | default: 'jdk' 18 | openjdk_impl: 19 | description: 'JVM implementation, example: "hotspot", "openj9". Default: "hotspot"' 20 | required: false 21 | default: 'hotspot' 22 | architecture: 23 | description: 'Architecture of the JDK, example: "x64", "x32", "ppc64", "s390x", 24 | "ppc64le", "aarch64". Default: "x64"' 25 | required: false 26 | default: 'x64' 27 | heap_size: 28 | description: 'Heap size for OpenJ9, example: "normal", "large" (for heaps >=57 GiB). 29 | Default: "normal"' 30 | required: false 31 | default: 'normal' 32 | release: 33 | description: 'Exact release of OpenJDK, example: "latest", "jdk-11.0.4+11.4", 34 | "jdk8u172-b00-201807161800". Default: "latest"' 35 | required: false 36 | default: 'latest' 37 | jdkFile: 38 | description: 'Path to where the compressed JDK is located. The path could 39 | be in your source repository or a local path on the agent.' 40 | required: false 41 | server-id: 42 | description: 'ID of the distributionManagement repository in the pom.xml 43 | file. Default is `github`' 44 | required: false 45 | default: 'github' 46 | server-username: 47 | description: 'Environment variable name for the username for authentication 48 | to the Apache Maven repository. Default is $GITHUB_ACTOR' 49 | required: false 50 | default: 'GITHUB_ACTOR' 51 | server-password: 52 | description: 'Environment variable name for password or token for 53 | authentication to the Apache Maven repository. Default is $GITHUB_TOKEN' 54 | required: false 55 | default: 'GITHUB_TOKEN' 56 | settings-path: 57 | description: 'Path to where the settings.xml file will be written. Default is ~/.m2.' 58 | required: false 59 | gpg-private-key: 60 | description: 'GPG private key to import. Default is empty string.' 61 | required: false 62 | gpg-passphrase: 63 | description: 'Environment variable name for the GPG private key passphrase. Default is 64 | $GPG_PASSPHRASE.' 65 | required: false 66 | overwrite-settings: 67 | description: 'Overwrite the settings.xml file if it exists. Default is "true".' 68 | required: false 69 | outputs: 70 | path: 71 | description: 'Path to where the java environment has been installed (same as $JAVA_HOME)' 72 | version: 73 | description: 'Actual version of the java environment that has been installed' 74 | runs: 75 | using: 'node12' 76 | main: 'dist/setup/index.js' 77 | post: 'dist/cleanup/index.js' 78 | branding: 79 | icon: 'download' 80 | color: 'blue' 81 | -------------------------------------------------------------------------------- /dist/setup/unzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joschi/setup-jdk/1818212fcdf7eea4e09a6eb156c536640bf7b52f/dist/setup/unzip -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | clearMocks: true, 3 | moduleFileExtensions: ['js', 'ts'], 4 | testEnvironment: 'node', 5 | testMatch: ['**/*.test.ts'], 6 | testRunner: 'jest-circus/runner', 7 | transform: { 8 | '^.+\\.ts$': 'ts-jest' 9 | }, 10 | verbose: true 11 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "setup-jdk", 3 | "version": "2.5.1", 4 | "private": true, 5 | "description": "Setup JDK action", 6 | "main": "dist/setup/index.js", 7 | "scripts": { 8 | "build": "ncc build -o dist/setup src/setup-jdk.ts && ncc build -o dist/cleanup src/cleanup-java.ts", 9 | "format": "prettier --write **/*.ts", 10 | "format-check": "prettier --check **/*.ts", 11 | "prerelease": "npm run-script build", 12 | "release": "git add -f dist/setup/index.js dist/cleanup/index.js", 13 | "test": "jest" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/joschi/setup-jdk.git" 18 | }, 19 | "keywords": [ 20 | "actions", 21 | "java", 22 | "openjdk", 23 | "adoptopenjdk", 24 | "setup" 25 | ], 26 | "author": "Jochen Schalanda", 27 | "license": "MIT", 28 | "dependencies": { 29 | "@actions/core": "^1.5.0", 30 | "@actions/exec": "^1.0.0", 31 | "@actions/http-client": "^1.0.8", 32 | "@actions/io": "^1.0.0", 33 | "@actions/tool-cache": "^1.3.1", 34 | "semver": "^6.1.1", 35 | "xmlbuilder2": "^2.1.2" 36 | }, 37 | "devDependencies": { 38 | "@types/jest": "^24.0.13", 39 | "@types/node": "^12.0.4", 40 | "@types/semver": "^6.0.0", 41 | "@zeit/ncc": "^0.20.5", 42 | "jest": "^24.8.0", 43 | "jest-circus": "^24.7.1", 44 | "prettier": "^1.19.1", 45 | "ts-jest": "^24.0.2", 46 | "typescript": "^3.5.1" 47 | }, 48 | "husky": { 49 | "skipCI": true, 50 | "hooks": { 51 | "pre-commit": "npm run build && npm run format" 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/auth.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as os from 'os'; 3 | import * as path from 'path'; 4 | import * as core from '@actions/core'; 5 | import * as io from '@actions/io'; 6 | import {create as xmlCreate} from 'xmlbuilder2'; 7 | import * as constants from './constants'; 8 | 9 | export const M2_DIR = '.m2'; 10 | export const SETTINGS_FILE = 'settings.xml'; 11 | 12 | export async function configAuthentication( 13 | id: string, 14 | username: string, 15 | password: string, 16 | overwriteSettings: boolean = true, 17 | gpgPassphrase: string | undefined = undefined 18 | ) { 19 | console.log( 20 | `creating ${SETTINGS_FILE} with server-id: ${id};`, 21 | 'environment variables:', 22 | `username=\$${username},`, 23 | `password=\$${password},`, 24 | `and gpg-passphrase=${gpgPassphrase ? '$' + gpgPassphrase : null}` 25 | ); 26 | // when an alternate m2 location is specified use only that location (no .m2 directory) 27 | // otherwise use the home/.m2/ path 28 | const settingsDirectory: string = path.join( 29 | core.getInput(constants.INPUT_SETTINGS_PATH) || os.homedir(), 30 | core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : M2_DIR 31 | ); 32 | await io.mkdirP(settingsDirectory); 33 | core.debug(`created directory ${settingsDirectory}`); 34 | await write( 35 | settingsDirectory, 36 | generate(id, username, password, gpgPassphrase), 37 | overwriteSettings 38 | ); 39 | } 40 | 41 | // only exported for testing purposes 42 | export function generate( 43 | id: string, 44 | username: string, 45 | password: string, 46 | gpgPassphrase: string | undefined = undefined 47 | ) { 48 | const xmlObj: {[key: string]: any} = { 49 | settings: { 50 | '@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0', 51 | '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', 52 | '@xsi:schemaLocation': 53 | 'http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd', 54 | servers: { 55 | server: [ 56 | { 57 | id: id, 58 | username: `\${env.${username}}`, 59 | password: `\${env.${password}}` 60 | } 61 | ] 62 | } 63 | } 64 | }; 65 | 66 | if (gpgPassphrase) { 67 | const gpgServer = { 68 | id: 'gpg.passphrase', 69 | passphrase: `\${env.${gpgPassphrase}}` 70 | }; 71 | xmlObj.settings.servers.server.push(gpgServer); 72 | } 73 | 74 | return xmlCreate(xmlObj).end({headless: true, prettyPrint: true, width: 80}); 75 | } 76 | 77 | async function write( 78 | directory: string, 79 | settings: string, 80 | overwriteSettings: boolean 81 | ) { 82 | const location = path.join(directory, SETTINGS_FILE); 83 | const exists = fs.existsSync(location); 84 | if (exists && overwriteSettings) { 85 | console.warn(`overwriting existing file ${location}`); 86 | } else if (!exists) { 87 | console.log(`writing ${location}`); 88 | } else { 89 | console.log(`not overwriting existing file ${location}`); 90 | return; 91 | } 92 | 93 | return fs.writeFileSync(location, settings, { 94 | encoding: 'utf-8', 95 | flag: 'w' 96 | }); 97 | } 98 | -------------------------------------------------------------------------------- /src/cleanup-java.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import * as gpg from './gpg'; 3 | import * as constants from './constants'; 4 | 5 | async function run() { 6 | if (core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false})) { 7 | core.info('removing private key from keychain'); 8 | try { 9 | const keyFingerprint = core.getState( 10 | constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT 11 | ); 12 | await gpg.deleteKey(keyFingerprint); 13 | } catch (error) { 14 | core.setFailed('failed to remove private key'); 15 | } 16 | } 17 | } 18 | 19 | run(); 20 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const INPUT_VERSION = 'version'; 2 | export const INPUT_JAVA_VERSION = 'java-version'; 3 | export const INPUT_ARCHITECTURE = 'architecture'; 4 | export const INPUT_JAVA_PACKAGE = 'java-package'; 5 | export const INPUT_JDK_FILE = 'jdkFile'; 6 | export const INPUT_SERVER_ID = 'server-id'; 7 | export const INPUT_SERVER_USERNAME = 'server-username'; 8 | export const INPUT_SERVER_PASSWORD = 'server-password'; 9 | export const INPUT_SETTINGS_PATH = 'settings-path'; 10 | export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key'; 11 | export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase'; 12 | export const INPUT_RELEASE_TYPE = 'release_type'; 13 | export const INPUT_OPENJDK_IMPL = 'openjdk_impl'; 14 | export const INPUT_HEAP_SIZE = 'heap_size'; 15 | export const INPUT_RELEASE = 'release'; 16 | export const INPUT_OVERWRITE_SETTINGS = 'overwrite-settings'; 17 | 18 | export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; 19 | export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; 20 | 21 | export const STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint'; 22 | -------------------------------------------------------------------------------- /src/gpg.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | import * as io from '@actions/io'; 4 | import * as exec from '@actions/exec'; 5 | import * as util from './util'; 6 | import {ExecOptions} from '@actions/exec/lib/interfaces'; 7 | 8 | export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc'); 9 | 10 | const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/; 11 | 12 | export async function importKey(privateKey: string) { 13 | fs.writeFileSync(PRIVATE_KEY_FILE, privateKey, { 14 | encoding: 'utf-8', 15 | flag: 'w' 16 | }); 17 | 18 | let output = ''; 19 | 20 | const options: ExecOptions = { 21 | silent: true, 22 | listeners: { 23 | stdout: (data: Buffer) => { 24 | output += data.toString(); 25 | } 26 | } 27 | }; 28 | 29 | await exec.exec( 30 | 'gpg', 31 | [ 32 | '--batch', 33 | '--import-options', 34 | 'import-show', 35 | '--import', 36 | PRIVATE_KEY_FILE 37 | ], 38 | options 39 | ); 40 | 41 | await io.rmRF(PRIVATE_KEY_FILE); 42 | 43 | const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); 44 | return match && match[0]; 45 | } 46 | 47 | export async function deleteKey(keyFingerprint: string) { 48 | await exec.exec( 49 | 'gpg', 50 | ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], 51 | {silent: true} 52 | ); 53 | await exec.exec( 54 | 'gpg', 55 | ['--batch', '--yes', '--delete-keys', keyFingerprint], 56 | {silent: true} 57 | ); 58 | } 59 | -------------------------------------------------------------------------------- /src/installer.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import * as exec from '@actions/exec'; 3 | import * as fs from 'fs'; 4 | import * as httpm from '@actions/http-client'; 5 | import * as io from '@actions/io'; 6 | import * as path from 'path'; 7 | import * as semver from 'semver'; 8 | import * as tc from '@actions/tool-cache'; 9 | import * as util from './util'; 10 | 11 | const IS_WINDOWS = util.isWindows(); 12 | const IS_MACOS = util.isDarwin(); 13 | const toolName = 'AdoptOpenJDK'; 14 | const os = getOsString(process.platform); 15 | const architectureAliases = new Map([ 16 | ['amd64', 'x64'], 17 | ['i686', 'x32'], 18 | ['x86', 'x32'], 19 | ['x86_64', 'x64'] 20 | ]); 21 | 22 | const tempDirectory = util.getTempDir(); 23 | 24 | export async function getJava( 25 | version: string, 26 | arch: string, 27 | jdkFile: string, 28 | javaPackage: string 29 | ): Promise { 30 | let toolPath = tc.find(javaPackage, version); 31 | 32 | if (toolPath) { 33 | core.debug(`Tool found in cache ${toolPath}`); 34 | } else { 35 | let compressedFileExtension = ''; 36 | if (!jdkFile) { 37 | core.debug('Downloading JDK from Azul'); 38 | const http = new httpm.HttpClient('setup-java', undefined, { 39 | allowRetries: true, 40 | maxRetries: 3 41 | }); 42 | const url = 'https://static.azul.com/zulu/bin/'; 43 | const response = await http.get(url); 44 | const statusCode = response.message.statusCode || 0; 45 | if (statusCode < 200 || statusCode > 299) { 46 | let body = ''; 47 | try { 48 | body = await response.readBody(); 49 | } catch (err) { 50 | core.debug(`Unable to read body: ${err.message}`); 51 | } 52 | const message = `Unexpected HTTP status code '${response.message.statusCode}' when retrieving versions from '${url}'. ${body}`.trim(); 53 | throw new Error(message); 54 | } 55 | 56 | const contents = await response.readBody(); 57 | const refs = contents.match(//gi) || []; 58 | const downloadInfo = getDownloadInfo(refs, version, arch, javaPackage); 59 | jdkFile = await tc.downloadTool(downloadInfo.url); 60 | version = downloadInfo.version; 61 | compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; 62 | } else { 63 | core.debug('Retrieving Jdk from local path'); 64 | } 65 | compressedFileExtension = compressedFileExtension || getFileEnding(jdkFile); 66 | let tempDir: string = path.join( 67 | tempDirectory, 68 | 'temp_' + Math.floor(Math.random() * 2000000000) 69 | ); 70 | const jdkDir = await unzipJavaDownload( 71 | jdkFile, 72 | compressedFileExtension, 73 | tempDir 74 | ); 75 | core.debug(`jdk extracted to ${jdkDir}`); 76 | toolPath = await tc.cacheDir( 77 | jdkDir, 78 | javaPackage, 79 | getCacheVersionString(version), 80 | arch 81 | ); 82 | } 83 | 84 | let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch; 85 | core.exportVariable(extendedJavaHome, toolPath); //TODO: remove for v2 86 | // For portability reasons environment variables should only consist of 87 | // uppercase letters, digits, and the underscore. Therefore we convert 88 | // the extendedJavaHome variable to upper case and replace '.' symbols and 89 | // any other non-alphanumeric characters with an underscore. 90 | extendedJavaHome = extendedJavaHome.toUpperCase().replace(/[^0-9A-Z_]/g, '_'); 91 | core.exportVariable('JAVA_HOME', toolPath); 92 | core.exportVariable(extendedJavaHome, toolPath); 93 | core.addPath(path.join(toolPath, 'bin')); 94 | core.setOutput('path', toolPath); 95 | core.setOutput('version', version); 96 | } 97 | 98 | function getCacheVersionString(version: string) { 99 | const versionArray = version.split('.'); 100 | const major = versionArray[0]; 101 | const minor = versionArray.length > 1 ? versionArray[1] : '0'; 102 | const patch = versionArray.length > 2 ? versionArray[2] : '0'; 103 | return `${major}.${minor}.${patch}`; 104 | } 105 | 106 | function getFileEnding(file: string): string { 107 | let fileEnding = ''; 108 | 109 | if (file.endsWith('.tar')) { 110 | fileEnding = '.tar'; 111 | } else if (file.endsWith('.tar.gz')) { 112 | fileEnding = '.tar.gz'; 113 | } else if (file.endsWith('.zip')) { 114 | fileEnding = '.zip'; 115 | } else if (file.endsWith('.7z')) { 116 | fileEnding = '.7z'; 117 | } else { 118 | throw new Error(`${file} has an unsupported file extension`); 119 | } 120 | 121 | return fileEnding; 122 | } 123 | 124 | async function extractFiles( 125 | file: string, 126 | fileEnding: string, 127 | destinationFolder: string 128 | ): Promise { 129 | const stats = fs.statSync(file); 130 | if (!stats) { 131 | throw new Error(`Failed to extract ${file} - it doesn't exist`); 132 | } else if (stats.isDirectory()) { 133 | throw new Error(`Failed to extract ${file} - it is a directory`); 134 | } 135 | 136 | if ('.tar' === fileEnding || '.tar.gz' === fileEnding) { 137 | await tc.extractTar(file, destinationFolder); 138 | } else if ('.zip' === fileEnding) { 139 | await tc.extractZip(file, destinationFolder); 140 | } else { 141 | // fall through and use sevenZip 142 | await tc.extract7z(file, destinationFolder); 143 | } 144 | } 145 | 146 | // This method recursively finds all .pack files under fsPath and unpacks them with the unpack200 tool 147 | async function unpackJars(fsPath: string, javaBinPath: string) { 148 | if (fs.existsSync(fsPath)) { 149 | if (fs.lstatSync(fsPath).isDirectory()) { 150 | for (const file in fs.readdirSync(fsPath)) { 151 | const curPath = path.join(fsPath, file); 152 | await unpackJars(curPath, javaBinPath); 153 | } 154 | } else if (path.extname(fsPath).toLowerCase() === '.pack') { 155 | // Unpack the pack file synchonously 156 | const p = path.parse(fsPath); 157 | const toolName = IS_WINDOWS ? 'unpack200.exe' : 'unpack200'; 158 | const args = IS_WINDOWS ? '-r -v -l ""' : ''; 159 | const name = path.join(p.dir, p.name); 160 | await exec.exec(`"${path.join(javaBinPath, toolName)}"`, [ 161 | `${args} "${name}.pack" "${name}.jar"` 162 | ]); 163 | } 164 | } 165 | } 166 | 167 | async function unzipJavaDownload( 168 | repoRoot: string, 169 | fileEnding: string, 170 | destinationFolder: string, 171 | extension?: string 172 | ): Promise { 173 | // Create the destination folder if it doesn't exist 174 | await io.mkdirP(destinationFolder); 175 | 176 | const jdkFile = path.normalize(repoRoot); 177 | const stats = fs.statSync(jdkFile); 178 | if (stats.isFile()) { 179 | await extractFiles(jdkFile, fileEnding, destinationFolder); 180 | const jdkDirectory = getJdkDirectory(destinationFolder); 181 | await unpackJars(jdkDirectory, path.join(jdkDirectory, 'bin')); 182 | return jdkDirectory; 183 | } else { 184 | throw new Error(`Jdk argument ${jdkFile} is not a file`); 185 | } 186 | } 187 | 188 | function getDownloadInfo( 189 | refs: string[], 190 | version: string, 191 | arch: string, 192 | javaPackage: string 193 | ): {version: string; url: string} { 194 | version = normalizeVersion(version); 195 | 196 | const archExtension = arch === 'x86' ? 'i686' : 'x64'; 197 | 198 | let extension = ''; 199 | if (IS_WINDOWS) { 200 | extension = `-win_${archExtension}.zip`; 201 | } else { 202 | if (process.platform === 'darwin') { 203 | extension = `-macosx_${archExtension}.tar.gz`; 204 | } else { 205 | extension = `-linux_${archExtension}.tar.gz`; 206 | } 207 | } 208 | 209 | core.debug(`Searching for files with extension: ${extension}`); 210 | 211 | let pkgRegexp = new RegExp(''); 212 | let pkgTypeLength = 0; 213 | if (javaPackage === 'jdk') { 214 | pkgRegexp = /jdk.*-/gi; 215 | pkgTypeLength = 'jdk'.length; 216 | } else if (javaPackage == 'jre') { 217 | pkgRegexp = /jre.*-/gi; 218 | pkgTypeLength = 'jre'.length; 219 | } else if (javaPackage == 'jdk+fx') { 220 | pkgRegexp = /fx-jdk.*-/gi; 221 | pkgTypeLength = 'fx-jdk'.length; 222 | } else { 223 | throw new Error( 224 | `package argument ${javaPackage} is not in [jdk | jre | jdk+fx]` 225 | ); 226 | } 227 | 228 | // Maps version to url 229 | let versionMap = new Map(); 230 | 231 | // Filter by platform 232 | refs.forEach(ref => { 233 | if (!ref.endsWith(extension + '">')) { 234 | return; 235 | } 236 | 237 | // If we haven't returned, means we're looking at the correct platform 238 | let versions = ref.match(pkgRegexp) || []; 239 | if (versions.length > 1) { 240 | throw new Error( 241 | `Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}` 242 | ); 243 | } 244 | if (versions.length == 0) { 245 | return; 246 | } 247 | const refVersion = versions[0].slice(pkgTypeLength, versions[0].length - 1); 248 | 249 | if (semver.satisfies(refVersion, version)) { 250 | versionMap.set( 251 | refVersion, 252 | 'https://static.azul.com/zulu/bin/' + 253 | ref.slice(''.length) 254 | ); 255 | } 256 | }); 257 | 258 | // Choose the most recent satisfying version 259 | let curVersion = '0.0.0'; 260 | let curUrl = ''; 261 | for (const entry of versionMap.entries()) { 262 | const entryVersion = entry[0]; 263 | const entryUrl = entry[1]; 264 | if (semver.gt(entryVersion, curVersion)) { 265 | curUrl = entryUrl; 266 | curVersion = entryVersion; 267 | } 268 | } 269 | 270 | if (curUrl == '') { 271 | throw new Error( 272 | `No valid download found for version ${version} and package ${javaPackage}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument` 273 | ); 274 | } 275 | 276 | return {version: curVersion, url: curUrl}; 277 | } 278 | 279 | function normalizeVersion(version: string): string { 280 | if (version.slice(0, 2) === '1.') { 281 | // Trim leading 1. for versions like 1.8 282 | version = version.slice(2); 283 | if (!version) { 284 | throw new Error('1. is not a valid version'); 285 | } 286 | } 287 | 288 | if (version.endsWith('-ea')) { 289 | // convert e.g. 14-ea to 14.0.0-ea 290 | if (version.indexOf('.') == -1) { 291 | version = version.slice(0, version.length - 3) + '.0.0-ea'; 292 | } 293 | // match anything in -ea.X (semver won't do .x matching on pre-release versions) 294 | if (version[0] >= '0' && version[0] <= '9') { 295 | version = '>=' + version; 296 | } 297 | } else if (version.split('.').length < 3) { 298 | // For non-ea versions, add trailing .x if it is missing 299 | if (version[version.length - 1] != 'x') { 300 | version = version + '.x'; 301 | } 302 | } 303 | 304 | return version; 305 | } 306 | 307 | function getOsString(platform: string): string { 308 | switch (platform) { 309 | case 'win32': 310 | return 'windows'; 311 | case 'darwin': 312 | return 'mac'; 313 | default: 314 | return 'linux'; 315 | } 316 | } 317 | 318 | function getCacheVersionSpec( 319 | release_type: string, 320 | version: string, 321 | image_type: string, 322 | jvm_impl: string, 323 | os: string, 324 | arch: string, 325 | heap_size: string, 326 | release: string 327 | ): string { 328 | return `1.0.0-${release_type}-${version}-${image_type}-${jvm_impl}-${os}-${arch}-${heap_size}-${release}`; 329 | } 330 | 331 | export async function getAdoptOpenJDK( 332 | release_type: string, 333 | version: string, 334 | image_type: string, 335 | jvm_impl: string, 336 | arch: string, 337 | heap_size: string, 338 | release: string, 339 | jdkFile: string 340 | ): Promise { 341 | return downloadJavaBinary( 342 | release_type, 343 | version, 344 | image_type, 345 | jvm_impl, 346 | os, 347 | arch, 348 | heap_size, 349 | release, 350 | jdkFile 351 | ); 352 | } 353 | 354 | function getAdoptOpenJdkUrl( 355 | release_type: string, 356 | version: string, 357 | image_type: string, 358 | jvm_impl: string, 359 | os: string, 360 | arch: string, 361 | heap_size: string, 362 | release: string 363 | ): string { 364 | const feature_version: string = version; 365 | const release_type_parsed: string = release_type; 366 | if (release == 'latest') { 367 | return `https://api.adoptopenjdk.net/v3/binary/latest/${feature_version}/${release_type_parsed}/${os}/${arch}/${image_type}/${jvm_impl}/${heap_size}/adoptopenjdk`; 368 | } else { 369 | const release_name = encodeURIComponent(release); 370 | return `https://api.adoptopenjdk.net/v3/binary/version/${release_name}/${os}/${arch}/${image_type}/${jvm_impl}/${heap_size}/adoptopenjdk`; 371 | } 372 | } 373 | 374 | function getJdkDirectory(destinationFolder: string): string { 375 | const jdkRoot: string = path.join( 376 | destinationFolder, 377 | fs.readdirSync(destinationFolder)[0] 378 | ); 379 | if (IS_MACOS) { 380 | const binDirectory: string = path.join(jdkRoot, 'bin'); 381 | if (fs.existsSync(binDirectory)) { 382 | return jdkRoot; 383 | } else { 384 | return path.join(jdkRoot, 'Contents', 'Home'); 385 | } 386 | } else { 387 | return jdkRoot; 388 | } 389 | } 390 | 391 | async function downloadJavaBinary( 392 | release_type: string, 393 | version: string, 394 | image_type: string, 395 | jvm_impl: string, 396 | os: string, 397 | arch: string, 398 | heap_size: string, 399 | release: string, 400 | jdkFile: string 401 | ): Promise { 402 | const normalizedArchitecture = architectureAliases.get(arch) || arch; 403 | const normalizedVersion = version.replace('openjdk', ''); 404 | const versionSpec = getCacheVersionSpec( 405 | release_type, 406 | normalizedVersion, 407 | image_type, 408 | jvm_impl, 409 | os, 410 | normalizedArchitecture, 411 | heap_size, 412 | release 413 | ); 414 | let toolPath = tc.find(toolName, versionSpec, normalizedArchitecture); 415 | 416 | if (toolPath) { 417 | core.debug(`Tool found in cache ${toolPath}`); 418 | } else { 419 | let compressedFileExtension = ''; 420 | if (!jdkFile) { 421 | core.debug('Downloading JDK from AdoptOpenJDK'); 422 | const url: string = getAdoptOpenJdkUrl( 423 | release_type, 424 | normalizedVersion, 425 | image_type, 426 | jvm_impl, 427 | os, 428 | normalizedArchitecture, 429 | heap_size, 430 | release 431 | ); 432 | core.debug(`AdoptOpenJDK URL: ${url}`); 433 | jdkFile = await tc.downloadTool(url); 434 | compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; 435 | } 436 | 437 | compressedFileExtension = compressedFileExtension || getFileEnding(jdkFile); 438 | let tempDir: string = path.join( 439 | tempDirectory, 440 | 'adoptopenjdk_' + Math.floor(Math.random() * 2000000000) 441 | ); 442 | const jdkDir = await unzipJavaDownload( 443 | jdkFile, 444 | compressedFileExtension, 445 | tempDir 446 | ); 447 | core.debug(`JDK extracted to ${jdkDir}`); 448 | toolPath = await tc.cacheDir( 449 | jdkDir, 450 | toolName, 451 | versionSpec, 452 | normalizedArchitecture 453 | ); 454 | } 455 | 456 | let extendedJavaHome = `JAVA_HOME_${normalizedVersion}_${normalizedArchitecture}`; 457 | core.exportVariable(extendedJavaHome, toolPath); //TODO: remove for v2 458 | // For portability reasons environment variables should only consist of 459 | // uppercase letters, digits, and the underscore. Therefore we convert 460 | // the extendedJavaHome variable to upper case and replace '.' symbols and 461 | // any other non-alphanumeric characters with an underscore. 462 | extendedJavaHome = extendedJavaHome.toUpperCase().replace(/[^0-9A-Z_]/g, '_'); 463 | core.exportVariable('JAVA_HOME', toolPath); 464 | core.exportVariable(extendedJavaHome, toolPath); 465 | core.addPath(path.join(toolPath, 'bin')); 466 | core.setOutput('path', toolPath); 467 | core.setOutput('version', normalizedVersion); 468 | } 469 | -------------------------------------------------------------------------------- /src/setup-java.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import * as installer from './installer'; 3 | import * as auth from './auth'; 4 | import * as gpg from './gpg'; 5 | import * as constants from './constants'; 6 | import * as path from 'path'; 7 | 8 | async function run() { 9 | try { 10 | let version = core.getInput(constants.INPUT_VERSION); 11 | if (!version) { 12 | version = core.getInput(constants.INPUT_JAVA_VERSION, {required: true}); 13 | } 14 | 15 | const arch = core.getInput(constants.INPUT_ARCHITECTURE, {required: true}); 16 | if (!['x86', 'x64'].includes(arch)) { 17 | throw new Error(`architecture "${arch}" is not in [x86 | x64]`); 18 | } 19 | 20 | const javaPackage = core.getInput(constants.INPUT_JAVA_PACKAGE, { 21 | required: true 22 | }); 23 | const jdkFile = core.getInput(constants.INPUT_JDK_FILE, {required: false}); 24 | 25 | await installer.getJava(version, arch, jdkFile, javaPackage); 26 | 27 | const matchersPath = path.join(__dirname, '..', '..', '.github'); 28 | core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); 29 | 30 | const id = core.getInput(constants.INPUT_SERVER_ID, {required: false}); 31 | const username = core.getInput(constants.INPUT_SERVER_USERNAME, { 32 | required: false 33 | }); 34 | const password = core.getInput(constants.INPUT_SERVER_PASSWORD, { 35 | required: false 36 | }); 37 | const overwriteSettings = 38 | core.getInput(constants.INPUT_OVERWRITE_SETTINGS, {required: false}) || 39 | 'true'; 40 | const gpgPrivateKey = 41 | core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) || 42 | constants.INPUT_DEFAULT_GPG_PRIVATE_KEY; 43 | const gpgPassphrase = 44 | core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) || 45 | (gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined); 46 | 47 | if (gpgPrivateKey) { 48 | core.setSecret(gpgPrivateKey); 49 | } 50 | 51 | await auth.configAuthentication( 52 | id, 53 | username, 54 | password, 55 | overwriteSettings === 'true', 56 | gpgPassphrase 57 | ); 58 | 59 | if (gpgPrivateKey) { 60 | core.info('importing private key'); 61 | const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || ''; 62 | core.saveState( 63 | constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT, 64 | keyFingerprint 65 | ); 66 | } 67 | } catch (error) { 68 | core.setFailed(error.message); 69 | } 70 | } 71 | 72 | run(); 73 | -------------------------------------------------------------------------------- /src/setup-jdk.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import * as installer from './installer'; 3 | import * as auth from './auth'; 4 | import * as gpg from './gpg'; 5 | import * as constants from './constants'; 6 | import * as path from 'path'; 7 | 8 | async function run() { 9 | core.notice( 10 | 'The joschi/setup-jdk GitHub Action is deprecated. Please consider switching to the official actions/setup-java action v2 or later which also supports AdoptOpenJDK and its successor Eclipse Temurin: https://github.com/actions/setup-java/tree/v2.5.0#basic' 11 | ); 12 | 13 | try { 14 | // Type of release. Either a release version, known as General Availability ("ga") or an Early Access ("ea") 15 | const release_type = core.getInput(constants.INPUT_RELEASE_TYPE) || 'ga'; 16 | // OpenJDK feature release version, example: "8", "11", "13". 17 | const javaVersion = core.getInput(constants.INPUT_JAVA_VERSION, { 18 | required: true 19 | }); 20 | // OpenJDK implementation, example: "hotspot", "openj9". 21 | const openjdk_impl = 22 | core.getInput(constants.INPUT_OPENJDK_IMPL) || 'hotspot'; 23 | // Architecture of the JDK, example: "x64", "x32", "arm", "ppc64", "s390x", "ppc64le", "aarch64", "sparcv9". 24 | const arch = 25 | core.getInput(constants.INPUT_ARCHITECTURE, {required: true}) || 'x64'; 26 | // Heap size for OpenJ9, example: "normal", "large" (for heaps >=57 GiB). 27 | const heap_size = 28 | core.getInput(constants.INPUT_HEAP_SIZE, {required: false}) || 'normal'; 29 | // Exact release of OpenJDK, example: "latest", "jdk-11.0.4+11.4", "jdk8u172-b00-201807161800". 30 | const release = 31 | core.getInput(constants.INPUT_RELEASE, {required: false}) || 'latest'; 32 | // The image type (jre, jdk) 33 | const javaPackage = 34 | core.getInput(constants.INPUT_JAVA_PACKAGE, { 35 | required: true 36 | }) || 'jdk'; 37 | const jdkFile = core.getInput(constants.INPUT_JDK_FILE, {required: false}); 38 | 39 | await installer.getAdoptOpenJDK( 40 | release_type, 41 | javaVersion, 42 | javaPackage, 43 | openjdk_impl, 44 | arch, 45 | heap_size, 46 | release, 47 | jdkFile 48 | ); 49 | 50 | const matchersPath = path.join(__dirname, '..', '..', '.github'); 51 | console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); 52 | 53 | const id = core.getInput(constants.INPUT_SERVER_ID, {required: false}); 54 | const username = core.getInput(constants.INPUT_SERVER_USERNAME, { 55 | required: false 56 | }); 57 | const password = core.getInput(constants.INPUT_SERVER_PASSWORD, { 58 | required: false 59 | }); 60 | const overwriteSettings = 61 | core.getInput(constants.INPUT_OVERWRITE_SETTINGS, {required: false}) || 62 | 'true'; 63 | const gpgPrivateKey = 64 | core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) || 65 | constants.INPUT_DEFAULT_GPG_PRIVATE_KEY; 66 | const gpgPassphrase = 67 | core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) || 68 | (gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined); 69 | 70 | if (gpgPrivateKey) { 71 | core.setSecret(gpgPrivateKey); 72 | } 73 | 74 | await auth.configAuthentication( 75 | id, 76 | username, 77 | password, 78 | overwriteSettings === 'true', 79 | gpgPassphrase 80 | ); 81 | 82 | if (gpgPrivateKey) { 83 | core.info('importing private key'); 84 | const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || ''; 85 | core.saveState( 86 | constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT, 87 | keyFingerprint 88 | ); 89 | } 90 | } catch (error) { 91 | core.setFailed(error.message); 92 | } 93 | } 94 | 95 | run(); 96 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | export function getTempDir() { 4 | let tempDirectory = process.env.RUNNER_TEMP; 5 | if (tempDirectory === undefined) { 6 | let baseLocation; 7 | if (isWindows()) { 8 | // On windows use the USERPROFILE env variable 9 | baseLocation = process.env['USERPROFILE'] 10 | ? process.env['USERPROFILE'] 11 | : 'C:\\'; 12 | } else { 13 | if (process.platform === 'darwin') { 14 | baseLocation = '/Users'; 15 | } else { 16 | baseLocation = '/home'; 17 | } 18 | } 19 | tempDirectory = path.join(baseLocation, 'actions', 'temp'); 20 | } 21 | return tempDirectory; 22 | } 23 | 24 | export function isWindows() { 25 | return process.platform === 'win32'; 26 | } 27 | 28 | export function isDarwin() { 29 | return process.platform === 'darwin'; 30 | } 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | // "incremental": true, /* Enable incremental compilation */ 5 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 6 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 7 | // "allowJs": true, /* Allow javascript files to be compiled. */ 8 | // "checkJs": true, /* Report errors in .js files. */ 9 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 10 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 12 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | "outDir": "./lib", /* Redirect output structure to the directory. */ 15 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | // "composite": true, /* Enable project compilation */ 17 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 18 | // "removeComments": true, /* Do not emit comments to output. */ 19 | // "noEmit": true, /* Do not emit outputs. */ 20 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 21 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 22 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 23 | 24 | /* Strict Type-Checking Options */ 25 | "strict": true, /* Enable all strict type-checking options. */ 26 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 27 | // "strictNullChecks": true, /* Enable strict null checks. */ 28 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 29 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 30 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 31 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 32 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 33 | 34 | /* Additional Checks */ 35 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 36 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 37 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 38 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 39 | 40 | /* Module Resolution Options */ 41 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 42 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 43 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 44 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 45 | // "typeRoots": [], /* List of folders to include type definitions from. */ 46 | // "types": [], /* Type declaration files to be included in compilation. */ 47 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 48 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 49 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 50 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 51 | 52 | /* Source Map Options */ 53 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 54 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 55 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 56 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 57 | 58 | /* Experimental Options */ 59 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 60 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 61 | }, 62 | "exclude": ["node_modules", "**/*.test.ts"] 63 | } 64 | -------------------------------------------------------------------------------- /yaml-lint-config.yml: -------------------------------------------------------------------------------- 1 | extends: default 2 | 3 | rules: 4 | # 80 chars should be enough, but don't fail if a line is longer 5 | line-length: 6 | max: 80 7 | level: warning 8 | --------------------------------------------------------------------------------