Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support java-version-file #95

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,27 @@ jobs:
# popd > /dev/null
- name: Remove components
run: gu remove espresso llvm-toolchain nodejs python ruby wasm

test-java-version-file:
name: java-version-file on ubuntu-latest
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # for `native-image-pr-reports` option
steps:
- uses: actions/checkout@v4
- run: echo '17' > .java-version
- name: Run setup-graalvm action
uses: ./
with:
java-version-file: .java-version
distribution: 'graalvm'
native-image-job-reports: 'true'
native-image-pr-reports: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build HelloWorld executable with GraalVM Native Image on Windows
run: |
echo 'public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }' > HelloWorld.java
javac HelloWorld.java
native-image HelloWorld
./helloworld
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ can be replaced with:

| Name | Default | Description |
|-----------------|:--------:|-------------|
| `java-version`<br>*(required)* | n/a | Java version <ul><li>major versions: `'21'`, `'17'`, `'11'`, `'8'`</li><li>specific versions: `'21.0.2'`, `'17.0.7'`</li><li>early access (EA) builds: `'22-ea'` *(requires `distribution: 'graalvm'`)*</li><li>latest EA build: `'latest-ea'` *(requires `distribution: 'graalvm'`)*</li><li>dev builds: `'dev'`</li></ul> |
| `java-version` | n/a | Java version <ul><li>major versions: `'21'`, `'17'`, `'11'`, `'8'`</li><li>specific versions: `'21.0.2'`, `'17.0.7'`</li><li>early access (EA) builds: `'22-ea'` *(requires `distribution: 'graalvm'`)*</li><li>latest EA build: `'latest-ea'` *(requires `distribution: 'graalvm'`)*</li><li>dev builds: `'dev'`</li></ul> |
| `java-version-file`| n/a | The path to the `.java-version` file. See more details in [about `.java-version` file](#Java-version-file) |
| `distribution` | `'graalvm'` | GraalVM distribution <ul><li>Oracle GraalVM: `'graalvm'`</li><li>GraalVM Community Edition: `'graalvm-community'`</li><li>Mandrel: `'mandrel'`</li><li>Liberica: `'liberica'`</li></ul> |
| `java-package` | `'jdk'` | The package type (`'jdk'` or `'jdk+fx'`). Currently applies to Liberica only. |
| `github-token` | `'${{ github.token }}'` | Token for communication with the GitHub API. Please set this to `${{ secrets.GITHUB_TOKEN }}` (see [templates](#templates)) to allow the action to authenticate with the GitHub API, which helps reduce rate-limiting issues. |
Expand All @@ -203,6 +204,20 @@ can be replaced with:

**) Make sure that Native Image is used only once per build job. Otherwise, the report is only generated for the last Native Image build.*

## Advanced Usage

### 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8, 11, 16 are rather old. Could you please update this and the other lists to 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openjdk64 does not make sense here. Maybe use graalvm-21.0.3 or so?

```
If the file contains multiple versions, only the first one will be recognized.

## Contributing

Expand Down
3 changes: 2 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ branding:
color: 'blue'
inputs:
java-version:
required: true
description: 'Java version. See examples of supported syntax in the README file.'
java-version-file:
description: 'The path to the `.java-version` file. See examples of supported syntax in README file'
java-package:
description: 'The package type (jdk or jdk+fx). Currently applies to Liberica only.'
required: false
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as otypes from '@octokit/types'
export const INPUT_VERSION = 'version'
export const INPUT_GDS_TOKEN = 'gds-token'
export const INPUT_JAVA_VERSION = 'java-version'
export const INPUT_JAVA_VERSION_FILE = 'java-version-file'
export const INPUT_JAVA_PACKAGE = 'java-package'
export const INPUT_DISTRIBUTION = 'distribution'
export const INPUT_COMPONENTS = 'components'
Expand All @@ -12,6 +13,8 @@ export const INPUT_CACHE = 'cache'
export const INPUT_CHECK_FOR_UPDATES = 'check-for-updates'
export const INPUT_NI_MUSL = 'native-image-musl'

export const DISTRIBUTIONS_ONLY_MAJOR_VERSION = ['corretto']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corretto does not make sense here, I'm ok with an empty array for compatibility with the upstream code

Suggested change
export const DISTRIBUTIONS_ONLY_MAJOR_VERSION = ['corretto']
export const DISTRIBUTIONS_ONLY_MAJOR_VERSION = []


export const IS_LINUX = process.platform === 'linux'
export const IS_MACOS = process.platform === 'darwin'
export const IS_WINDOWS = process.platform === 'win32'
Expand Down
31 changes: 30 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as c from './constants'
import * as core from '@actions/core'
import * as graalvm from './graalvm'
import {getVersionFromFileContent} from './utils'
import * as semver from 'semver'
import {isFeatureAvailable as isCacheAvailable} from '@actions/cache'
import {basename, join} from 'path'
Expand All @@ -14,10 +15,12 @@ import {setUpNativeImageMusl} from './features/musl'
import {setUpWindowsEnvironment} from './msvc'
import {setUpNativeImageBuildReports} from './features/reports'
import {exec} from '@actions/exec'
import fs from 'fs'

async function run(): Promise<void> {
try {
const javaVersion = core.getInput(c.INPUT_JAVA_VERSION, {required: true})
const javaVersionInput = core.getInput(c.INPUT_JAVA_VERSION)
const javaVersionFile = core.getInput(c.INPUT_JAVA_VERSION_FILE)
const javaPackage = core.getInput(c.INPUT_JAVA_PACKAGE)
const distribution = core.getInput(c.INPUT_DISTRIBUTION)
const graalVMVersion = core.getInput(c.INPUT_VERSION)
Expand All @@ -35,6 +38,32 @@ async function run(): Promise<void> {
const isGraalVMforJDK17OrLater =
distribution.length > 0 || graalVMVersion.length == 0

if (!javaVersionInput && !javaVersionFile) {
throw new Error('java-version or java-version-file input expected');
}

var javaVersion = javaVersionInput
if (!javaVersion) {
core.debug(
'java-version input is empty, looking for java-version-file input'
);
const content = fs.readFileSync(javaVersionFile).toString().trim();

javaVersion = getVersionFromFileContent(
content,
javaPackage,
javaVersionFile
)

core.debug(`Parsed version from file '${javaVersion}'`);

if (!javaVersion) {
throw new Error(
`No supported version was found in file ${javaVersionFile}`
);
}
}

if (c.IS_WINDOWS) {
setUpWindowsEnvironment(
javaVersion,
Expand Down
57 changes: 56 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {ExecOptions, exec as e} from '@actions/exec'
import {readFileSync, readdirSync} from 'fs'
import {Octokit} from '@octokit/core'
import {createHash} from 'crypto'
import {join} from 'path'
import {join, path} from 'path'

// Set up Octokit for github.com only and in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = 'https://api.github.com'
Expand Down Expand Up @@ -201,3 +201,58 @@ export async function createPRComment(content: string): Promise<void> {
)
}
}

// copied from https://github.com/actions/setup-java/blob/a1c6c9c8677803c9f4bd31e0f15ac0844258f955/src/util.ts#L116
export function getVersionFromFileContent(
content: string,
distributionName: string,
versionFile: string
): string | null {
let javaVersionRegExp: RegExp;

function getFileName(versionFile: string) {
return path.basename(versionFile);
}

const versionFileName = getFileName(versionFile);
if (versionFileName == '.tool-versions') {
javaVersionRegExp =
/^(java\s+)(?:\S*-)?v?(?<version>(\d+)(\.\d+)?(\.\d+)?(\+\d+)?(-ea(\.\d+)?)?)$/m;
} else {
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 (c.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;
}