Skip to content

Commit 47d9951

Browse files
committed
Take the version from .open-java-format-version
The action took the version as an input and the pre-commit hook pinned its own in FORMATTER_VERSION, so a repository had two places to keep in step, and either could fall behind on its own. Now both read .open-java-format-version from the repository root, and the version input is gone. Without the file, or with something in it that is not a version number, the action and the hook stop and say what to put there. The check for a newer release stays: the log warning and the code scanning alert now point at .open-java-format-version, line 1, which also does away with the search for the line of the workflow that named the version. The hook's help text says to change that one file. This repository already keeps its own version in that file for Follow open-java-format releases, so Test Action runs the action and the hook with it, and now also checks that both refuse to run without it. The version input is gone, so this is v4.
1 parent 25979c3 commit 47d9951

6 files changed

Lines changed: 103 additions & 79 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ on:
55
pull_request:
66
workflow_dispatch: # Follow open-java-format releases runs this on the bump it pushes
77

8-
# No version input anywhere here: the tests run the action with its default, the version that Follow
9-
# open-java-format releases bumps. That workflow pushes with its own token, which may not change a
10-
# workflow file, so the version must not be written in this one.
8+
# No version anywhere here: the action and the hook read .open-java-format-version from the checkout,
9+
# the file that Follow open-java-format releases bumps. That workflow pushes with its own token, which
10+
# may not change a workflow file, so the version must not be written in this one.
1111
jobs:
1212
test-changed:
1313
name: Test mode=changed
@@ -25,8 +25,9 @@ jobs:
2525
mode: changed
2626
code-scanning: true # with the permission: the upload has to go through
2727

28-
# The action and the hook on every platform they support, with a file that is formatted and one that
29-
# is not. The repository itself has no Java files, so the tests write their own.
28+
# The action and the hook on every platform they support: with a file that is formatted, with one
29+
# that is not, and without .open-java-format-version. The repository itself has no Java files, so
30+
# the tests write their own.
3031
test-platforms:
3132
name: Test on ${{ matrix.os }}
3233
runs-on: ${{ matrix.os }}
@@ -64,12 +65,34 @@ jobs:
6465
- name: Make sure the check failed
6566
run: test "${{ steps.unformatted.outcome }}" = failure
6667

67-
- name: Run the pre-commit hook on a file that is not formatted, then on a formatted one
68+
- name: Take .open-java-format-version away, leaving only the formatted file
69+
run: |
70+
rm Unformatted.java
71+
mv .open-java-format-version version.away
72+
73+
- name: Check without the version file, expecting a failure
74+
id: no-version
75+
continue-on-error: true
76+
uses: ./
77+
with:
78+
mode: all
79+
80+
- name: Make sure that failed, and put the file back
81+
run: |
82+
test "${{ steps.no-version.outcome }}" = failure
83+
mv version.away .open-java-format-version
84+
85+
- name: Run the pre-commit hook without the version file, then on a file that is not formatted, then on a formatted one
6886
run: |
6987
git init -q hook-test
7088
cd hook-test
7189
printf 'class Hook{int x;}\n' > Hook.java
7290
git add Hook.java
91+
if bash ../pre-commit; then
92+
echo "::error::The hook ran without .open-java-format-version"
93+
exit 1
94+
fi
95+
cp ../.open-java-format-version .
7396
if bash ../pre-commit; then
7497
echo "::error::The hook accepted a file that is not formatted"
7598
exit 1

‎.github/workflows/follow-releases.yml‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: Follow open-java-format releases
22

3-
# The action, the pre-commit hook and the README name one open-java-format version, and
4-
# .open-java-format-version holds it. Once an hour this compares that file with the latest release of
3+
# .open-java-format-version holds the open-java-format version this repository is on, as it does in
4+
# any repository that uses the action or the pre-commit hook; the README and the error messages name
5+
# the version too. Once an hour this compares that file with the latest release of
56
# openjavaformat/open-java-format. When a new release is out, the version is replaced in every file
67
# that names it, the result is pushed to main, and Test Action is run on it. That run has to be
78
# explicit: a push made with the workflow's own token starts no push-triggered workflow.
@@ -49,8 +50,9 @@ jobs:
4950
git commit --all --quiet --file - <<COMMIT
5051
Check with open-java-format $latest
5152
52-
The action and the pre-commit hook default to $latest, which
53-
openjavaformat/open-java-format released on $published. Made by the
53+
.open-java-format-version names $latest, which
54+
openjavaformat/open-java-format released on $published, so the tests
55+
run the action and the pre-commit hook with it. Made by the
5456
"$GITHUB_WORKFLOW" workflow:
5557
$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID
5658
COMMIT

‎README.md‎

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,26 @@ No Java, Maven, or Gradle required — downloads a native binary from Maven Cent
66

77
## Usage
88

9+
The version of open-java-format to check with goes in `.open-java-format-version` at the repository root, one of the versions on [Maven Central](https://repo1.maven.org/maven2/dev/openjavaformat/open-java-format-native/):
10+
11+
```
12+
2.98.0.6
13+
```
14+
15+
The action and the [pre-commit hook](#git-pre-commit-hook) both read that file, so the two cannot drift apart; without it, both stop and ask for it. The action itself needs no inputs:
16+
917
```yaml
1018
- uses: actions/checkout@v7
1119

12-
- uses: openjavaformat/open-java-format-action@v3
13-
with:
14-
version: '2.98.0.6'
20+
- uses: openjavaformat/open-java-format-action@v4
1521
```
1622
17-
v3 is for open-java-format 2.98.0.2 and later, which has a single style; it differs from v2 by the optional [code scanning report](#code-scanning). A workflow that pins 2.98.0.1 stays on `@v1`, which passes that version the `--ojf` flag it needs.
23+
v4 is for open-java-format 2.98.0.2 and later, which has a single style. v3 and v2 are for the same versions but take the version as a `version` input instead of the file. A workflow that pins 2.98.0.1 stays on `@v1`, which passes that version the `--ojf` flag it needs.
1824

1925
## Inputs
2026

2127
| Input | Required | Default | Description |
2228
|-------|----------|---------|-------------|
23-
| `version` | yes | `2.98.0.6` | Version of the open-java-format native binary, one of those on [Maven Central](https://repo1.maven.org/maven2/dev/openjavaformat/open-java-format-native/) |
2429
| `mode` | no | `changed` | `changed` — only files from PR or push; `all` — every `.java` file in repo |
2530
| `code-scanning` | no | `false` | Also report the version check to [code scanning](#code-scanning); needs the `security-events: write` permission |
2631

@@ -32,6 +37,7 @@ v3 is for open-java-format 2.98.0.2 and later, which has a single style; it diff
3237

3338
## Behaviour
3439

40+
- If `.open-java-format-version` is missing → stops and asks for the file ❌
3541
- If all files are formatted correctly → passes ✅
3642
- If any file has formatting issues → lists unformatted files and fails ❌
3743
- If a newer open-java-format release is out → warns in the job log, and raises a [code scanning alert](#code-scanning) when that is turned on
@@ -70,7 +76,7 @@ Notes:
7076

7177
## Recommended setup
7278

73-
Both setups check the files of a pull request and every file on a push to `main`. They differ in where a newer open-java-format release is announced.
79+
Both setups check the files of a pull request and every file on a push to `main`, with the version from `.open-java-format-version`. They differ in where a newer open-java-format release is announced.
7480

7581
### With the version check in the job log
7682

@@ -88,9 +94,8 @@ jobs:
8894
steps:
8995
- uses: actions/checkout@v7
9096
91-
- uses: openjavaformat/open-java-format-action@v3
97+
- uses: openjavaformat/open-java-format-action@v4
9298
with:
93-
version: '2.98.0.6'
9499
mode: ${{ github.event_name == 'push' && 'all' || 'changed' }}
95100
```
96101

@@ -114,24 +119,22 @@ jobs:
114119
steps:
115120
- uses: actions/checkout@v7
116121
117-
- uses: openjavaformat/open-java-format-action@v3
122+
- uses: openjavaformat/open-java-format-action@v4
118123
with:
119-
version: '2.98.0.6'
120124
mode: ${{ github.event_name == 'push' && 'all' || 'changed' }}
121125
code-scanning: true
122126
```
123127

124128
## Code scanning
125129

126-
The action compares the `version` it runs with the latest [open-java-format release](https://github.com/openjavaformat/open-java-format/releases) and warns in the job log when a newer one is out. A log warning is easy to miss, so the check can also be reported to code scanning: the action then uploads a SARIF file with one alert while the version is behind, and with none once it is current, which closes the alert. The alert shows up under **Security → Code scanning** and in the **Code scanning results** check on pull requests, and points at the line of the workflow that names the version.
130+
The action compares the version in `.open-java-format-version` with the latest [open-java-format release](https://github.com/openjavaformat/open-java-format/releases) and warns in the job log when a newer one is out. A log warning is easy to miss, so the check can also be reported to code scanning: the action then uploads a SARIF file with one alert while the version is behind, and with none once it is current, which closes the alert. The alert shows up under **Security → Code scanning** and in the **Code scanning results** check on pull requests, and points at `.open-java-format-version`.
127131

128132
This is off by default, because the upload needs the `security-events: write` permission, which the default token does not have. To turn it on, set `code-scanning: true` and give the job the permission, as in the [second recommended setup](#with-the-version-check-in-code-scanning-too). If the permission is missing anyway, the upload is skipped with a line in the log, the check passes as before, and the log warning stays. Code scanning is free on public repositories; a private repository needs [GitHub Code Security](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository) enabled. Pull requests from forks run with a read-only token and get the log warning only.
129133

130134
One report per job is enough. When the job runs on a matrix, turn it on for one leg only:
131135

132136
```yaml
133137
with:
134-
version: '2.98.0.6'
135138
code-scanning: ${{ matrix.os == 'ubuntu-latest' }}
136139
```
137140

@@ -148,9 +151,7 @@ cp pre-commit .githooks/pre-commit
148151
git config core.hooksPath .githooks
149152
```
150153

151-
The hook automatically downloads the native binary on first run and caches it in `~/.cache/open-java-format`, then checks only staged `.java` files on each commit. It also honours the same [`.open-java-format-exclude`](#excluding-files) file as the action.
152-
153-
The hook pins its own formatter version in `FORMATTER_VERSION` at the top of the script — keep it in step with the `version` your workflow passes to the action.
154+
The hook reads the version from the same [`.open-java-format-version`](#usage) file as the action and honours the same [`.open-java-format-exclude`](#excluding-files) file. It downloads the native binary on first run and caches it in `~/.cache/open-java-format`, then checks only staged `.java` files on each commit.
154155

155156
## Supported platforms
156157

‎action.yml‎

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ branding:
77
color: 'green'
88

99
inputs:
10-
version:
11-
description: 'Version of open-java-format to use'
12-
required: true
13-
default: '2.98.0.6'
1410
mode:
1511
description: 'Which files to check: "changed" for files from PR/push, "all" for every .java file'
1612
required: false
@@ -23,6 +19,25 @@ inputs:
2319
runs:
2420
using: 'composite'
2521
steps:
22+
- name: Read the open-java-format version
23+
id: version
24+
shell: bash
25+
run: |
26+
# The version to check with comes from .open-java-format-version in the repository root,
27+
# the file the pre-commit hook reads too, so that the two cannot drift apart.
28+
FILE=".open-java-format-version"
29+
if [ ! -f "$FILE" ]; then
30+
echo "::error::No $FILE in the repository root. Put the open-java-format version to check with in it, one of the releases at https://github.com/openjavaformat/open-java-format/releases, for example: echo 2.98.0.6 > $FILE"
31+
exit 1
32+
fi
33+
VERSION=$(head -n1 "$FILE" | tr -d '[:space:]')
34+
if ! [[ "$VERSION" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then
35+
echo "::error file=$FILE,line=1::$FILE holds '$VERSION', not an open-java-format version such as 2.98.0.6."
36+
exit 1
37+
fi
38+
echo "Checking with open-java-format $VERSION, from $FILE."
39+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
40+
2641
- name: Detect platform
2742
id: platform
2843
shell: bash
@@ -61,7 +76,7 @@ runs:
6176
env:
6277
GH_TOKEN: ${{ github.token }}
6378
run: |
64-
VERSION="${{ inputs.version }}"
79+
VERSION="${{ steps.version.outputs.version }}"
6580
6681
# Best-effort version check — must never fail the build. The GitHub API
6782
# returns 403 for unauthenticated CI requests (rate limit), so authenticate
@@ -79,24 +94,23 @@ runs:
7994
if [ -z "$LATEST" ]; then
8095
echo "Could not check the latest open-java-format version — skipping this check."
8196
elif [ "$LATEST" != "$VERSION" ]; then
82-
echo "::warning::A newer open-java-format version is available: $LATEST (you are using $VERSION)"
97+
echo "::warning file=.open-java-format-version,line=1::A newer open-java-format version is available: $LATEST (.open-java-format-version has $VERSION)"
8398
fi
8499
85100
- name: Report the version check to code scanning
86101
if: inputs.code-scanning == 'true' && steps.latest.outputs.version != ''
87102
shell: bash
88103
env:
89104
GH_TOKEN: ${{ github.token }}
90-
VERSION: ${{ inputs.version }}
105+
VERSION: ${{ steps.version.outputs.version }}
91106
LATEST: ${{ steps.latest.outputs.version }}
92107
run: |
93108
# A log warning is easy to miss, so the check is also handed to code scanning: a SARIF
94109
# file with one alert while a newer release is out, and with none once the version is
95-
# current, which closes the alert. The alert sits on the line of this repository's
96-
# workflow that names the version, so that it points at what to change. The upload goes
97-
# straight to the REST API: github/codeql-action/upload-sarif fails the job when the
98-
# permission is missing, and this must stay best-effort, like the check itself — nothing
99-
# here may fail the build.
110+
# current, which closes the alert. The alert sits on .open-java-format-version, the file
111+
# to change. The upload goes straight to the REST API: github/codeql-action/upload-sarif
112+
# fails the job when the permission is missing, and this must stay best-effort, like the
113+
# check itself — nothing here may fail the build.
100114
case "$GITHUB_REF" in
101115
refs/heads/*|refs/tags/*|refs/pull/*) ;;
102116
*) echo "Code scanning takes no results for ref '$GITHUB_REF' — not reporting the version check."; exit 0 ;;
@@ -108,37 +122,13 @@ runs:
108122
109123
RESULTS='[]'
110124
if [ "$LATEST" != "$VERSION" ]; then
111-
# The first line naming the version: in the workflow that runs this job, then in any
112-
# other workflow of the repository (a reusable one, say). Failing that, the line that
113-
# uses the action, then the top of the workflow.
114-
FILE=""
115-
LINE=""
116-
PATTERN="(^|[^0-9.])${VERSION//./\\.}([^0-9.]|$)"
117-
while IFS= read -r CANDIDATE; do
118-
[ -f "$CANDIDATE" ] || continue
119-
HIT=$(grep -nE -m1 "$PATTERN" "$CANDIDATE" | cut -d: -f1 || true)
120-
if [ -n "$HIT" ]; then
121-
FILE="$CANDIDATE"
122-
LINE="$HIT"
123-
break
124-
fi
125-
done < <(printf '%s\n' "$WORKFLOW"; find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null | sort)
126-
if [ -z "$FILE" ] && [ -f "$WORKFLOW" ]; then
127-
FILE="$WORKFLOW"
128-
LINE=$(grep -nE -m1 'uses:.*open-java-format-action' "$FILE" | cut -d: -f1 || true)
129-
LINE="${LINE:-1}"
130-
fi
131-
if [ -z "$FILE" ]; then
132-
echo "No workflow file to put the alert on — not reporting the version check."
133-
exit 0
134-
fi
135-
136-
# Code scanning tells alerts apart by this fingerprint, not by the line number. It is
137-
# made from the line's text without whitespace, so the alert survives the line moving.
138-
TEXT=$(sed -n "${LINE}p" "$FILE" | tr -d '\r')
125+
FILE=".open-java-format-version"
126+
LINE=1
127+
# Code scanning tells alerts apart by this fingerprint, made from the line's text.
128+
TEXT=$(head -n1 "$FILE" | tr -d '\r')
139129
FINGERPRINT=$(printf '%s' "${TEXT//[[:space:]]/}" | git hash-object --stdin)
140130
RESULTS=$(jq -n \
141-
--arg text "open-java-format $LATEST is available; this workflow checks formatting with $VERSION." \
131+
--arg text "open-java-format $LATEST is available; $FILE has $VERSION." \
142132
--arg file "$FILE" --argjson line "$LINE" --argjson end "$(( ${#TEXT} + 1 ))" \
143133
--arg fingerprint "${FINGERPRINT:0:16}:1" \
144134
'[{
@@ -155,14 +145,9 @@ runs:
155145
156146
HELP="$RUNNER_TEMP/open-java-format-version-help.md"
157147
cat > "$HELP" <<'HELP_END'
158-
A newer [open-java-format release](https://github.com/openjavaformat/open-java-format/releases) is out than the one this workflow checks formatting with. Releases fix formatting bugs, so code that passes with the pinned version may be formatted differently by the newer one.
159-
160-
To update:
161-
162-
- set the `version` input of `openjavaformat/open-java-format-action` to the new release;
163-
- if the repository uses the pre-commit hook, set `FORMATTER_VERSION` at the top of it to the same release.
148+
A newer [open-java-format release](https://github.com/openjavaformat/open-java-format/releases) is out than the one named in `.open-java-format-version`. Releases fix formatting bugs, so code that passes with the pinned version may be formatted differently by the newer one.
164149
165-
The alert closes on its own once the workflow runs with the latest release.
150+
To update, put the new release in `.open-java-format-version` at the repository root. The action and the pre-commit hook both read that file. The alert closes on its own once the workflow runs with the latest release.
166151
HELP_END
167152
168153
# One category per workflow and job, so that uploads from different jobs do not replace
@@ -179,7 +164,7 @@ runs:
179164
id: "outdated-version",
180165
name: "OutdatedVersion",
181166
shortDescription: {text: "A newer open-java-format release is available"},
182-
fullDescription: {text: "The workflow checks formatting with an open-java-format version older than the latest release. Releases fix formatting bugs, so code that passes with the pinned version may be formatted differently by the newer one."},
167+
fullDescription: {text: ".open-java-format-version names an open-java-format version older than the latest release. Releases fix formatting bugs, so code that passes with the pinned version may be formatted differently by the newer one."},
183168
help: {text: $help, markdown: $help},
184169
defaultConfiguration: {level: "warning"},
185170
properties: {tags: ["maintainability"], precision: "very-high", "problem.severity": "warning"}
@@ -224,13 +209,13 @@ runs:
224209
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
225210
with:
226211
path: ${{ github.action_path }}/${{ steps.platform.outputs.binary }}
227-
key: open-java-format-${{ inputs.version }}-${{ steps.platform.outputs.suffix }}
212+
key: open-java-format-${{ steps.version.outputs.version }}-${{ steps.platform.outputs.suffix }}
228213

229214
- name: Download open-java-format native binary
230215
if: steps.cache.outputs.cache-hit != 'true'
231216
shell: bash
232217
run: |
233-
VERSION="${{ inputs.version }}"
218+
VERSION="${{ steps.version.outputs.version }}"
234219
SUFFIX="${{ steps.platform.outputs.suffix }}"
235220
BASE_URL="https://repo1.maven.org/maven2/dev/openjavaformat/open-java-format-native/${VERSION}"
236221
ARTIFACT="open-java-format-native-${VERSION}-nativeImage-${SUFFIX}.${{ steps.platform.outputs.extension }}"

‎example-usage.yml‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ jobs:
1515
- uses: actions/checkout@v7
1616

1717
- name: Check formatting
18-
uses: openjavaformat/open-java-format-action@v3
18+
uses: openjavaformat/open-java-format-action@v4
1919
with:
20-
version: '2.98.0.6'
2120
mode: ${{ github.event_name == 'push' && 'all' || 'changed' }}

0 commit comments

Comments
 (0)