Compare commits
16 Commits
v3.8.0
...
update-cod
Author | SHA1 | Date | |
---|---|---|---|
03d1057e7d | |||
d401f0c450 | |||
5e1c7d44c8 | |||
bf3c595741 | |||
35e7c82cf7 | |||
5bbbb020e8 | |||
007465e618 | |||
8a24ed99d8 | |||
3dc9295fa8 | |||
81f1f778b7 | |||
06db6c25b8 | |||
545223a83e | |||
a3c7fb1220 | |||
1eb7169fc2 | |||
caaa9d738f | |||
1df8dbefe2 |
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@ -1,2 +1 @@
|
||||
* @actions/actions-service
|
||||
* @actions/virtual-environments-owners
|
||||
* @actions/setup-actions-team
|
||||
|
17
.github/workflows/basic-validation.yml
vendored
Normal file
17
.github/workflows/basic-validation.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: Basic validation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
call-basic-validation:
|
||||
name: Basic validation
|
||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@ -1,31 +0,0 @@
|
||||
name: Build Action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.JS 16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm run format-check
|
||||
- run: npm test
|
41
.github/workflows/check-dist.yml
vendored
41
.github/workflows/check-dist.yml
vendored
@ -1,8 +1,3 @@
|
||||
# `dist/index.js` is a special file in Actions.
|
||||
# When you reference an action with `uses:` in a workflow,
|
||||
# `index.js` is the code that will run.
|
||||
# For our project, we generate this file through a build process from other source files.
|
||||
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||
name: Check dist/
|
||||
|
||||
on:
|
||||
@ -17,36 +12,6 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-dist:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set Node.js 16.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Rebuild the dist/ directory
|
||||
run: npm run build
|
||||
|
||||
- name: Compare the expected and actual dist/ directories
|
||||
run: |
|
||||
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||
echo "Detected uncommitted changes after build. See status below:"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
id: diff
|
||||
|
||||
# If index.js was different than expected, upload the expected version as an artifact
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
||||
call-check-dist:
|
||||
name: Check dist/
|
||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||
|
14
.github/workflows/codeql-analysis.yml
vendored
Normal file
14
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
name: CodeQL analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '0 3 * * 0'
|
||||
|
||||
jobs:
|
||||
call-codeQL-analysis:
|
||||
name: CodeQL analysis
|
||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
1
.github/workflows/e2e-cache.yml
vendored
1
.github/workflows/e2e-cache.yml
vendored
@ -1,4 +1,5 @@
|
||||
name: Validate cache
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
1
.github/workflows/e2e-local-file.yml
vendored
1
.github/workflows/e2e-local-file.yml
vendored
@ -1,4 +1,5 @@
|
||||
name: Validate local file
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
1
.github/workflows/e2e-publishing.yml
vendored
1
.github/workflows/e2e-publishing.yml
vendored
@ -1,4 +1,5 @@
|
||||
name: Validate publishing functionality
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
98
.github/workflows/e2e-versions.yml
vendored
98
.github/workflows/e2e-versions.yml
vendored
@ -1,4 +1,5 @@
|
||||
name: Validate Java e2e
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@ -240,4 +241,99 @@ jobs:
|
||||
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
||||
# Only Microsoft provides AArch64. However, GitHub-hosted runners do not support this architecture.
|
||||
setup-java-version-both-version-inputs-presents:
|
||||
name: ${{ matrix.distribution }} version (should be from input) - ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: ['temurin', 'microsoft', 'corretto' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "8" > .java-version
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: ${{ matrix.distribution }}
|
||||
java-version: 11
|
||||
java-version-file: '.java-version'
|
||||
- name: Verify Java
|
||||
run: bash __tests__/verify-java.sh "11" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
||||
setup-java-version-from-file-major-notation:
|
||||
name: ${{ matrix.distribution }} version from file X - ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: ['temurin', 'zulu', 'liberica', 'microsoft', 'corretto' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "11" > .java-version
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: ${{ matrix.distribution }}
|
||||
java-version-file: '.java-version'
|
||||
- name: Verify Java
|
||||
run: bash __tests__/verify-java.sh "11" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
||||
setup-java-version-from-file-major-minor-patch-notation:
|
||||
name: ${{ matrix.distribution }} version from file X.Y.Z - ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: [ 'adopt', 'adopt-openj9', 'zulu' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "11.0.2" > .java-version
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: ${{ matrix.distribution }}
|
||||
java-version-file: '.java-version'
|
||||
- name: Verify Java
|
||||
run: bash __tests__/verify-java.sh "11.0.2" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
||||
setup-java-version-from-file-major-minor-patch-with-dist:
|
||||
name: ${{ matrix.distribution }} version from file 'openjdk64-11.0.2' - ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: ['adopt', 'zulu', 'liberica' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Create .java-version file
|
||||
shell: bash
|
||||
run: echo "openjdk64-11.0.2" > .java-version
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
distribution: ${{ matrix.distribution }}
|
||||
java-version-file: '.java-version'
|
||||
- name: Verify Java
|
||||
run: bash __tests__/verify-java.sh "11.0.2" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
16
.github/workflows/licensed.yml
vendored
16
.github/workflows/licensed.yml
vendored
@ -10,16 +10,6 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check licenses
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: npm ci
|
||||
- name: Install licensed
|
||||
run: |
|
||||
cd $RUNNER_TEMP
|
||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
|
||||
sudo tar -xzf licensed.tar.gz
|
||||
sudo mv licensed /usr/local/bin/licensed
|
||||
- run: licensed status
|
||||
call-licensed:
|
||||
name: Licensed
|
||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||
|
@ -1,4 +1,5 @@
|
||||
name: Release new action version
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
@ -23,13 +23,15 @@ This action allows you to work with Java and Scala projects.
|
||||
|
||||
## Usage
|
||||
|
||||
- `java-version`: _(required)_ The Java version to set up. Takes a whole or [semver](#supported-version-syntax) Java version.
|
||||
- `java-version`: The Java version that is going to be set up. Takes a whole or [semver](#supported-version-syntax) Java version. If not specified, the action will expect `java-version-file` input to be specified.
|
||||
|
||||
- `java-version-file`: The path to the `.java-version` file. See more details in [about `.java-version` file](docs/advanced-usage.md#Java-version-file).
|
||||
|
||||
- `distribution`: _(required)_ Java [distribution](#supported-distributions).
|
||||
|
||||
- `java-package`: The packaging variant of the choosen distribution. Possible values: `jdk`, `jre`, `jdk+fx`, `jre+fx`. Default value: `jdk`.
|
||||
|
||||
- `architecture`: The target architecture of the package. Possible values: `x86`, `x64`, `armv7`, `aarch64`, `ppc64le`. Default value: `x64`.
|
||||
- `architecture`: The target architecture of the package. Possible values: `x86`, `x64`, `armv7`, `aarch64`, `ppc64le`. Default value: Derived from the runner machine.
|
||||
|
||||
- `jdkFile`: If a use-case requires a custom distribution setup-java uses the compressed JDK from the location pointed by this input and will take care of the installation and caching on the VM.
|
||||
|
||||
|
@ -29,14 +29,13 @@ describe('isVersionSatisfies', () => {
|
||||
describe('isCacheFeatureAvailable', () => {
|
||||
it('isCacheFeatureAvailable disabled on GHES', () => {
|
||||
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false);
|
||||
const infoMock = jest.spyOn(core, 'warning');
|
||||
const message =
|
||||
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.';
|
||||
try {
|
||||
process.env['GITHUB_SERVER_URL'] = 'http://example.com';
|
||||
isCacheFeatureAvailable();
|
||||
} catch (error) {
|
||||
expect(error).toHaveProperty(
|
||||
'message',
|
||||
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
|
||||
);
|
||||
expect(isCacheFeatureAvailable()).toBeFalsy();
|
||||
expect(infoMock).toHaveBeenCalledWith(message);
|
||||
} finally {
|
||||
delete process.env['GITHUB_SERVER_URL'];
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ author: 'GitHub'
|
||||
inputs:
|
||||
java-version:
|
||||
description: 'The Java version to set up. Takes a whole or semver Java version. See examples of supported syntax in README file'
|
||||
required: true
|
||||
java-version-file:
|
||||
description: 'The path to the `.java-version` file. See examples of supported syntax in README file'
|
||||
distribution:
|
||||
description: 'Java distribution. See the list of supported distributions in README file'
|
||||
required: true
|
||||
|
49
dist/cleanup/index.js
vendored
49
dist/cleanup/index.js
vendored
@ -68480,9 +68480,10 @@ else {
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
|
||||
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION_FILE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
|
||||
exports.MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
|
||||
exports.INPUT_JAVA_VERSION = 'java-version';
|
||||
exports.INPUT_JAVA_VERSION_FILE = 'java-version-file';
|
||||
exports.INPUT_ARCHITECTURE = 'architecture';
|
||||
exports.INPUT_JAVA_PACKAGE = 'java-package';
|
||||
exports.INPUT_DISTRIBUTION = 'distribution';
|
||||
@ -68505,6 +68506,7 @@ exports.MVN_SETTINGS_FILE = 'settings.xml';
|
||||
exports.MVN_TOOLCHAINS_FILE = 'toolchains.xml';
|
||||
exports.INPUT_MVN_TOOLCHAIN_ID = 'mvn-toolchain-id';
|
||||
exports.INPUT_MVN_TOOLCHAIN_VENDOR = 'mvn-toolchain-vendor';
|
||||
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = ['corretto'];
|
||||
|
||||
|
||||
/***/ }),
|
||||
@ -68622,7 +68624,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0;
|
||||
exports.getVersionFromFileContent = exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0;
|
||||
const os_1 = __importDefault(__nccwpck_require__(2037));
|
||||
const path_1 = __importDefault(__nccwpck_require__(1017));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
@ -68706,18 +68708,45 @@ function isGhes() {
|
||||
}
|
||||
exports.isGhes = isGhes;
|
||||
function isCacheFeatureAvailable() {
|
||||
if (!cache.isFeatureAvailable()) {
|
||||
if (isGhes()) {
|
||||
throw new Error('Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.');
|
||||
}
|
||||
else {
|
||||
core.warning('The runner was not able to contact the cache service. Caching will be skipped');
|
||||
}
|
||||
if (cache.isFeatureAvailable()) {
|
||||
return true;
|
||||
}
|
||||
if (isGhes()) {
|
||||
core.warning('Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
core.warning('The runner was not able to contact the cache service. Caching will be skipped');
|
||||
return false;
|
||||
}
|
||||
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
|
||||
function getVersionFromFileContent(content, distributionName) {
|
||||
var _a, _b, _c, _d, _e;
|
||||
const javaVersionRegExp = /(?<version>(?<=(^|\s|\-))(\d+\S*))(\s|$)/;
|
||||
const fileContent = ((_b = (_a = content.match(javaVersionRegExp)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.version)
|
||||
? (_d = (_c = content.match(javaVersionRegExp)) === null || _c === void 0 ? void 0 : _c.groups) === null || _d === void 0 ? void 0 : _d.version
|
||||
: '';
|
||||
if (!fileContent) {
|
||||
return null;
|
||||
}
|
||||
core.debug(`Version from file '${fileContent}'`);
|
||||
const tentativeVersion = avoidOldNotation(fileContent);
|
||||
const rawVersion = tentativeVersion.split('-')[0];
|
||||
let version = semver.validRange(rawVersion) ? tentativeVersion : semver.coerce(tentativeVersion);
|
||||
core.debug(`Range version from file is '${version}'`);
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
if (constants_1.DISTRIBUTIONS_ONLY_MAJOR_VERSION.includes(distributionName)) {
|
||||
const coerceVersion = (_e = semver.coerce(version)) !== null && _e !== void 0 ? _e : version;
|
||||
version = semver.major(coerceVersion).toString();
|
||||
}
|
||||
return version.toString();
|
||||
}
|
||||
exports.getVersionFromFileContent = getVersionFromFileContent;
|
||||
// By convention, action expects version 8 in the format `8.*` instead of `1.8`
|
||||
function avoidOldNotation(content) {
|
||||
return content.startsWith('1.') ? content.substring(2) : content;
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
126
dist/setup/index.js
vendored
126
dist/setup/index.js
vendored
@ -103582,9 +103582,10 @@ function isProbablyGradleDaemonProblem(packageManager, error) {
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
|
||||
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION_FILE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
|
||||
exports.MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
|
||||
exports.INPUT_JAVA_VERSION = 'java-version';
|
||||
exports.INPUT_JAVA_VERSION_FILE = 'java-version-file';
|
||||
exports.INPUT_ARCHITECTURE = 'architecture';
|
||||
exports.INPUT_JAVA_PACKAGE = 'java-package';
|
||||
exports.INPUT_DISTRIBUTION = 'distribution';
|
||||
@ -103607,6 +103608,7 @@ exports.MVN_SETTINGS_FILE = 'settings.xml';
|
||||
exports.MVN_TOOLCHAINS_FILE = 'toolchains.xml';
|
||||
exports.INPUT_MVN_TOOLCHAIN_ID = 'mvn-toolchain-id';
|
||||
exports.INPUT_MVN_TOOLCHAIN_VENDOR = 'mvn-toolchain-vendor';
|
||||
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = ['corretto'];
|
||||
|
||||
|
||||
/***/ }),
|
||||
@ -104551,7 +104553,7 @@ class MicrosoftDistributions extends base_installer_1.JavaBase {
|
||||
}
|
||||
const foundRelease = yield tc.findFromManifest(range, true, manifest, arch);
|
||||
if (!foundRelease) {
|
||||
throw new Error(`Could not find satisfied version for SemVer ${range}. ${manifest
|
||||
throw new Error(`Could not find satisfied version for SemVer ${range}.\nAvailable versions: ${manifest
|
||||
.map(item => item.version)
|
||||
.join(', ')}`);
|
||||
}
|
||||
@ -105056,7 +105058,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const fs_1 = __importDefault(__nccwpck_require__(7147));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const auth = __importStar(__nccwpck_require__(3497));
|
||||
const util_1 = __nccwpck_require__(2629);
|
||||
@ -105068,37 +105074,45 @@ const distribution_factory_1 = __nccwpck_require__(924);
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION, { required: true });
|
||||
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
|
||||
const distributionName = core.getInput(constants.INPUT_DISTRIBUTION, { required: true });
|
||||
const versionFile = core.getInput(constants.INPUT_JAVA_VERSION_FILE);
|
||||
const architecture = core.getInput(constants.INPUT_ARCHITECTURE);
|
||||
const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE);
|
||||
const jdkFile = core.getInput(constants.INPUT_JDK_FILE);
|
||||
const cache = core.getInput(constants.INPUT_CACHE);
|
||||
const checkLatest = util_1.getBooleanInput(constants.INPUT_CHECK_LATEST, false);
|
||||
let toolchainIds = core.getMultilineInput(constants.INPUT_MVN_TOOLCHAIN_ID);
|
||||
core.startGroup('Installed distributions');
|
||||
if (versions.length !== toolchainIds.length) {
|
||||
toolchainIds = [];
|
||||
}
|
||||
core.startGroup('Installed distributions');
|
||||
for (const [index, version] of versions.entries()) {
|
||||
const installerOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
version,
|
||||
checkLatest
|
||||
};
|
||||
const distribution = distribution_factory_1.getJavaDistribution(distributionName, installerOptions, jdkFile);
|
||||
if (!distribution) {
|
||||
throw new Error(`No supported distribution was found for input ${distributionName}`);
|
||||
if (!versions.length && !versionFile) {
|
||||
throw new Error('java-version or java-version-file input expected');
|
||||
}
|
||||
const installerInputsOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
distributionName,
|
||||
jdkFile,
|
||||
toolchainIds
|
||||
};
|
||||
if (!versions.length) {
|
||||
core.debug('java-version input is empty, looking for java-version-file input');
|
||||
const content = fs_1.default
|
||||
.readFileSync(versionFile)
|
||||
.toString()
|
||||
.trim();
|
||||
const version = util_1.getVersionFromFileContent(content, distributionName);
|
||||
core.debug(`Parsed version from file '${version}'`);
|
||||
if (!version) {
|
||||
throw new Error(`No supported version was found in file ${versionFile}`);
|
||||
}
|
||||
const result = yield distribution.setupJava();
|
||||
yield toolchains.configureToolchains(version, distributionName, result.path, toolchainIds[index]);
|
||||
core.info('');
|
||||
core.info('Java configuration:');
|
||||
core.info(` Distribution: ${distributionName}`);
|
||||
core.info(` Version: ${result.version}`);
|
||||
core.info(` Path: ${result.path}`);
|
||||
core.info('');
|
||||
yield installVersion(version, installerInputsOptions);
|
||||
}
|
||||
for (const [index, version] of versions.entries()) {
|
||||
yield installVersion(version, installerInputsOptions, index);
|
||||
}
|
||||
core.endGroup();
|
||||
const matchersPath = path.join(__dirname, '..', '..', '.github');
|
||||
@ -105114,6 +105128,29 @@ function run() {
|
||||
});
|
||||
}
|
||||
run();
|
||||
function installVersion(version, options, toolchainId = 0) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { distributionName, jdkFile, architecture, packageType, checkLatest, toolchainIds } = options;
|
||||
const installerOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
version
|
||||
};
|
||||
const distribution = distribution_factory_1.getJavaDistribution(distributionName, installerOptions, jdkFile);
|
||||
if (!distribution) {
|
||||
throw new Error(`No supported distribution was found for input ${distributionName}`);
|
||||
}
|
||||
const result = yield distribution.setupJava();
|
||||
yield toolchains.configureToolchains(version, distributionName, result.path, toolchainIds[toolchainId]);
|
||||
core.info('');
|
||||
core.info('Java configuration:');
|
||||
core.info(` Distribution: ${distributionName}`);
|
||||
core.info(` Version: ${result.version}`);
|
||||
core.info(` Path: ${result.path}`);
|
||||
core.info('');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
@ -105315,7 +105352,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0;
|
||||
exports.getVersionFromFileContent = exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0;
|
||||
const os_1 = __importDefault(__nccwpck_require__(2037));
|
||||
const path_1 = __importDefault(__nccwpck_require__(1017));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
@ -105399,18 +105436,45 @@ function isGhes() {
|
||||
}
|
||||
exports.isGhes = isGhes;
|
||||
function isCacheFeatureAvailable() {
|
||||
if (!cache.isFeatureAvailable()) {
|
||||
if (isGhes()) {
|
||||
throw new Error('Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.');
|
||||
}
|
||||
else {
|
||||
core.warning('The runner was not able to contact the cache service. Caching will be skipped');
|
||||
}
|
||||
if (cache.isFeatureAvailable()) {
|
||||
return true;
|
||||
}
|
||||
if (isGhes()) {
|
||||
core.warning('Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
core.warning('The runner was not able to contact the cache service. Caching will be skipped');
|
||||
return false;
|
||||
}
|
||||
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
|
||||
function getVersionFromFileContent(content, distributionName) {
|
||||
var _a, _b, _c, _d, _e;
|
||||
const javaVersionRegExp = /(?<version>(?<=(^|\s|\-))(\d+\S*))(\s|$)/;
|
||||
const fileContent = ((_b = (_a = content.match(javaVersionRegExp)) === null || _a === void 0 ? void 0 : _a.groups) === null || _b === void 0 ? void 0 : _b.version)
|
||||
? (_d = (_c = content.match(javaVersionRegExp)) === null || _c === void 0 ? void 0 : _c.groups) === null || _d === void 0 ? void 0 : _d.version
|
||||
: '';
|
||||
if (!fileContent) {
|
||||
return null;
|
||||
}
|
||||
core.debug(`Version from file '${fileContent}'`);
|
||||
const tentativeVersion = avoidOldNotation(fileContent);
|
||||
const rawVersion = tentativeVersion.split('-')[0];
|
||||
let version = semver.validRange(rawVersion) ? tentativeVersion : semver.coerce(tentativeVersion);
|
||||
core.debug(`Range version from file is '${version}'`);
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
if (constants_1.DISTRIBUTIONS_ONLY_MAJOR_VERSION.includes(distributionName)) {
|
||||
const coerceVersion = (_e = semver.coerce(version)) !== null && _e !== void 0 ? _e : version;
|
||||
version = semver.major(coerceVersion).toString();
|
||||
}
|
||||
return version.toString();
|
||||
}
|
||||
exports.getVersionFromFileContent = getVersionFromFileContent;
|
||||
// By convention, action expects version 8 in the format `8.*` instead of `1.8`
|
||||
function avoidOldNotation(content) {
|
||||
return content.startsWith('1.') ? content.substring(2) : content;
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
@ -15,6 +15,7 @@
|
||||
- [Publishing using Gradle](#Publishing-using-Gradle)
|
||||
- [Hosted Tool Cache](#Hosted-Tool-Cache)
|
||||
- [Modifying Maven Toolchains](#Modifying-Maven-Toolchains)
|
||||
- [Java-version file](#Java-version-file)
|
||||
|
||||
See [action.yml](../action.yml) for more details on task inputs.
|
||||
|
||||
@ -464,3 +465,15 @@ steps:
|
||||
something_else
|
||||
something_other
|
||||
```
|
||||
|
||||
## Java-version file
|
||||
If the `java-version-file` input is specified, the action will try to extract the version from the file and install it.
|
||||
Action is able to recognize all variants of the version description according to [jenv](https://github.com/jenv/jenv).
|
||||
Valid entry options:
|
||||
```
|
||||
major versions: 8, 11, 16, 17
|
||||
more specific versions: 1.8.0.2, 17.0, 11.0, 11.0.4, 8.0.232, 8.0.282+8
|
||||
early access (EA) versions: 15-ea, 15.0.0-ea, 15.0.0-ea.2, 15.0.0+2-ea
|
||||
versions with specified distribution: openjdk64-11.0.2
|
||||
```
|
||||
If the file contains multiple versions, only the first one will be recognized.
|
||||
|
@ -8,6 +8,7 @@
|
||||
"build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts",
|
||||
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
|
||||
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
|
||||
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
|
||||
"prerelease": "npm run-script build",
|
||||
"release": "git add -f dist/setup/index.js dist/cleanup/index.js",
|
||||
"test": "jest"
|
||||
|
@ -1,5 +1,6 @@
|
||||
export const MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
|
||||
export const INPUT_JAVA_VERSION = 'java-version';
|
||||
export const INPUT_JAVA_VERSION_FILE = 'java-version-file';
|
||||
export const INPUT_ARCHITECTURE = 'architecture';
|
||||
export const INPUT_JAVA_PACKAGE = 'java-package';
|
||||
export const INPUT_DISTRIBUTION = 'distribution';
|
||||
@ -26,3 +27,5 @@ export const MVN_SETTINGS_FILE = 'settings.xml';
|
||||
export const MVN_TOOLCHAINS_FILE = 'toolchains.xml';
|
||||
export const INPUT_MVN_TOOLCHAIN_ID = 'mvn-toolchain-id';
|
||||
export const INPUT_MVN_TOOLCHAIN_VENDOR = 'mvn-toolchain-vendor';
|
||||
|
||||
export const DISTRIBUTIONS_ONLY_MAJOR_VERSION = ['corretto'];
|
||||
|
@ -60,7 +60,7 @@ export class MicrosoftDistributions extends JavaBase {
|
||||
|
||||
if (!foundRelease) {
|
||||
throw new Error(
|
||||
`Could not find satisfied version for SemVer ${range}. ${manifest
|
||||
`Could not find satisfied version for SemVer ${range}.\nAvailable versions: ${manifest
|
||||
.map(item => item.version)
|
||||
.join(', ')}`
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import * as core from '@actions/core';
|
||||
import * as auth from './auth';
|
||||
import { getBooleanInput, isCacheFeatureAvailable } from './util';
|
||||
import { getBooleanInput, isCacheFeatureAvailable, getVersionFromFileContent } from './util';
|
||||
import * as toolchains from './toolchains';
|
||||
import * as constants from './constants';
|
||||
import { restore } from './cache';
|
||||
@ -10,8 +11,9 @@ import { JavaInstallerOptions } from './distributions/base-models';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION, { required: true });
|
||||
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
|
||||
const distributionName = core.getInput(constants.INPUT_DISTRIBUTION, { required: true });
|
||||
const versionFile = core.getInput(constants.INPUT_JAVA_VERSION_FILE);
|
||||
const architecture = core.getInput(constants.INPUT_ARCHITECTURE);
|
||||
const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE);
|
||||
const jdkFile = core.getInput(constants.INPUT_JDK_FILE);
|
||||
@ -19,38 +21,44 @@ async function run() {
|
||||
const checkLatest = getBooleanInput(constants.INPUT_CHECK_LATEST, false);
|
||||
let toolchainIds = core.getMultilineInput(constants.INPUT_MVN_TOOLCHAIN_ID);
|
||||
|
||||
core.startGroup('Installed distributions');
|
||||
|
||||
if (versions.length !== toolchainIds.length) {
|
||||
toolchainIds = [];
|
||||
}
|
||||
|
||||
core.startGroup('Installed distributions');
|
||||
for (const [index, version] of versions.entries()) {
|
||||
const installerOptions: JavaInstallerOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
version,
|
||||
checkLatest
|
||||
};
|
||||
if (!versions.length && !versionFile) {
|
||||
throw new Error('java-version or java-version-file input expected');
|
||||
}
|
||||
|
||||
const distribution = getJavaDistribution(distributionName, installerOptions, jdkFile);
|
||||
if (!distribution) {
|
||||
throw new Error(`No supported distribution was found for input ${distributionName}`);
|
||||
const installerInputsOptions: installerInputsOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
distributionName,
|
||||
jdkFile,
|
||||
toolchainIds
|
||||
};
|
||||
|
||||
if (!versions.length) {
|
||||
core.debug('java-version input is empty, looking for java-version-file input');
|
||||
const content = fs
|
||||
.readFileSync(versionFile)
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
const version = getVersionFromFileContent(content, distributionName);
|
||||
core.debug(`Parsed version from file '${version}'`);
|
||||
|
||||
if (!version) {
|
||||
throw new Error(`No supported version was found in file ${versionFile}`);
|
||||
}
|
||||
|
||||
const result = await distribution.setupJava();
|
||||
await toolchains.configureToolchains(
|
||||
version,
|
||||
distributionName,
|
||||
result.path,
|
||||
toolchainIds[index]
|
||||
);
|
||||
await installVersion(version, installerInputsOptions);
|
||||
}
|
||||
|
||||
core.info('');
|
||||
core.info('Java configuration:');
|
||||
core.info(` Distribution: ${distributionName}`);
|
||||
core.info(` Version: ${result.version}`);
|
||||
core.info(` Path: ${result.path}`);
|
||||
core.info('');
|
||||
for (const [index, version] of versions.entries()) {
|
||||
await installVersion(version, installerInputsOptions, index);
|
||||
}
|
||||
core.endGroup();
|
||||
const matchersPath = path.join(__dirname, '..', '..', '.github');
|
||||
@ -66,3 +74,50 @@ async function run() {
|
||||
}
|
||||
|
||||
run();
|
||||
|
||||
async function installVersion(version: string, options: installerInputsOptions, toolchainId = 0) {
|
||||
const {
|
||||
distributionName,
|
||||
jdkFile,
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
toolchainIds
|
||||
} = options;
|
||||
|
||||
const installerOptions: JavaInstallerOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
version
|
||||
};
|
||||
|
||||
const distribution = getJavaDistribution(distributionName, installerOptions, jdkFile);
|
||||
if (!distribution) {
|
||||
throw new Error(`No supported distribution was found for input ${distributionName}`);
|
||||
}
|
||||
|
||||
const result = await distribution.setupJava();
|
||||
await toolchains.configureToolchains(
|
||||
version,
|
||||
distributionName,
|
||||
result.path,
|
||||
toolchainIds[toolchainId]
|
||||
);
|
||||
|
||||
core.info('');
|
||||
core.info('Java configuration:');
|
||||
core.info(` Distribution: ${distributionName}`);
|
||||
core.info(` Version: ${result.version}`);
|
||||
core.info(` Path: ${result.path}`);
|
||||
core.info('');
|
||||
}
|
||||
|
||||
interface installerInputsOptions {
|
||||
architecture: string;
|
||||
packageType: string;
|
||||
checkLatest: boolean;
|
||||
distributionName: string;
|
||||
jdkFile: string;
|
||||
toolchainIds: Array<string>;
|
||||
}
|
||||
|
58
src/util.ts
58
src/util.ts
@ -6,7 +6,7 @@ import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import { INPUT_JOB_STATUS } from './constants';
|
||||
import { INPUT_JOB_STATUS, DISTRIBUTIONS_ONLY_MAJOR_VERSION } from './constants';
|
||||
|
||||
export function getTempDir() {
|
||||
let tempDirectory = process.env['RUNNER_TEMP'] || os.tmpdir();
|
||||
@ -85,17 +85,55 @@ export function isGhes(): boolean {
|
||||
}
|
||||
|
||||
export function isCacheFeatureAvailable(): boolean {
|
||||
if (!cache.isFeatureAvailable()) {
|
||||
if (isGhes()) {
|
||||
throw new Error(
|
||||
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
|
||||
);
|
||||
} else {
|
||||
core.warning('The runner was not able to contact the cache service. Caching will be skipped');
|
||||
}
|
||||
if (cache.isFeatureAvailable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isGhes()) {
|
||||
core.warning(
|
||||
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
core.warning('The runner was not able to contact the cache service. Caching will be skipped');
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getVersionFromFileContent(
|
||||
content: string,
|
||||
distributionName: string
|
||||
): string | null {
|
||||
const javaVersionRegExp = /(?<version>(?<=(^|\s|\-))(\d+\S*))(\s|$)/;
|
||||
const fileContent = content.match(javaVersionRegExp)?.groups?.version
|
||||
? (content.match(javaVersionRegExp)?.groups?.version as string)
|
||||
: '';
|
||||
if (!fileContent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
core.debug(`Version from file '${fileContent}'`);
|
||||
|
||||
const tentativeVersion = avoidOldNotation(fileContent);
|
||||
const rawVersion = tentativeVersion.split('-')[0];
|
||||
|
||||
let version = semver.validRange(rawVersion) ? tentativeVersion : semver.coerce(tentativeVersion);
|
||||
|
||||
core.debug(`Range version from file is '${version}'`);
|
||||
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (DISTRIBUTIONS_ONLY_MAJOR_VERSION.includes(distributionName)) {
|
||||
const coerceVersion = semver.coerce(version) ?? version;
|
||||
version = semver.major(coerceVersion).toString();
|
||||
}
|
||||
|
||||
return version.toString();
|
||||
}
|
||||
|
||||
// By convention, action expects version 8 in the format `8.*` instead of `1.8`
|
||||
function avoidOldNotation(content: string): string {
|
||||
return content.startsWith('1.') ? content.substring(2) : content;
|
||||
}
|
||||
|
Reference in New Issue
Block a user