Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
b6e674f4b7 | |||
d202f5dbf7 | |||
11790a2d66 | |||
8bb50d97d6 | |||
fe06bcdc44 | |||
d34a7e45c8 | |||
3019d15cad | |||
1253a7eed4 | |||
1277492cb9 | |||
38e0c8bd18 | |||
77d6565ede | |||
ac9630fb91 | |||
36bb906fe0 | |||
012c21ec81 | |||
4d8dc69fc8 | |||
2d0e474aa9 | |||
034b7a7488 | |||
91d166793d | |||
7f2382879a | |||
01f44229d4 | |||
d920b7da5f | |||
88965601fb | |||
655cb05195 | |||
81bfa641b0 | |||
6e1616c588 | |||
457d7a4579 | |||
e494666ae9 | |||
d94db22179 | |||
4003c04fbc | |||
9c7b108c73 | |||
505c9972aa | |||
5c87b70ffe | |||
ea8ea84c9e | |||
6dc4d4a3ed | |||
5ef3a8d61b | |||
60cf21b5e7 | |||
f63b906f27 | |||
9c4f82dc57 | |||
623089a937 | |||
ec103c0d1a | |||
90c448a85d | |||
63d68602dd | |||
351c3fb96f | |||
f6b96adea7 | |||
c74a6f8415 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1,2 +1,3 @@
|
|||||||
dist/index.js -diff -merge
|
dist/index.js -diff -merge
|
||||||
dist/index.js linguist-generated=true
|
dist/index.js linguist-generated=true
|
||||||
|
.licenses/** -diff linguist-generated=true
|
||||||
|
20
.github/workflows/licensed.yml
vendored
Normal file
20
.github/workflows/licensed.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
name: Licensed
|
||||||
|
|
||||||
|
on:
|
||||||
|
push: {branches: main}
|
||||||
|
pull_request: {branches: main}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Check licenses
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: npm ci
|
||||||
|
- name: Install licensed
|
||||||
|
run: |
|
||||||
|
cd $RUNNER_TEMP
|
||||||
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
||||||
|
sudo tar -xzf licensed.tar.gz
|
||||||
|
sudo mv licensed /usr/local/bin/licensed
|
||||||
|
- run: licensed status
|
12
.github/workflows/lint-yaml.yml
vendored
12
.github/workflows/lint-yaml.yml
vendored
@ -1,12 +0,0 @@
|
|||||||
name: Lint YAML
|
|
||||||
on: [pull_request]
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@master
|
|
||||||
- name: Lint action.yml
|
|
||||||
uses: ibiqlik/action-yamllint@master
|
|
||||||
with:
|
|
||||||
file_or_dir: action.yml
|
|
||||||
config_file: yaml-lint-config.yml
|
|
82
.github/workflows/workflow.yml
vendored
82
.github/workflows/workflow.yml
vendored
@ -1,26 +1,88 @@
|
|||||||
name: Main workflow
|
name: Main workflow
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
run:
|
build:
|
||||||
name: Run
|
|
||||||
runs-on: ${{ matrix.operating-system }}
|
runs-on: ${{ matrix.operating-system }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest]
|
operating-system: [ubuntu-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Node.js 12
|
||||||
- name: Set Node.js 10.x
|
uses: actions/setup-node@v1
|
||||||
uses: actions/setup-node@master
|
|
||||||
with:
|
with:
|
||||||
node-version: 10.x
|
node-version: 12.x
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: npm run format-check
|
run: npm run format-check
|
||||||
|
|
||||||
- name: npm test
|
- name: npm test
|
||||||
run: npm test
|
run: npm test
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Clear tool cache
|
||||||
|
if: runner.os != 'windows'
|
||||||
|
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
|
||||||
|
- name: Clear tool cache (Windows)
|
||||||
|
if: runner.os == 'windows'
|
||||||
|
run: move "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
|
||||||
|
- name: Setup Java 13
|
||||||
|
id: setup-java
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
java-version: 13.0.2
|
||||||
|
- name: Verify Java 13
|
||||||
|
if: runner.os != 'windows'
|
||||||
|
run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
|
||||||
|
- name: Verify Java 13 (Windows)
|
||||||
|
if: runner.os == 'windows'
|
||||||
|
run: __tests__/verify-java.ps1 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
|
||||||
|
|
||||||
|
test-proxy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ubuntu:latest
|
||||||
|
options: --dns 127.0.0.1
|
||||||
|
services:
|
||||||
|
squid-proxy:
|
||||||
|
image: ubuntu/squid:latest
|
||||||
|
ports:
|
||||||
|
- 3128:3128
|
||||||
|
env:
|
||||||
|
https_proxy: http://squid-proxy:3128
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Clear tool cache
|
||||||
|
run: rm -rf $RUNNER_TOOL_CACHE/*
|
||||||
|
- name: Setup Java 13
|
||||||
|
id: setup-java
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
java-version: 13.0.2
|
||||||
|
- name: Verify Java 13
|
||||||
|
run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
|
||||||
|
|
||||||
|
test-bypass-proxy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
https_proxy: http://no-such-proxy:3128
|
||||||
|
no_proxy: github.com,static.azul.com
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Clear tool cache
|
||||||
|
run: rm -rf $RUNNER_TOOL_CACHE/*
|
||||||
|
- name: Setup Java 13
|
||||||
|
id: setup-java
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
java-version: 13.0.2
|
||||||
|
- name: Verify Java 13
|
||||||
|
run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
|
||||||
|
14
.licensed.yml
Normal file
14
.licensed.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
sources:
|
||||||
|
npm: true
|
||||||
|
|
||||||
|
allowed:
|
||||||
|
- apache-2.0
|
||||||
|
- bsd-2-clause
|
||||||
|
- bsd-3-clause
|
||||||
|
- isc
|
||||||
|
- mit
|
||||||
|
- cc0-1.0
|
||||||
|
- unlicense
|
||||||
|
|
||||||
|
reviewed:
|
||||||
|
npm:
|
BIN
.licenses/npm/@actions/core.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/core.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-2.1.0.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-2.1.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/tool-cache.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/tool-cache.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/dom.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/dom.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/infra-1.0.3.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/infra-1.0.3.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/infra-1.0.5.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/infra-1.0.5.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/url.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/url.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/util-1.0.1.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/util-1.0.1.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/util-1.0.2.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/util-1.0.2.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/util-8.0.0.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/util-8.0.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@oozcitak/util-8.3.3.dep.yml
generated
Normal file
BIN
.licenses/npm/@oozcitak/util-8.3.3.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver.dep.yml
generated
Normal file
BIN
.licenses/npm/semver.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/uuid-3.4.0.dep.yml
generated
Normal file
BIN
.licenses/npm/uuid-3.4.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/uuid-8.3.2.dep.yml
generated
Normal file
BIN
.licenses/npm/uuid-8.3.2.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/xmlbuilder2.dep.yml
generated
Normal file
BIN
.licenses/npm/xmlbuilder2.dep.yml
generated
Normal file
Binary file not shown.
38
CONTRIBUTING.md
Normal file
38
CONTRIBUTING.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Contributors
|
||||||
|
|
||||||
|
### Checkin
|
||||||
|
|
||||||
|
- Do checkin source (src)
|
||||||
|
- Do checkin a single index.js file after running `ncc`
|
||||||
|
- Do not checking node_modules
|
||||||
|
|
||||||
|
### NCC
|
||||||
|
|
||||||
|
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/`.
|
||||||
|
There are two main files that get created
|
||||||
|
- `dist/setup/index.js`
|
||||||
|
- Core `setup-java` logic that downloads and installs an appropriate version of Java
|
||||||
|
- Handling creating a `settings.xml` file to make it easier to publish packages
|
||||||
|
- `dist/cleanup/index/js`
|
||||||
|
- Extra cleanup script that is used to remove GPG keys (needed for certain self-hosted runner scenarios)
|
||||||
|
|
||||||
|
If you're developing locally, after doing `npm install`, you can use the following commands
|
||||||
|
```yaml
|
||||||
|
npm run build # runs tsc along with ncc
|
||||||
|
npm run format # runs prettier --write
|
||||||
|
npm run format-check # runs prettier --check
|
||||||
|
npm run test # runs jest
|
||||||
|
npm run release # add all the necessary ncc files under dist/* to the git staging area
|
||||||
|
```
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
Tests are included under `_tests_/*` and can be run using `npm run-script test`.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### Licensed
|
||||||
|
|
||||||
|
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.
|
77
README.md
77
README.md
@ -16,19 +16,47 @@ See [action.yml](action.yml)
|
|||||||
## Basic
|
## Basic
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: '9.0.4' # The JDK version to make available on the path. Takes a whole or semver JDK version, or 1.x syntax (e.g. 1.8 => Jdk 8.x). To specify a specific version for JDK 8 or older use the following pattern (8.0.x)
|
java-version: '9.0.4' # The JDK version to make available on the path.
|
||||||
java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk
|
java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk
|
||||||
architecture: x64 # (x64 or x86) - defaults to x64
|
architecture: x64 # (x64 or x86) - defaults to x64
|
||||||
- run: java -cp java HelloWorldApp
|
- run: java -cp java HelloWorldApp
|
||||||
```
|
```
|
||||||
|
Examples of version specifications that the java-version parameter will accept:
|
||||||
|
|
||||||
|
- A major Java version
|
||||||
|
|
||||||
|
e.g. ```6, 7, 8, 9, 10, 11, 12, 13, ...```
|
||||||
|
|
||||||
|
- A semver Java version specification
|
||||||
|
|
||||||
|
e.g. ```8.0.232, 7.0.181, 11.0.4```
|
||||||
|
|
||||||
|
e.g. ```8.0.x, >11.0.3, >=13.0.1, <8.0.212```
|
||||||
|
|
||||||
|
- An early access (EA) Java version
|
||||||
|
|
||||||
|
e.g. ```14-ea, 15-ea```
|
||||||
|
|
||||||
|
e.g. ```14.0.0-ea, 15.0.0-ea```
|
||||||
|
|
||||||
|
e.g. ```14.0.0-ea.28, 15.0.0-ea.2``` (syntax for specifying an EA build number)
|
||||||
|
|
||||||
|
Note that, per semver rules, EA builds will be matched by explicit EA version specifications.
|
||||||
|
|
||||||
|
- 1.x syntax
|
||||||
|
|
||||||
|
e.g. ```1.8``` (same as ```8```)
|
||||||
|
|
||||||
|
e.g. ```1.8.0.212``` (same as ```8.0.212```)
|
||||||
|
|
||||||
|
|
||||||
## Local file
|
## Local file
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: '4.0.0'
|
java-version: '4.0.0'
|
||||||
@ -48,7 +76,7 @@ jobs:
|
|||||||
java: [ 1.6, 6.0.83, 7, 7.0.181, 8, 8.0.192, 9.0.x, 10, 11.0.x, 11.0.3, 12, 13 ]
|
java: [ 1.6, 6.0.83, 7, 7.0.181, 8, 8.0.192, 9.0.x, 10, 11.0.x, 11.0.3, 12, 13 ]
|
||||||
name: Java ${{ matrix.java }} sample
|
name: Java ${{ matrix.java }} sample
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v2
|
||||||
- name: Setup java
|
- name: Setup java
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
@ -64,7 +92,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- name: Set up JDK 1.8
|
- name: Set up JDK 1.8
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
@ -85,39 +113,60 @@ jobs:
|
|||||||
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
|
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
|
||||||
server-username: MAVEN_USERNAME # env variable for username in deploy
|
server-username: MAVEN_USERNAME # env variable for username in deploy
|
||||||
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
|
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
|
||||||
|
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
|
||||||
|
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
|
||||||
|
|
||||||
- name: Publish to Apache Maven Central
|
- name: Publish to Apache Maven Central
|
||||||
run: mvn deploy
|
run: mvn deploy
|
||||||
env:
|
env:
|
||||||
MAVEN_USERNAME: maven_username123
|
MAVEN_USERNAME: maven_username123
|
||||||
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
|
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
|
||||||
|
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
|
||||||
```
|
```
|
||||||
|
|
||||||
The two `settings.xml` files created from the above example look like the following.
|
The two `settings.xml` files created from the above example look like the following.
|
||||||
|
|
||||||
`settings.xml` file created for the first deploy to GitHub Packages
|
`settings.xml` file created for the first deploy to GitHub Packages
|
||||||
```xml
|
```xml
|
||||||
<servers>
|
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||||
|
<servers>
|
||||||
<server>
|
<server>
|
||||||
<id>github</id>
|
<id>github</id>
|
||||||
<username>${env.GITHUB_ACTOR}</username>
|
<username>${env.GITHUB_ACTOR}</username>
|
||||||
<password>${env.GITHUB_TOKEN}</password>
|
<password>${env.GITHUB_TOKEN}</password>
|
||||||
</server>
|
</server>
|
||||||
</servers>
|
<server>
|
||||||
|
<id>gpg.passphrase</id>
|
||||||
|
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
|
||||||
|
</server>
|
||||||
|
</servers>
|
||||||
|
</settings>
|
||||||
```
|
```
|
||||||
|
|
||||||
`settings.xml` file created for the second deploy to Apache Maven Central
|
`settings.xml` file created for the second deploy to Apache Maven Central
|
||||||
```xml
|
```xml
|
||||||
<servers>
|
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||||
|
<servers>
|
||||||
<server>
|
<server>
|
||||||
<id>maven</id>
|
<id>maven</id>
|
||||||
<username>${env.MAVEN_USERNAME}</username>
|
<username>${env.MAVEN_USERNAME}</username>
|
||||||
<password>${env.MAVEN_CENTRAL_TOKEN}</password>
|
<password>${env.MAVEN_CENTRAL_TOKEN}</password>
|
||||||
</server>
|
</server>
|
||||||
</servers>
|
<server>
|
||||||
|
<id>gpg.passphrase</id>
|
||||||
|
<passphrase>${env.MAVEN_GPG_PASSPHRASE}</passphrase>
|
||||||
|
</server>
|
||||||
|
</servers>
|
||||||
|
</settings>
|
||||||
```
|
```
|
||||||
|
|
||||||
***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.***
|
***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.***
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@ -129,7 +178,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Set up JDK 1.8
|
- name: Set up JDK 1.8
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
@ -144,7 +193,7 @@ jobs:
|
|||||||
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.***
|
***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.***
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@ -159,7 +208,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- name: Set up JDK 1.8 for Shared Runner
|
- name: Set up JDK 1.8 for Shared Runner
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
|
@ -53,7 +53,7 @@ describe('auth tests', () => {
|
|||||||
await io.rmRF(altHome);
|
await io.rmRF(altHome);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
it('creates settings.xml with username and password', async () => {
|
it('creates settings.xml with minimal configuration', async () => {
|
||||||
const id = 'packages';
|
const id = 'packages';
|
||||||
const username = 'UNAME';
|
const username = 'UNAME';
|
||||||
const password = 'TOKEN';
|
const password = 'TOKEN';
|
||||||
@ -67,6 +67,21 @@ describe('auth tests', () => {
|
|||||||
);
|
);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
|
it('creates settings.xml with additional configuration', async () => {
|
||||||
|
const id = 'packages';
|
||||||
|
const username = 'UNAME';
|
||||||
|
const password = 'TOKEN';
|
||||||
|
const gpgPassphrase = 'GPG';
|
||||||
|
|
||||||
|
await auth.configAuthentication(id, username, password, gpgPassphrase);
|
||||||
|
|
||||||
|
expect(fs.existsSync(m2Dir)).toBe(true);
|
||||||
|
expect(fs.existsSync(settingsFile)).toBe(true);
|
||||||
|
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
||||||
|
auth.generate(id, username, password, gpgPassphrase)
|
||||||
|
);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
it('overwrites existing settings.xml files', async () => {
|
it('overwrites existing settings.xml files', async () => {
|
||||||
const id = 'packages';
|
const id = 'packages';
|
||||||
const username = 'USERNAME';
|
const username = 'USERNAME';
|
||||||
@ -86,59 +101,50 @@ describe('auth tests', () => {
|
|||||||
);
|
);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
it('does not create settings.xml without required parameters', async () => {
|
it('generates valid settings.xml with minimal configuration', () => {
|
||||||
await auth.configAuthentication('FOO');
|
|
||||||
|
|
||||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
|
||||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
|
||||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
|
||||||
auth.generate('FOO', auth.DEFAULT_USERNAME, auth.DEFAULT_PASSWORD)
|
|
||||||
);
|
|
||||||
|
|
||||||
await auth.configAuthentication(undefined, 'BAR', undefined);
|
|
||||||
|
|
||||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
|
||||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
|
||||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
|
||||||
auth.generate(auth.DEFAULT_ID, 'BAR', auth.DEFAULT_PASSWORD)
|
|
||||||
);
|
|
||||||
|
|
||||||
await auth.configAuthentication(undefined, undefined, 'BAZ');
|
|
||||||
|
|
||||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
|
||||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
|
||||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
|
||||||
auth.generate(auth.DEFAULT_ID, auth.DEFAULT_USERNAME, 'BAZ')
|
|
||||||
);
|
|
||||||
|
|
||||||
await auth.configAuthentication();
|
|
||||||
|
|
||||||
expect(fs.existsSync(m2Dir)).toBe(true);
|
|
||||||
expect(fs.existsSync(settingsFile)).toBe(true);
|
|
||||||
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
|
|
||||||
auth.generate(
|
|
||||||
auth.DEFAULT_ID,
|
|
||||||
auth.DEFAULT_USERNAME,
|
|
||||||
auth.DEFAULT_PASSWORD
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
it('escapes invalid XML inputs', () => {
|
|
||||||
const id = 'packages';
|
const id = 'packages';
|
||||||
const username = 'USER';
|
const username = 'USER';
|
||||||
const password = '&<>"\'\'"><&';
|
const password = '&<>"\'\'"><&';
|
||||||
|
|
||||||
expect(auth.generate(id, username, password)).toEqual(`
|
const expectedSettings = `<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||||
<settings>
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<servers>
|
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||||
<server>
|
<servers>
|
||||||
<id>${id}</id>
|
<server>
|
||||||
<username>\${env.${username}}</username>
|
<id>${id}</id>
|
||||||
<password>\${env.&<>"''"><&}</password>
|
<username>\${env.${username}}</username>
|
||||||
</server>
|
<password>\${env.&<>"''"><&}</password>
|
||||||
</servers>
|
</server>
|
||||||
</settings>
|
</servers>
|
||||||
`);
|
</settings>`;
|
||||||
|
|
||||||
|
expect(auth.generate(id, username, password)).toEqual(expectedSettings);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generates valid settings.xml with additional configuration', () => {
|
||||||
|
const id = 'packages';
|
||||||
|
const username = 'USER';
|
||||||
|
const password = '&<>"\'\'"><&';
|
||||||
|
const gpgPassphrase = 'PASSPHRASE';
|
||||||
|
|
||||||
|
const expectedSettings = `<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||||
|
<servers>
|
||||||
|
<server>
|
||||||
|
<id>${id}</id>
|
||||||
|
<username>\${env.${username}}</username>
|
||||||
|
<password>\${env.&<>"''"><&}</password>
|
||||||
|
</server>
|
||||||
|
<server>
|
||||||
|
<id>gpg.passphrase</id>
|
||||||
|
<passphrase>\${env.${gpgPassphrase}}</passphrase>
|
||||||
|
</server>
|
||||||
|
</servers>
|
||||||
|
</settings>`;
|
||||||
|
|
||||||
|
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
|
||||||
|
expectedSettings
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
56
__tests__/gpg.test.ts
Normal file
56
__tests__/gpg.test.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import path = require('path');
|
||||||
|
import io = require('@actions/io');
|
||||||
|
import exec = require('@actions/exec');
|
||||||
|
|
||||||
|
jest.mock('@actions/exec', () => {
|
||||||
|
return {
|
||||||
|
exec: jest.fn()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||||
|
process.env['RUNNER_TEMP'] = tempDir;
|
||||||
|
|
||||||
|
import gpg = require('../src/gpg');
|
||||||
|
|
||||||
|
describe('gpg tests', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await io.mkdirP(tempDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
try {
|
||||||
|
await io.rmRF(tempDir);
|
||||||
|
} catch {
|
||||||
|
console.log('Failed to remove test directories');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('importKey', () => {
|
||||||
|
it('attempts to import private key and returns null key id on failure', async () => {
|
||||||
|
const privateKey = 'KEY CONTENTS';
|
||||||
|
const keyId = await gpg.importKey(privateKey);
|
||||||
|
|
||||||
|
expect(keyId).toBeNull();
|
||||||
|
|
||||||
|
expect(exec.exec).toHaveBeenCalledWith(
|
||||||
|
'gpg',
|
||||||
|
expect.anything(),
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('deleteKey', () => {
|
||||||
|
it('deletes private key', async () => {
|
||||||
|
const keyId = 'asdfhjkl';
|
||||||
|
await gpg.deleteKey(keyId);
|
||||||
|
|
||||||
|
expect(exec.exec).toHaveBeenCalledWith(
|
||||||
|
'gpg',
|
||||||
|
expect.anything(),
|
||||||
|
expect.anything()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
61
__tests__/util.test.ts
Normal file
61
__tests__/util.test.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import path = require('path');
|
||||||
|
|
||||||
|
const env = process.env;
|
||||||
|
|
||||||
|
describe('util tests', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const tempEnv = Object.assign({}, env);
|
||||||
|
delete tempEnv.RUNNER_TEMP;
|
||||||
|
delete tempEnv.USERPROFILE;
|
||||||
|
process.env = tempEnv;
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'linux'});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTempDir', () => {
|
||||||
|
it('gets temp dir using env', () => {
|
||||||
|
process.env['RUNNER_TEMP'] = 'defaulttmp';
|
||||||
|
const util = require('../src/util');
|
||||||
|
|
||||||
|
const tempDir = util.getTempDir();
|
||||||
|
|
||||||
|
expect(tempDir).toEqual(process.env['RUNNER_TEMP']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets temp dir for windows using userprofile', () => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'win32'});
|
||||||
|
process.env['USERPROFILE'] = 'winusertmp';
|
||||||
|
const util = require('../src/util');
|
||||||
|
|
||||||
|
const tempDir = util.getTempDir();
|
||||||
|
|
||||||
|
expect(tempDir).toEqual(
|
||||||
|
path.join(process.env['USERPROFILE'], 'actions', 'temp')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets temp dir for windows using c drive', () => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'win32'});
|
||||||
|
const util = require('../src/util');
|
||||||
|
|
||||||
|
const tempDir = util.getTempDir();
|
||||||
|
|
||||||
|
expect(tempDir).toEqual(path.join('C:\\', 'actions', 'temp'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets temp dir for mac', () => {
|
||||||
|
Object.defineProperty(process, 'platform', {value: 'darwin'});
|
||||||
|
const util = require('../src/util');
|
||||||
|
|
||||||
|
const tempDir = util.getTempDir();
|
||||||
|
|
||||||
|
expect(tempDir).toEqual(path.join('/Users', 'actions', 'temp'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets temp dir for linux', () => {
|
||||||
|
const util = require('../src/util');
|
||||||
|
const tempDir = util.getTempDir();
|
||||||
|
|
||||||
|
expect(tempDir).toEqual(path.join('/home', 'actions', 'temp'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
31
__tests__/verify-java.ps1
Normal file
31
__tests__/verify-java.ps1
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
if (!$args.Count -or !$args[0])
|
||||||
|
{
|
||||||
|
throw "Must supply java version argument"
|
||||||
|
}
|
||||||
|
|
||||||
|
$java_version = & cmd.exe /c "java -version 2>&1" | Out-String
|
||||||
|
Write-Host "Found java version: $java_version"
|
||||||
|
if (!$java_version.Contains($args[0]))
|
||||||
|
{
|
||||||
|
throw "Unexpected version"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($args.Count -lt 2 -or !$args[1])
|
||||||
|
{
|
||||||
|
throw "Must supply java path argument"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($args[1] -ne $Env:JAVA_HOME)
|
||||||
|
{
|
||||||
|
throw "Unexpected path"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($args.Count -lt 3 -or !$args[2])
|
||||||
|
{
|
||||||
|
throw "Must supply java version argument"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($args[0] -ne $args[2])
|
||||||
|
{
|
||||||
|
throw "Unexpected version"
|
||||||
|
}
|
33
__tests__/verify-java.sh
Executable file
33
__tests__/verify-java.sh
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "::error::Must supply java version argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
java_version="$(java -version 2>&1)"
|
||||||
|
echo "Found java version: $java_version"
|
||||||
|
if [ -z "$(echo $java_version | grep --fixed-strings $1)" ]; then
|
||||||
|
echo "::error::Unexpected version"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "::error::Must supply java path argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" != "$JAVA_HOME" ]; then
|
||||||
|
echo "::error::Unexpected path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$3" ]; then
|
||||||
|
echo "::error::Must supply java version argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" != "$3" ]; then
|
||||||
|
echo "::error::Unexpected version"
|
||||||
|
exit 1
|
||||||
|
fi
|
22
action.yml
22
action.yml
@ -5,7 +5,9 @@ author: 'GitHub'
|
|||||||
inputs:
|
inputs:
|
||||||
java-version:
|
java-version:
|
||||||
description: 'The Java version to make available on the path. Takes a whole
|
description: 'The Java version to make available on the path. Takes a whole
|
||||||
or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)'
|
or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x).
|
||||||
|
Early access versions can be specified in the form of e.g. 14-ea,
|
||||||
|
14.0.0-ea, or 14.0.0-ea.28'
|
||||||
required: true
|
required: true
|
||||||
java-package:
|
java-package:
|
||||||
description: 'The package type (jre, jdk, jdk+fx)'
|
description: 'The package type (jre, jdk, jdk+fx)'
|
||||||
@ -23,17 +25,33 @@ inputs:
|
|||||||
description: 'ID of the distributionManagement repository in the pom.xml
|
description: 'ID of the distributionManagement repository in the pom.xml
|
||||||
file. Default is `github`'
|
file. Default is `github`'
|
||||||
required: false
|
required: false
|
||||||
|
default: 'github'
|
||||||
server-username:
|
server-username:
|
||||||
description: 'Environment variable name for the username for authentication
|
description: 'Environment variable name for the username for authentication
|
||||||
to the Apache Maven repository. Default is $GITHUB_ACTOR'
|
to the Apache Maven repository. Default is $GITHUB_ACTOR'
|
||||||
required: false
|
required: false
|
||||||
|
default: 'GITHUB_ACTOR'
|
||||||
server-password:
|
server-password:
|
||||||
description: 'Environment variable name for password or token for
|
description: 'Environment variable name for password or token for
|
||||||
authentication to the Apache Maven repository. Default is $GITHUB_TOKEN'
|
authentication to the Apache Maven repository. Default is $GITHUB_TOKEN'
|
||||||
required: false
|
required: false
|
||||||
|
default: 'GITHUB_TOKEN'
|
||||||
settings-path:
|
settings-path:
|
||||||
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
|
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
|
||||||
required: false
|
required: false
|
||||||
|
gpg-private-key:
|
||||||
|
description: 'GPG private key to import. Default is empty string.'
|
||||||
|
required: false
|
||||||
|
gpg-passphrase:
|
||||||
|
description: 'Environment variable name for the GPG private key passphrase. Default is
|
||||||
|
$GPG_PASSPHRASE.'
|
||||||
|
required: false
|
||||||
|
outputs:
|
||||||
|
path:
|
||||||
|
description: 'Path to where the java environment has been installed (same as $JAVA_HOME)'
|
||||||
|
version:
|
||||||
|
description: 'Actual version of the java environment that has been installed'
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node12'
|
||||||
main: 'dist/index.js'
|
main: 'dist/setup/index.js'
|
||||||
|
post: 'dist/cleanup/index.js'
|
||||||
|
4150
dist/cleanup/index.js
vendored
Normal file
4150
dist/cleanup/index.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
dist/index.js
generated
vendored
BIN
dist/index.js
generated
vendored
Binary file not shown.
38060
dist/setup/index.js
vendored
Normal file
38060
dist/setup/index.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
0
dist/unzip → dist/setup/unzip
vendored
0
dist/unzip → dist/setup/unzip
vendored
@ -1,34 +0,0 @@
|
|||||||
# Contributors
|
|
||||||
|
|
||||||
### Checkin
|
|
||||||
|
|
||||||
- Do checkin source (src)
|
|
||||||
- Do checkin a single index.js file after running `ncc`
|
|
||||||
- Do not checking node_modules
|
|
||||||
|
|
||||||
### NCC
|
|
||||||
|
|
||||||
In order to avoid uploading `node_modules` to the repository, we use [zeit/ncc](https://github.com/zeit/ncc) to create a single `index.js` file that gets saved in `dist/`.
|
|
||||||
|
|
||||||
If you're developing locally you can run
|
|
||||||
```
|
|
||||||
npm install
|
|
||||||
tsc
|
|
||||||
ncc build
|
|
||||||
```
|
|
||||||
You can also do
|
|
||||||
```
|
|
||||||
npm run-script build # runs tsc
|
|
||||||
npm run-script format # runs prettier --write
|
|
||||||
npm run-script format-check # runs prettier --check
|
|
||||||
npm run-script test # runs jest
|
|
||||||
npm run-script release # runs ncc build
|
|
||||||
```
|
|
||||||
|
|
||||||
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`.
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
Tests are included under `_tests_/*` and can be run using `npm run-script test`.
|
|
||||||
|
|
||||||
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.
|
|
2237
package-lock.json
generated
2237
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -3,13 +3,13 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "setup java action",
|
"description": "setup java action",
|
||||||
"main": "dist/index.js",
|
"main": "dist/setup/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "ncc build src/setup-java.ts",
|
"build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts",
|
||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --write **/*.ts",
|
||||||
"format-check": "prettier --check **/*.ts",
|
"format-check": "prettier --check **/*.ts",
|
||||||
"prerelease": "npm run-script build",
|
"prerelease": "npm run-script build",
|
||||||
"release": "git add -f dist/index.js",
|
"release": "git add -f dist/setup/index.js dist/cleanup/index.js",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -24,12 +24,13 @@
|
|||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.0.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.0.0",
|
"@actions/exec": "^1.0.0",
|
||||||
|
"@actions/http-client": "^1.0.8",
|
||||||
"@actions/io": "^1.0.0",
|
"@actions/io": "^1.0.0",
|
||||||
"@actions/tool-cache": "^1.0.0",
|
"@actions/tool-cache": "^1.3.1",
|
||||||
"semver": "^6.1.1",
|
"semver": "^6.1.1",
|
||||||
"typed-rest-client": "1.5.0"
|
"xmlbuilder2": "^2.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^24.0.13",
|
"@types/jest": "^24.0.13",
|
||||||
|
87
src/auth.ts
87
src/auth.ts
@ -3,60 +3,73 @@ import * as os from 'os';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
|
import {create as xmlCreate} from 'xmlbuilder2';
|
||||||
|
import * as constants from './constants';
|
||||||
|
|
||||||
export const M2_DIR = '.m2';
|
export const M2_DIR = '.m2';
|
||||||
export const SETTINGS_FILE = 'settings.xml';
|
export const SETTINGS_FILE = 'settings.xml';
|
||||||
|
|
||||||
export const DEFAULT_ID = 'github';
|
|
||||||
export const DEFAULT_USERNAME = 'GITHUB_ACTOR';
|
|
||||||
export const DEFAULT_PASSWORD = 'GITHUB_TOKEN';
|
|
||||||
|
|
||||||
export async function configAuthentication(
|
export async function configAuthentication(
|
||||||
id = DEFAULT_ID,
|
id: string,
|
||||||
username = DEFAULT_USERNAME,
|
username: string,
|
||||||
password = DEFAULT_PASSWORD
|
password: string,
|
||||||
|
gpgPassphrase: string | undefined = undefined
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
`creating ${SETTINGS_FILE} with server-id: ${id};`,
|
`creating ${SETTINGS_FILE} with server-id: ${id};`,
|
||||||
`environment variables: username=\$${username} and password=\$${password}`
|
'environment variables:',
|
||||||
|
`username=\$${username},`,
|
||||||
|
`password=\$${password},`,
|
||||||
|
`and gpg-passphrase=${gpgPassphrase ? '$' + gpgPassphrase : null}`
|
||||||
);
|
);
|
||||||
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
||||||
// otherwise use the home/.m2/ path
|
// otherwise use the home/.m2/ path
|
||||||
const directory: string = path.join(
|
const settingsDirectory: string = path.join(
|
||||||
core.getInput('settings-path') || os.homedir(),
|
core.getInput(constants.INPUT_SETTINGS_PATH) || os.homedir(),
|
||||||
core.getInput('settings-path') ? '' : M2_DIR
|
core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : M2_DIR
|
||||||
|
);
|
||||||
|
await io.mkdirP(settingsDirectory);
|
||||||
|
core.debug(`created directory ${settingsDirectory}`);
|
||||||
|
await write(
|
||||||
|
settingsDirectory,
|
||||||
|
generate(id, username, password, gpgPassphrase)
|
||||||
);
|
);
|
||||||
await io.mkdirP(directory);
|
|
||||||
core.debug(`created directory ${directory}`);
|
|
||||||
await write(directory, generate(id, username, password));
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeXML(value: string) {
|
|
||||||
return value
|
|
||||||
.replace(/&/g, '&')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>')
|
|
||||||
.replace(/"/g, '"')
|
|
||||||
.replace(/'/g, ''');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// only exported for testing purposes
|
// only exported for testing purposes
|
||||||
export function generate(
|
export function generate(
|
||||||
id = DEFAULT_ID,
|
id: string,
|
||||||
username = DEFAULT_USERNAME,
|
username: string,
|
||||||
password = DEFAULT_PASSWORD
|
password: string,
|
||||||
|
gpgPassphrase: string | undefined = undefined
|
||||||
) {
|
) {
|
||||||
return `
|
const xmlObj: {[key: string]: any} = {
|
||||||
<settings>
|
settings: {
|
||||||
<servers>
|
'@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0',
|
||||||
<server>
|
'@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
||||||
<id>${escapeXML(id)}</id>
|
'@xsi:schemaLocation':
|
||||||
<username>\${env.${escapeXML(username)}}</username>
|
'http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd',
|
||||||
<password>\${env.${escapeXML(password)}}</password>
|
servers: {
|
||||||
</server>
|
server: [
|
||||||
</servers>
|
{
|
||||||
</settings>
|
id: id,
|
||||||
`;
|
username: `\${env.${username}}`,
|
||||||
|
password: `\${env.${password}}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (gpgPassphrase) {
|
||||||
|
const gpgServer = {
|
||||||
|
id: 'gpg.passphrase',
|
||||||
|
passphrase: `\${env.${gpgPassphrase}}`
|
||||||
|
};
|
||||||
|
xmlObj.settings.servers.server.push(gpgServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlCreate(xmlObj).end({headless: true, prettyPrint: true, width: 80});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function write(directory: string, settings: string) {
|
async function write(directory: string, settings: string) {
|
||||||
|
19
src/cleanup-java.ts
Normal file
19
src/cleanup-java.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import * as gpg from './gpg';
|
||||||
|
import * as constants from './constants';
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
if (core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false})) {
|
||||||
|
core.info('removing private key from keychain');
|
||||||
|
try {
|
||||||
|
const keyFingerprint = core.getState(
|
||||||
|
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT
|
||||||
|
);
|
||||||
|
await gpg.deleteKey(keyFingerprint);
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed('failed to remove private key');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
16
src/constants.ts
Normal file
16
src/constants.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export const INPUT_VERSION = 'version';
|
||||||
|
export const INPUT_JAVA_VERSION = 'java-version';
|
||||||
|
export const INPUT_ARCHITECTURE = 'architecture';
|
||||||
|
export const INPUT_JAVA_PACKAGE = 'java-package';
|
||||||
|
export const INPUT_JDK_FILE = 'jdkFile';
|
||||||
|
export const INPUT_SERVER_ID = 'server-id';
|
||||||
|
export const INPUT_SERVER_USERNAME = 'server-username';
|
||||||
|
export const INPUT_SERVER_PASSWORD = 'server-password';
|
||||||
|
export const INPUT_SETTINGS_PATH = 'settings-path';
|
||||||
|
export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
|
||||||
|
export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
|
||||||
|
|
||||||
|
export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
|
||||||
|
export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
|
||||||
|
|
||||||
|
export const STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint';
|
58
src/gpg.ts
Normal file
58
src/gpg.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as io from '@actions/io';
|
||||||
|
import * as exec from '@actions/exec';
|
||||||
|
import * as util from './util';
|
||||||
|
import {ExecOptions} from '@actions/exec/lib/interfaces';
|
||||||
|
|
||||||
|
export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc');
|
||||||
|
|
||||||
|
const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/;
|
||||||
|
|
||||||
|
export async function importKey(privateKey: string) {
|
||||||
|
fs.writeFileSync(PRIVATE_KEY_FILE, privateKey, {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
flag: 'w'
|
||||||
|
});
|
||||||
|
|
||||||
|
let output = '';
|
||||||
|
|
||||||
|
const options: ExecOptions = {
|
||||||
|
silent: true,
|
||||||
|
listeners: {
|
||||||
|
stdout: (data: Buffer) => {
|
||||||
|
output += data.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await exec.exec(
|
||||||
|
'gpg',
|
||||||
|
[
|
||||||
|
'--batch',
|
||||||
|
'--import-options',
|
||||||
|
'import-show',
|
||||||
|
'--import',
|
||||||
|
PRIVATE_KEY_FILE
|
||||||
|
],
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
await io.rmRF(PRIVATE_KEY_FILE);
|
||||||
|
|
||||||
|
const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX);
|
||||||
|
return match && match[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteKey(keyFingerprint: string) {
|
||||||
|
await exec.exec(
|
||||||
|
'gpg',
|
||||||
|
['--batch', '--yes', '--delete-secret-keys', keyFingerprint],
|
||||||
|
{silent: true}
|
||||||
|
);
|
||||||
|
await exec.exec(
|
||||||
|
'gpg',
|
||||||
|
['--batch', '--yes', '--delete-keys', keyFingerprint],
|
||||||
|
{silent: true}
|
||||||
|
);
|
||||||
|
}
|
@ -1,30 +1,15 @@
|
|||||||
let tempDirectory = process.env['RUNNER_TEMP'] || '';
|
|
||||||
|
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
|
import * as httpm from '@actions/http-client';
|
||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import * as httpm from 'typed-rest-client/HttpClient';
|
import * as util from './util';
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const tempDirectory = util.getTempDir();
|
||||||
|
const IS_WINDOWS = util.isWindows();
|
||||||
if (!tempDirectory) {
|
|
||||||
let baseLocation;
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
// On windows use the USERPROFILE env variable
|
|
||||||
baseLocation = process.env['USERPROFILE'] || 'C:\\';
|
|
||||||
} else {
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
baseLocation = '/Users';
|
|
||||||
} else {
|
|
||||||
baseLocation = '/home';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getJava(
|
export async function getJava(
|
||||||
version: string,
|
version: string,
|
||||||
@ -39,15 +24,28 @@ export async function getJava(
|
|||||||
} else {
|
} else {
|
||||||
let compressedFileExtension = '';
|
let compressedFileExtension = '';
|
||||||
if (!jdkFile) {
|
if (!jdkFile) {
|
||||||
core.debug('Downloading Jdk from Azul');
|
core.debug('Downloading JDK from Azul');
|
||||||
let http: httpm.HttpClient = new httpm.HttpClient('setup-java');
|
const http = new httpm.HttpClient('setup-java', undefined, {
|
||||||
let contents = await (
|
allowRetries: true,
|
||||||
await http.get('https://static.azul.com/zulu/bin/')
|
maxRetries: 3
|
||||||
).readBody();
|
});
|
||||||
let refs = contents.match(/<a href.*\">/gi) || [];
|
const url = 'https://static.azul.com/zulu/bin/';
|
||||||
|
const response = await http.get(url);
|
||||||
const downloadInfo = getDownloadInfo(refs, version, javaPackage);
|
const statusCode = response.message.statusCode || 0;
|
||||||
|
if (statusCode < 200 || statusCode > 299) {
|
||||||
|
let body = '';
|
||||||
|
try {
|
||||||
|
body = await response.readBody();
|
||||||
|
} catch (err) {
|
||||||
|
core.debug(`Unable to read body: ${err.message}`);
|
||||||
|
}
|
||||||
|
const message = `Unexpected HTTP status code '${response.message.statusCode}' when retrieving versions from '${url}'. ${body}`.trim();
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const contents = await response.readBody();
|
||||||
|
const refs = contents.match(/<a href.*\">/gi) || [];
|
||||||
|
const downloadInfo = getDownloadInfo(refs, version, arch, javaPackage);
|
||||||
jdkFile = await tc.downloadTool(downloadInfo.url);
|
jdkFile = await tc.downloadTool(downloadInfo.url);
|
||||||
version = downloadInfo.version;
|
version = downloadInfo.version;
|
||||||
compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz';
|
compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz';
|
||||||
@ -74,9 +72,17 @@ export async function getJava(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch;
|
let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch;
|
||||||
|
core.exportVariable(extendedJavaHome, toolPath); //TODO: remove for v2
|
||||||
|
// For portability reasons environment variables should only consist of
|
||||||
|
// uppercase letters, digits, and the underscore. Therefore we convert
|
||||||
|
// the extendedJavaHome variable to upper case and replace '.' symbols and
|
||||||
|
// any other non-alphanumeric characters with an underscore.
|
||||||
|
extendedJavaHome = extendedJavaHome.toUpperCase().replace(/[^0-9A-Z_]/g, '_');
|
||||||
core.exportVariable('JAVA_HOME', toolPath);
|
core.exportVariable('JAVA_HOME', toolPath);
|
||||||
core.exportVariable(extendedJavaHome, toolPath);
|
core.exportVariable(extendedJavaHome, toolPath);
|
||||||
core.addPath(path.join(toolPath, 'bin'));
|
core.addPath(path.join(toolPath, 'bin'));
|
||||||
|
core.setOutput('path', toolPath);
|
||||||
|
core.setOutput('version', version);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCacheVersionString(version: string) {
|
function getCacheVersionString(version: string) {
|
||||||
@ -175,20 +181,26 @@ async function unzipJavaDownload(
|
|||||||
function getDownloadInfo(
|
function getDownloadInfo(
|
||||||
refs: string[],
|
refs: string[],
|
||||||
version: string,
|
version: string,
|
||||||
|
arch: string,
|
||||||
javaPackage: string
|
javaPackage: string
|
||||||
): {version: string; url: string} {
|
): {version: string; url: string} {
|
||||||
version = normalizeVersion(version);
|
version = normalizeVersion(version);
|
||||||
|
|
||||||
|
const archExtension = arch === 'x86' ? 'i686' : 'x64';
|
||||||
|
|
||||||
let extension = '';
|
let extension = '';
|
||||||
if (IS_WINDOWS) {
|
if (IS_WINDOWS) {
|
||||||
extension = `-win_x64.zip`;
|
extension = `-win_${archExtension}.zip`;
|
||||||
} else {
|
} else {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
extension = `-macosx_x64.tar.gz`;
|
extension = `-macosx_${archExtension}.tar.gz`;
|
||||||
} else {
|
} else {
|
||||||
extension = `-linux_x64.tar.gz`;
|
extension = `-linux_${archExtension}.tar.gz`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core.debug(`Searching for files with extension: ${extension}`);
|
||||||
|
|
||||||
let pkgRegexp = new RegExp('');
|
let pkgRegexp = new RegExp('');
|
||||||
let pkgTypeLength = 0;
|
let pkgTypeLength = 0;
|
||||||
if (javaPackage === 'jdk') {
|
if (javaPackage === 'jdk') {
|
||||||
|
@ -1,30 +1,60 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as installer from './installer';
|
import * as installer from './installer';
|
||||||
import * as auth from './auth';
|
import * as auth from './auth';
|
||||||
|
import * as gpg from './gpg';
|
||||||
|
import * as constants from './constants';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
let version = core.getInput('version');
|
let version = core.getInput(constants.INPUT_VERSION);
|
||||||
if (!version) {
|
if (!version) {
|
||||||
version = core.getInput('java-version', {required: true});
|
version = core.getInput(constants.INPUT_JAVA_VERSION, {required: true});
|
||||||
}
|
}
|
||||||
const arch = core.getInput('architecture', {required: true});
|
|
||||||
const javaPackage = core.getInput('java-package', {required: true});
|
const arch = core.getInput(constants.INPUT_ARCHITECTURE, {required: true});
|
||||||
const jdkFile = core.getInput('jdkFile', {required: false}) || '';
|
if (!['x86', 'x64'].includes(arch)) {
|
||||||
|
throw new Error(`architecture "${arch}" is not in [x86 | x64]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const javaPackage = core.getInput(constants.INPUT_JAVA_PACKAGE, {
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
const jdkFile = core.getInput(constants.INPUT_JDK_FILE, {required: false});
|
||||||
|
|
||||||
await installer.getJava(version, arch, jdkFile, javaPackage);
|
await installer.getJava(version, arch, jdkFile, javaPackage);
|
||||||
|
|
||||||
const matchersPath = path.join(__dirname, '..', '.github');
|
const matchersPath = path.join(__dirname, '..', '..', '.github');
|
||||||
console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);
|
core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);
|
||||||
|
|
||||||
const id = core.getInput('server-id', {required: false}) || undefined;
|
const id = core.getInput(constants.INPUT_SERVER_ID, {required: false});
|
||||||
const username =
|
const username = core.getInput(constants.INPUT_SERVER_USERNAME, {
|
||||||
core.getInput('server-username', {required: false}) || undefined;
|
required: false
|
||||||
const password =
|
});
|
||||||
core.getInput('server-password', {required: false}) || undefined;
|
const password = core.getInput(constants.INPUT_SERVER_PASSWORD, {
|
||||||
|
required: false
|
||||||
|
});
|
||||||
|
const gpgPrivateKey =
|
||||||
|
core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) ||
|
||||||
|
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
|
||||||
|
const gpgPassphrase =
|
||||||
|
core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) ||
|
||||||
|
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined);
|
||||||
|
|
||||||
await auth.configAuthentication(id, username, password);
|
if (gpgPrivateKey) {
|
||||||
|
core.setSecret(gpgPrivateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
await auth.configAuthentication(id, username, password, gpgPassphrase);
|
||||||
|
|
||||||
|
if (gpgPrivateKey) {
|
||||||
|
core.info('importing private key');
|
||||||
|
const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || '';
|
||||||
|
core.saveState(
|
||||||
|
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT,
|
||||||
|
keyFingerprint
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
26
src/util.ts
Normal file
26
src/util.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
export function getTempDir() {
|
||||||
|
let tempDirectory = process.env.RUNNER_TEMP;
|
||||||
|
if (tempDirectory === undefined) {
|
||||||
|
let baseLocation;
|
||||||
|
if (isWindows()) {
|
||||||
|
// On windows use the USERPROFILE env variable
|
||||||
|
baseLocation = process.env['USERPROFILE']
|
||||||
|
? process.env['USERPROFILE']
|
||||||
|
: 'C:\\';
|
||||||
|
} else {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
baseLocation = '/Users';
|
||||||
|
} else {
|
||||||
|
baseLocation = '/home';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
||||||
|
}
|
||||||
|
return tempDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isWindows() {
|
||||||
|
return process.platform === 'win32';
|
||||||
|
}
|
Reference in New Issue
Block a user