Skip to content
Merged
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
64 changes: 64 additions & 0 deletions .github/scripts/common.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
export async function hidePriorCommentsWithPrefix({
github, // injected by GitHub
context, // injected by GitHub
exec, // injected by GitHub
prefix = '',
resolved = true,
user = 'github-actions[bot]',
}) {
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
for (const comment of comments.data) {
const isHidden = (await github.graphql(`
query($nodeId: ID!) {
node(id: $nodeId) {
... on IssueComment {
isMinimized
}
}
}
`, { nodeId: comment.node_id }))?.node?.isMinimized;
await exec.exec('sleep 0.5s');
if (isHidden) { continue; }
if (
comment.user.login === user &&
comment.body.startsWith(prefix)
) {
console.log('Comment node_id:', comment.node_id);
console.log(await github.graphql(`
mutation($subjectId: ID!, $classifier: ReportedContentClassifiers!) {
minimizeComment(input: {
subjectId: $subjectId,
classifier: $classifier
}) {
minimizedComment {
isMinimized
minimizedReason
}
}
}
`, {
subjectId: comment.node_id,
classifier: resolved ? 'RESOLVED' : 'OUTDATED',
}));
await exec.exec('sleep 0.5s');
}
}
}

export async function createComment({
github, // injected by GitHub
context, // injected by GitHub
exec, // injected by GitHub
body = '',
}) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body,
});
}
97 changes: 66 additions & 31 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ on:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.ref }}-linter
cancel-in-progress: true

permissions:
contents: read
pull-requests: write
issues: write
# issues: write

jobs:
format-check:
Expand Down Expand Up @@ -46,41 +46,76 @@ jobs:
files: |
**.md
**.mdx
separator: ":"

- name: Check formatting of MDX and Markdown files
id: check-fmt
env:
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
if [ -z $(echo -e "${ALL_CHANGED_FILES[@]}" | tr -d '[:space:]') ]; then
echo -e '\nNo such files affected!'
exit 0
fi
echo -e '\nChecking formatting of the following MDX and Markdown files affected by this PR:\n'
for file in ${ALL_CHANGED_FILES}; do
echo "- $file"
done
echo
npx remark --no-stdout --quiet --frail --silently-ignore $(echo -e "${ALL_CHANGED_FILES[@]}" | tr '\n' ' ')

- name: ${{ steps.check-fmt.conclusion == 'failure' && '👀 How to fix the formatting? See these suggestions!' || '...' }}
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
const files = (process.env.ALL_CHANGED_FILES ?? '').trim().split(':').filter(Boolean);
if (files.length === 0) {
console.log('\nNo such files affected!');
process.exit(0);
}
console.log('\nChecking formatting of the following MDX and Markdown files affected by this PR:\n');
for (const file of files) {
console.log(`- ${file}`);
}
const filesQuoted = files.map((it) => '"' + it + '"');
try {
await exec.exec('npm', ['run', 'check:fmt:some', '--', ...filesQuoted], {
silent: true, // >/dev/null 2>&1
});
} catch (_) {
// Comment right in the actions output
const filesJoined = filesQuoted.join(' ');
console.log('\n\x1b[31mError:\x1b[0m Some files are not properly formatted!');
console.log('1. Install necessary dependencies: \x1b[31mnpm ci\x1b[0m');
console.log(`2. Run this command to fix the issues: \x1b[31mnpm run fmt:some -- ${filesJoined}\x1b[0m`);

// Prepare a comment on the PR
const comment = [
'To fix the **formatting** issues:\n',
'1. Install necessary dependencises: `npm ci`',
'2. Then, run this command:',
'```shell',
`npm run fmt:some -- ${filesJoined}`,
'```',
].join('\n');

// Set environment variable for subsequent steps
core.exportVariable('COMMENT', comment);

// Rethrow the exit code of the failed formatting check
core.setFailed('Some files are not properly formatted!');
process.exit(1);
}

- name: Hide prior PR comments and issue a new one in case of failure
if: ${{ !cancelled() && github.event_name == 'pull_request' && github.event_name != 'pull_request_target' }}
env:
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
if: failure()
run: |
# Preparations
FILES="$(echo -e "${ALL_CHANGED_FILES[@]}" | tr '\n' ' ')"
BODY="{\"body\":\"To fix the **formatting** issues:\n\n1. Install necessary dependencies: \`npm ci\`\n2. Then, run this command:\n\`\`\`shell\nnpx remark -o --silent --silently-ignore ${FILES}\n\`\`\`\"}"
# Comment on the PR
curl -s -o /dev/null -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-d "$BODY" \
https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.number }}/comments
# Comment right in the actions output
echo -e "\nInstall necessary dependencies: \033[31mnpm ci\033[0m"
echo -e "Then, run this to fix formatting: \033[31mnpx remark -o --silent --silently-ignore ${FILES}\033[0m"
COMMENT: ${{ env.COMMENT }}
SUCCESS: ${{ steps.check-fmt.conclusion == 'failure' && 'false' || 'true' }}
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
const { hidePriorCommentsWithPrefix, createComment } = await import('${{ github.workspace }}/.github/scripts/common.mjs');
const success = JSON.parse(process.env.SUCCESS ?? 'false');
const rawCommentText = process.env.COMMENT ?? '';
if (!success && rawCommentText === '') {
console.log('There was a formatting error, but no comment was given, skipping...');
process.exit(0);
}
const prefix = rawCommentText.slice(1, 30);
await hidePriorCommentsWithPrefix({ github, context, exec, prefix, resolved: success });
// Create a new comment in case of a new failure
if (!success) {
const body = rawCommentText.slice(1, -1).replace(/\\n/g, '\n');
await createComment({ github, context, exec, body });
}

spell-check:
name: "Spelling"
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
"check:navigation": "node scripts/check-navigation.mjs",
"check:fs": "echo 'https://github.com/ton-org/docs/issues/1182'",
"check:fmt": "remark . -e mdx,md --no-stdout --quiet --frail",
"check:fmt:some": "remark --no-stdout --quiet --frail --silently-ignore",
"check:spell": "cspell --no-progress --show-suggestions .",
"check:all": "npm run check:openapi && npm run check:links && npm run check:redirects && npm run check:fs && npm run check:fmt && npm run check:spell",
"fmt": "remark . -e mdx,md -o --silent",
"fmt:some": "remark -o --silent",
"fmt:some": "remark -o --silent --silently-ignore",
"spell": "cspell lint --no-progress --show-suggestions .",
"spell:some": "cspell lint",
"lint:all": "npm run check:all",
Expand Down