Skip to content

Bump astro from 5.16.6 to 5.16.9 #14

Bump astro from 5.16.6 to 5.16.9

Bump astro from 5.16.6 to 5.16.9 #14

Workflow file for this run

# .github/workflows/languagetool.yml
name: LanguageTool (PR comment)
on:
pull_request_target:
types: [opened, reopened, synchronize, labeled]
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
issues: write
concurrency:
group: languagetool-${{ github.event.pull_request.number || github.event.issue.number || github.run_id }}
cancel-in-progress: true
env:
LT_LANGUAGE: en-US
RERUN_LABEL: languagetool:rerun
jobs:
# Comment command -> toggles a label to trigger the PR job
rerun_on_comment:
if: |
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/languagetool') &&
(github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'COLLABORATOR')
runs-on: ubuntu-latest
steps:
- name: Toggle rerun label on PR
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = context.issue.number;
const label = process.env.RERUN_LABEL;
// Ensure label exists
try {
await github.rest.issues.getLabel({ owner, repo, name: label });
} catch {
await github.rest.issues.createLabel({
owner, repo, name: label, color: '0e8a16',
description: 'Rerun LanguageTool on this PR'
});
}
// Remove if present (ignore errors), then add to force a new "labeled" event
try {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: label });
} catch {}
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [label] });
languagetool:
if: |
github.event_name == 'pull_request_target' &&
(
github.event.action == 'opened' ||
github.event.action == 'reopened' ||
github.event.action == 'synchronize' ||
(github.event.action == 'labeled' && github.event.label.name == 'languagetool:rerun')
)
runs-on: ubuntu-latest
steps:
- name: Checkout PR head (safe)
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Fetch base SHA for diff
run: |
set -euo pipefail
git remote add upstream "https://github.com/${{ github.event.pull_request.base.repo.full_name }}.git" || true
git fetch --no-tags --depth=1 upstream "${{ github.event.pull_request.base.sha }}"
- name: Setup Java 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Download LanguageTool CLI (latest snapshot)
run: |
set -euo pipefail
curl -fsSL -o lt.zip "https://internal1.languagetool.org/snapshots/LanguageTool-latest-snapshot.zip"
rm -rf .lt
mkdir -p .lt
unzip -q lt.zip -d .lt
LT_JAR="$(ls -1 .lt/**/languagetool-commandline.jar 2>/dev/null | head -n1 || true)"
if [ -z "${LT_JAR}" ]; then
echo "Could not find languagetool-commandline.jar in snapshot" >&2
find .lt -maxdepth 4 -type f -name "*languagetool*jar" -print >&2 || true
exit 1
fi
echo "LT_JAR=${LT_JAR}" >> "$GITHUB_ENV"
- name: Run LanguageTool + build PR comment (collapsible + exact word)
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
# jq is present on ubuntu-latest, but install if your runner image differs
command -v jq >/dev/null || (sudo apt-get update && sudo apt-get install -y jq)
# Choose files to check
mapfile -t FILES < <(git diff --name-only "$BASE_SHA" "$HEAD_SHA" \
| grep -E '\.(md|mdx|txt|rst|adoc|asciidoc|tex)$' || true)
# Load custom words (optional)
WORDS_FILE=".languagetool/words.txt"
if [ -f "$WORDS_FILE" ]; then
WORDS_JSON="$(jq -R -s '
split("\n")
| map(gsub("\r";""))
| map(select(length>0 and (startswith("#")|not)))
| map(ascii_downcase)
' "$WORDS_FILE")"
else
WORDS_JSON='[]'
fi
: > results.jsonl
if [ "${#FILES[@]}" -eq 0 ]; then
echo '{"file":"(none)","issues":[]}' >> results.jsonl
else
for f in "${FILES[@]}"; do
[ -f "$f" ] || continue
# LT can print banner lines; keep JSON only (accepts either { or [)
java -jar "$LT_JAR" -l "${LT_LANGUAGE}" --json "$f" 2>/dev/null \
| sed -n '/^[{[]/,$p' > lt.json || true
# Extract issues and filter spelling-ish matches for custom words
jq -c \
--arg file "$f" \
--argjson words "$WORDS_JSON" '
def bad_raw:
(.context.offset // 0) as $o
| (.context.length // 0) as $l
| (.context.text // "") as $t
| ($t[$o:($o+$l)]);
def badtoken:
(bad_raw
| gsub("^[^[:alnum:]]+|[^[:alnum:]]+$";"")
| ascii_downcase);
(.matches // [])
| map(
. as $m
| ($m.rule.id // "") as $rid
| ($m.rule.category.id // "") as $cat
| (badtoken) as $bt
| select(
( (( $cat == "TYPOS") or ($rid|test("MORFOLOGIK";"i")) )
and (($words|index($bt)) != null)
) | not
)
| {
message: ($m.message // "LanguageTool finding"),
rule: $rid,
bad: (bad_raw),
replacements: (($m.replacements // []) | map(.value) | .[0:3]),
context: ($m.context.text // ""),
context_offset: ($m.context.offset // 0),
context_length: ($m.context.length // 0)
}
)
| {file:$file, issues:.}
' lt.json >> results.jsonl
done
fi
# Build markdown body (stored as a file) - collapsible per file
node <<'NODE'
const fs = require("fs");
const marker = "<!-- languagetool-report -->";
const raw = fs.readFileSync("results.jsonl","utf8").trim();
const lines = raw ? raw.split("\n").filter(Boolean) : [];
const parsed = lines.map(l => JSON.parse(l));
const checkedFiles = parsed.map(p => p.file).filter(f => f && f !== "(none)");
const byFile = parsed
.filter(p => Array.isArray(p.issues) && p.issues.length > 0)
.reduce((acc, p) => { acc[p.file] = p.issues; return acc; }, {});
let total = 0;
for (const f of Object.keys(byFile)) total += byFile[f].length;
function inlineCode(s) {
if (s == null) return "";
return String(s).replace(/`/g, "\\`").replace(/\n/g, " ").trim();
}
function shortContext(text, maxLen=220) {
const t = (text || "").replace(/\s+/g, " ").trim();
if (t.length <= maxLen) return t;
return t.slice(0, maxLen - 1) + "…";
}
let body =
`${marker}
## LanguageTool report
**Language:** \`${process.env.LT_LANGUAGE || "en-US"}\`
**Checked files:** ${checkedFiles.length}
**Findings:** ${total}
`;
if (!checkedFiles.length) {
body += `\nNo supported text files changed in this PR (based on configured extensions).\n`;
} else if (total === 0) {
body += `\n✅ No issues found in the changed text files.\n`;
} else {
body += `\n---\n`;
for (const [file, issues] of Object.entries(byFile)) {
body += `\n<details>\n<summary><strong>${file}</strong> — ${issues.length} finding(s)</summary>\n\n`;
for (const it of issues.slice(0, 200)) {
const found = inlineCode(it.bad);
const ctx = shortContext(it.context);
const sug = (it.replacements && it.replacements.length)
? `Suggested: ${it.replacements.map(s => `\`${inlineCode(s)}\``).join(", ")}\n`
: "";
body +=
`- **${inlineCode(it.rule || "RULE")}**: ${inlineCode(it.message)}
- Found: \`${found}\`
- ${sug ? sug.trimEnd() : "Suggested: (none)"}
- Context: ${ctx ? `> ${ctx}` : "(none)"}
`;
}
if (issues.length > 200) body += `…(${issues.length - 200} more in this file)\n\n`;
body += `</details>\n`;
}
}
fs.writeFileSync("comment.md", body.trim() + "\n");
NODE
- name: Post or update PR comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = context.payload.pull_request.number;
const body = fs.readFileSync('comment.md', 'utf8');
const marker = '<!-- languagetool-report -->';
const { data: comments } = await github.rest.issues.listComments({
owner, repo, issue_number, per_page: 100
});
const existing = comments.find(c => (c.body || '').includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner, repo, comment_id: existing.id, body
});
} else {
await github.rest.issues.createComment({
owner, repo, issue_number, body
});
}
- name: Remove rerun label
if: github.event.action == 'labeled' && github.event.label.name == 'languagetool:rerun'
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
name: process.env.RERUN_LABEL,
});