Skip to content

Commit fd877f3

Browse files
authored
Update languagetool-pr.yml
1 parent 1ff1ed4 commit fd877f3

1 file changed

Lines changed: 122 additions & 102 deletions

File tree

Lines changed: 122 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,176 @@
1-
name: LanguageTool (PR review)
1+
name: LanguageTool (reviewdog)
22

33
on:
4-
# Run once when the PR is opened/re-opened.
54
pull_request_target:
65
types: [opened, reopened, labeled]
7-
8-
# Allow maintainers to rerun by commenting "/languagetool"
96
issue_comment:
107
types: [created]
118

129
permissions:
1310
contents: read
1411
pull-requests: write
15-
issues: write
1612

1713
concurrency:
18-
group: languagetool-${{ github.event.pull_request.number || github.event.issue.number || github.run_id }}
14+
group: languagetool-${{ github.event.pull_request.number || github.event.issue.number }}
1915
cancel-in-progress: true
2016

21-
env:
22-
LT_LANGUAGE: en-US
23-
RERUN_LABEL: languagetool:run
24-
2517
jobs:
26-
# Comment command -> adds a label -> label event triggers the real run
27-
rerun_on_comment:
28-
if: |
29-
github.event_name == 'issue_comment' &&
30-
github.event.issue.pull_request &&
31-
contains(github.event.comment.body, '/languagetool') &&
32-
(github.event.comment.author_association == 'MEMBER' ||
33-
github.event.comment.author_association == 'OWNER' ||
34-
github.event.comment.author_association == 'COLLABORATOR')
18+
languagetool:
3519
runs-on: ubuntu-latest
20+
3621
steps:
37-
- name: Add rerun label to PR
22+
- name: Decide whether to run + gather PR info
23+
id: meta
3824
uses: actions/github-script@v7
3925
with:
4026
script: |
41-
const label = process.env.RERUN_LABEL;
42-
const owner = context.repo.owner;
43-
const repo = context.repo.repo;
44-
const issue_number = context.issue.number; // PR number for issue_comment
45-
46-
// Ensure label exists (create if missing)
47-
try {
48-
await github.rest.issues.getLabel({ owner, repo, name: label });
49-
} catch (e) {
50-
await github.rest.issues.createLabel({
51-
owner,
52-
repo,
53-
name: label,
54-
color: '0e8a16',
55-
description: 'Rerun LanguageTool on this PR'
27+
const eventName = context.eventName;
28+
29+
async function getPerm(username) {
30+
const res = await github.rest.repos.getCollaboratorPermissionLevel({
31+
owner: context.repo.owner,
32+
repo: context.repo.repo,
33+
username,
5634
});
35+
return res.data.permission; // admin|maintain|write|triage|read|none
5736
}
5837
59-
await github.rest.issues.addLabels({
60-
owner,
61-
repo,
62-
issue_number,
63-
labels: [label]
64-
});
38+
let run = false;
39+
let prNumber = null;
40+
let pr = null;
41+
42+
if (eventName === "pull_request_target") {
43+
pr = context.payload.pull_request;
44+
prNumber = pr.number;
45+
46+
if (context.payload.action === "labeled") {
47+
run = (context.payload.label?.name === "languagetool:rerun");
48+
} else {
49+
// opened / reopened
50+
run = true;
51+
}
52+
} else if (eventName === "issue_comment") {
53+
// only run for PR comments
54+
if (!context.payload.issue?.pull_request) {
55+
run = false;
56+
} else {
57+
const body = (context.payload.comment?.body || "").trim();
58+
const wants = body.startsWith("/languagetool");
59+
if (!wants) {
60+
run = false;
61+
} else {
62+
const perm = await getPerm(context.payload.comment.user.login);
63+
run = ["admin", "maintain", "write"].includes(perm);
64+
}
65+
66+
prNumber = context.payload.issue.number;
67+
const prRes = await github.rest.pulls.get({
68+
owner: context.repo.owner,
69+
repo: context.repo.repo,
70+
pull_number: prNumber,
71+
});
72+
pr = prRes.data;
73+
}
74+
}
6575
66-
languagetool:
67-
if: |
68-
github.event_name == 'pull_request_target' &&
69-
(
70-
github.event.action == 'opened' ||
71-
github.event.action == 'reopened' ||
72-
(github.event.action == 'labeled' && github.event.label.name == 'languagetool:run')
73-
)
74-
runs-on: ubuntu-latest
76+
core.setOutput("run", run ? "true" : "false");
77+
if (!pr) return;
7578
76-
steps:
77-
- name: Checkout PR (head SHA)
79+
core.setOutput("pr_number", String(prNumber));
80+
core.setOutput("head_sha", pr.head.sha);
81+
core.setOutput("base_sha", pr.base.sha);
82+
core.setOutput("head_repo", pr.head.repo.full_name);
83+
core.setOutput("base_repo", pr.base.repo.full_name);
84+
85+
- name: Stop early if not requested
86+
if: steps.meta.outputs.run != 'true'
87+
run: echo "Not running LanguageTool."
88+
89+
- name: Checkout PR head (safe)
90+
if: steps.meta.outputs.run == 'true'
7891
uses: actions/checkout@v4
7992
with:
80-
ref: ${{ github.event.pull_request.head.sha }}
93+
repository: ${{ steps.meta.outputs.head_repo }}
94+
ref: ${{ steps.meta.outputs.head_sha }}
8195
fetch-depth: 0
96+
persist-credentials: false
97+
submodules: false
8298

83-
- name: Build LanguageTool server image with custom dictionary
84-
shell: bash
99+
- name: Fetch base SHA for diffing
100+
if: steps.meta.outputs.run == 'true'
85101
run: |
86102
set -euo pipefail
103+
git remote add upstream "https://github.com/${{ steps.meta.outputs.base_repo }}.git" || true
104+
git fetch --no-tags --depth=1 upstream "${{ steps.meta.outputs.base_sha }}"
87105
88-
WORDS_DIR=".github/languagetool"
89-
SPELLING_FILE="$WORDS_DIR/spelling.en.txt"
90-
IGNORE_FILE="$WORDS_DIR/ignore.en.txt"
91-
92-
mkdir -p "$WORDS_DIR"
93-
test -f "$SPELLING_FILE" || : > "$SPELLING_FILE"
94-
test -f "$IGNORE_FILE" || : > "$IGNORE_FILE"
95-
96-
# Safety cap (avoid someone committing a gigantic word list)
97-
head -n 2000 "$SPELLING_FILE" > /tmp/spelling_additions.txt
98-
head -n 2000 "$IGNORE_FILE" > /tmp/ignore_additions.txt
99-
100-
mkdir -p /tmp/lt
101-
cp /tmp/spelling_additions.txt /tmp/lt/spelling_additions.txt
102-
cp /tmp/ignore_additions.txt /tmp/lt/ignore_additions.txt
106+
- name: Setup Python
107+
if: steps.meta.outputs.run == 'true'
108+
uses: actions/setup-python@v5
109+
with:
110+
python-version: "3.11"
103111

104-
cat > /tmp/lt/Dockerfile <<'EOF'
105-
FROM erikvl87/languagetool:latest
106-
USER root
107-
COPY spelling_additions.txt /tmp/spelling_additions.txt
108-
COPY ignore_additions.txt /tmp/ignore_additions.txt
109-
RUN set -e; \
110-
if [ -s /tmp/spelling_additions.txt ]; then (echo; cat /tmp/spelling_additions.txt) >> org/languagetool/resource/en/hunspell/spelling.txt; fi; \
111-
if [ -s /tmp/ignore_additions.txt ]; then (echo; cat /tmp/ignore_additions.txt) >> org/languagetool/resource/en/hunspell/ignore.txt; fi
112-
USER languagetool
113-
EOF
112+
- name: Install Python deps
113+
if: steps.meta.outputs.run == 'true'
114+
run: |
115+
python -m pip install --upgrade pip
116+
python -m pip install requests
114117
115-
docker build -t lt-custom /tmp/lt
118+
- name: Setup reviewdog
119+
if: steps.meta.outputs.run == 'true'
120+
uses: reviewdog/action-setup@v1
121+
with:
122+
reviewdog_version: latest
116123

117124
- name: Start LanguageTool server
118-
shell: bash
125+
if: steps.meta.outputs.run == 'true'
119126
run: |
120127
set -euo pipefail
121-
docker run -d --name languagetool -p 8010:8010 lt-custom
128+
docker run -d --rm --name languagetool -p 8010:8010 erikvl87/languagetool:latest
122129
123-
# Wait until the API is up
124-
for i in {1..60}; do
125-
if curl -fsS http://127.0.0.1:8010/v2/languages >/dev/null; then
130+
# Wait until ready
131+
for i in $(seq 1 60); do
132+
if curl -fsS "http://localhost:8010/v2/languages" >/dev/null; then
133+
echo "LanguageTool is up."
126134
exit 0
127135
fi
128-
sleep 1
136+
sleep 2
129137
done
130138
131-
echo "LanguageTool server did not start in time" >&2
139+
echo "LanguageTool did not become ready in time" >&2
132140
docker logs languagetool || true
133141
exit 1
134142
135-
- name: Run LanguageTool and comment suggestions on the PR
136-
uses: reviewdog/action-languagetool@v1.23.0
137-
with:
138-
github_token: ${{ secrets.GITHUB_TOKEN }}
139-
reporter: github-pr-review
140-
level: info
141-
patterns: "**/*.md **/*.txt **/*.rst **/*.adoc"
142-
language: ${{ env.LT_LANGUAGE }}
143-
custom_api_endpoint: "http://127.0.0.1:8010"
144-
145-
- name: Remove rerun label (so maintainers can trigger again)
146-
if: github.event.action == 'labeled' && github.event.label.name == 'languagetool:run'
147-
continue-on-error: true
143+
- name: Run LanguageTool and comment on PR
144+
if: steps.meta.outputs.run == 'true'
145+
env:
146+
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
147+
run: |
148+
set -euo pipefail
149+
python .github/scripts/languagetool_reviewdog.py \
150+
--api-url "http://localhost:8010/v2/check" \
151+
--language "en-US" \
152+
--base-sha "${{ steps.meta.outputs.base_sha }}" \
153+
--head-sha "${{ steps.meta.outputs.head_sha }}" \
154+
--dictionary ".languagetool/words.txt" \
155+
| reviewdog -f=rdjson \
156+
-name="LanguageTool" \
157+
-reporter="github-pr-review" \
158+
-filter-mode="file" \
159+
-fail-level="none" \
160+
-level="warning"
161+
162+
- name: Remove rerun label (so it can be added again later)
163+
if: steps.meta.outputs.run == 'true' && github.event_name == 'pull_request_target' && github.event.action == 'labeled' && github.event.label.name == 'languagetool:rerun'
148164
uses: actions/github-script@v7
149165
with:
150166
script: |
151167
await github.rest.issues.removeLabel({
152168
owner: context.repo.owner,
153169
repo: context.repo.repo,
154170
issue_number: context.payload.pull_request.number,
155-
name: 'languagetool:run',
171+
name: "languagetool:rerun",
156172
});
173+
174+
- name: Stop LanguageTool
175+
if: always() && steps.meta.outputs.run == 'true'
176+
run: docker stop languagetool || true

0 commit comments

Comments
 (0)