Skip to content

Commit 4d3a5fe

Browse files
committed
Merging schedule
2 parents 612db99 + d473941 commit 4d3a5fe

File tree

14 files changed

+839
-9
lines changed

14 files changed

+839
-9
lines changed

.github/workflows/spelling.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
name: Spell checking
2-
on: [pull_request, push]
2+
on:
3+
schedule:
4+
# * is a special character in YAML so you have to quote this string
5+
- cron: '15 * * * *'
6+
push:
7+
branches:
8+
- schedule
39

410
jobs:
511
build:
@@ -9,12 +15,9 @@ jobs:
915
- uses: actions/[email protected]
1016
with:
1117
fetch-depth: 0
12-
- uses: actions/[email protected]
13-
with:
14-
path: .git/spell-check
15-
ref: spelling-data-lorem
16-
- uses: check-spelling/[email protected]
18+
- uses: ./
1719
env:
18-
bucket: .git
19-
project: spell-check
20+
bucket: ssh://[email protected]/check-spelling/examples-testing.git
21+
project: spelling-data-schedule
2022
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23+
DEBUG: 1

Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM debian:9.5-slim
2+
3+
RUN\
4+
DEBIAN_FRONTEND=noninteractive apt-get -qq update < /dev/null > /dev/null &&\
5+
DEBIAN_FRONTEND=noninteractive apt-get install -qq curl git jq < /dev/null > /dev/null
6+
7+
WORKDIR /app
8+
COPY \
9+
check-pull-requests.sh \
10+
docker-setup.sh \
11+
exclude.pl \
12+
porcelain.pl \
13+
reporter.json \
14+
reporter.pl \
15+
spelling-unknown-word-splitter.pl \
16+
unknown-words.sh \
17+
./
18+
19+
RUN ./docker-setup.sh &&\
20+
rm docker-setup.sh
21+
22+
LABEL "com.github.actions.name"="Spell Checker"\
23+
"com.github.actions.description"="Check repository for spelling errors"\
24+
"com.github.actions.icon"="edit-3"\
25+
"com.github.actions.color"="red"\
26+
"repository"="http://github.com/jsoref/spelling-action"\
27+
"homepage"="http://github.com/jsoref/spelling-action/tree/master/README.md"\
28+
"maintainer"="Josh Soref <[email protected]>"
29+
30+
ENTRYPOINT ["/app/unknown-words.sh"]

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
## Sample document
1+
## Examples repository
2+
3+
This repository is designed to show examples of how to use check-spelling
24

35
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
46
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

api-notes.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
https://developer.github.com/v3/pulls/#list-pull-requests
2+
Accept: application/vnd.github.shadow-cat-preview+json
3+
GET /repos/:owner/:repo/pulls
4+
{
5+
state: 'open',
6+
sort: 'updated'
7+
}
8+
9+
=>
10+
11+
[
12+
{
13+
"url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
14+
...
15+
"review_comments_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347/comments",
16+
...
17+
"comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments",
18+
...
19+
"updated_at": "2011-01-26T19:01:12Z",
20+
...
21+
"merge_commit_sha": "e5bd3914e2e596debea16f433f57875b5b90bcd6",
22+
...
23+
"head": {
24+
...
25+
"ref": "new-topic",
26+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
27+
...
28+
},
29+
"base": {
30+
"label": "octocat:master",
31+
"ref": "master",
32+
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
33+
...
34+
},
35+
},
36+
...
37+
]

check-pull-requests.sh

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/bin/bash
2+
if [ -n "$DEBUG" ]; then
3+
set -x
4+
fi
5+
if [ $(uname) = "Linux" ]; then
6+
date_to_epoch() {
7+
date -u -d "$1" +'%s'
8+
}
9+
else
10+
date_to_epoch() {
11+
date -u -j -f '%Y-%m-%dT%H:%M:%SZ' "$1" +'%s'
12+
}
13+
fi
14+
timeframe=${timeframe:-60}
15+
time_limit=$(( $timeframe * 60 ))
16+
strip_quotes() {
17+
tr '"' ' '
18+
}
19+
now() {
20+
date +'%s'
21+
}
22+
start=$(now)
23+
24+
pulls=$temp/pulls.json
25+
escaped=$temp/escaped.b64
26+
pull=$temp/pull.json
27+
fake_event=$temp/fake_event.json
28+
headers=$temp/headers
29+
30+
if [ -e "$pulls" ]; then
31+
echo using cached $pulls
32+
else
33+
curl -s -s -H "Authorization: token $GITHUB_TOKEN" --header "Content-Type: application/json" -H "Accept: application/vnd.github.shadow-cat-preview+json" https://api.github.com/repos/check-spelling/examples-testing/pulls > $pulls
34+
fi
35+
cat "$pulls" | jq -c '.[]'|jq -c -r '{
36+
head_repo : .head.repo.full_name,
37+
base_repo: .base.repo.full_name,
38+
head_ref: .head.ref,
39+
head_sha: .head.sha,
40+
base_sha: .base.sha,
41+
clone_url: .head.repo.clone_url,
42+
merge_commit_sha: .merge_commit_sha,
43+
created_at: .created_at,
44+
issue_url: .issue_url,
45+
commits_url: .commits_url,
46+
comments_url: .comments_url
47+
} | @base64' > "$escaped"
48+
49+
get_created_from_events() {
50+
rm -f "$headers"
51+
created_at=$(curl -s -S \
52+
-H "Authorization: token $GITHUB_TOKEN" \
53+
--header "Content-Type: application/json" \
54+
-D "$headers" \
55+
"$1" |
56+
jq -M -r '[ .[]|select (.event=="head_ref_force_pushed") ][-1].created_at')
57+
if [ "$created_at" = "null" ]; then
58+
created_time=0
59+
else
60+
created_time=$(date_to_epoch $created_at)
61+
fi
62+
if [ -e "$headers" ]; then
63+
next_url=$(perl -ne 'next unless s/^Link: //;s/,\s+/\n/g; print "$1" if /<(.*)>; rel="last"/' $headers)
64+
rm -f "$headers"
65+
if [ -n "$next_url" ]; then
66+
other_time=$(get_created_from_events "$next_url")
67+
if [ "$created_time" -lt "$other_time" ]; then
68+
created_time=$other_time
69+
fi
70+
fi
71+
fi
72+
echo "$created_time"
73+
}
74+
75+
for a in $(cat "$escaped"); do
76+
echo "$a" | base64 --decode | jq -r . > $pull
77+
issue_url=$(cat $pull | jq -r .issue_url)
78+
created_at=$(get_created_from_events "${issue_url}/events")
79+
if [ "$created_at" -eq 0 ]; then
80+
created_at=$(date_to_epoch $(cat $pull | jq -r .created_at))
81+
fi
82+
age=$(( $start - $created_at ))
83+
if [ $age -gt $time_limit ]; then
84+
continue
85+
fi
86+
head_repo=$(cat $pull | jq -r .head_repo)
87+
base_repo=$(cat $pull | jq -r .base_repo)
88+
if [ "$head_repo" = "$base_repo" ]; then
89+
continue
90+
fi
91+
head_sha=$(cat $pull | jq -r .head_sha)
92+
base_sha=$(cat $pull | jq -r .base_sha)
93+
merge_commit_sha=$(cat $pull | jq -r .merge_commit_sha)
94+
comments_url=$(cat $pull | jq -r .comments_url)
95+
commits_url=$(cat $pull | jq -r .commits_url)
96+
clone_url=$(cat $pull | jq -r .clone_url)
97+
clone_url=$(echo "$clone_url" | sed -e 's/https/http/')
98+
head_ref=$(cat $pull | jq -r .head_ref)
99+
echo "do work for $head_repo -> $base_repo: $head_sha as $merge_commit_sha"
100+
export GITHUB_SHA="$head_sha"
101+
export GITHUB_EVENT_NAME=pull_request
102+
echo '{}' | jq \
103+
--arg head_sha "$head_sha" \
104+
--arg base_sha "$base_sha" \
105+
--arg comments_url "$comments_url" \
106+
--arg commits_url "$commits_url" \
107+
-r '{pull_request: {base: {sha: $base_sha}, head: {sha: $head_sha}, comments_url: $comments_url, commits_url: $commits_url }}' \
108+
> "$fake_event"
109+
export GITHUB_EVENT_PATH="$fake_event"
110+
git remote rm pr 2>/dev/null || true
111+
git remote add pr $clone_url
112+
cat .git/config
113+
git fetch pr $head_ref
114+
git checkout $head_sha
115+
git remote rm pr 2>/dev/null || true
116+
"$spellchecker/unknown-words.sh" || true
117+
done

docker-setup.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
# This CI acceptance test is based on:
3+
# https://github.com/jsoref/spelling/tree/04648bdc63723e5cdf5cbeaff2225a462807abc8
4+
# It is conceptually `f` which runs `w` (spelling-unknown-word-splitter)
5+
# plus `fchurn` which uses `dn` mostly rolled together.
6+
set -e
7+
8+
spellchecker='/app'
9+
w_location="$spellchecker/w"
10+
temp='/tmp/spelling'
11+
dict="$spellchecker/words"
12+
word_splitter="$spellchecker/spelling-unknown-word-splitter.pl"
13+
run_output="$spellchecker/unknown.words.txt"
14+
15+
wordlist=https://github.com/check-spelling/check-spelling/raw/dictionary/dict.txt
16+
17+
mkdir -p "$temp"
18+
if [ ! -e "$dict" ]; then
19+
echo "Retrieving cached $(basename "$wordlist")"
20+
# english.words is taken from rpm:
21+
# https://rpmfind.net/linux/fedora/linux/development/rawhide/Everything/aarch64/os/Packages/w/"
22+
# "words-.*.noarch.rpm"
23+
(
24+
curl -L -s "$wordlist" -o "$dict"
25+
) >/dev/null 2>/dev/null
26+
fi

exclude.pl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/perl
2+
# This script takes null delimited files as input
3+
# it drops paths that match the listed exclusions
4+
# output is null delimited to match input
5+
use File::Basename;
6+
my $exclude_file;
7+
if (defined $ENV{exclude_file}) {
8+
$exclude_file=$ENV{exclude_file};
9+
} else {
10+
my $dirname = dirname(__FILE__);
11+
$exclude_file = $dirname.'/excludes.txt';
12+
}
13+
my @excludes;
14+
15+
if (-e $exclude_file) {
16+
open EXCLUDES, '<', $exclude_file;
17+
while (<EXCLUDES>) {
18+
s/^\s*(.*)\s*$/$1/;
19+
push @excludes, $_;
20+
}
21+
}
22+
$/="\0";
23+
my $exclude = scalar @excludes ? join "|", @excludes : '^$';
24+
while (<>) {
25+
chomp;
26+
next if m{$exclude};
27+
print "$_$/";
28+
}

porcelain.pl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env perl
2+
3+
my $head=$ENV{HEAD};
4+
my $file=$ARGV[0];
5+
open LOG, qq<git log --oneline -s --no-abbrev-commit -1 "$head" -- "$file"|>;
6+
my $sha;
7+
while (<LOG>) {
8+
s/\s.*$//;
9+
$sha=$_;
10+
}
11+
chomp $sha;
12+
$head = $sha;
13+
close LOG;
14+
my $state=0;
15+
my ($sha, $orig, $cur, $length);
16+
open BLAME, qq<git blame -b -f -s -p "$head" -- "$file"|>;
17+
while (<BLAME>) {
18+
if ($state == 0) {
19+
/([0-9a-f]{40,}) (\d+) (\d+)(?: (\d+)|)/;
20+
($sha, $orig, $cur, $length) = ($1, $2, $3, $4);
21+
++$state;
22+
} elsif ($state == 1) {
23+
if (s/^\t//) {
24+
$state = 0;
25+
if ($sha eq $head) {
26+
print "$head $file $cur) $_";
27+
}
28+
}
29+
}
30+
}
31+
close BLAME;

pr-events.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## PR Events
2+
3+
GitHub Actions will fire for PRs ([pull_request](https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request)),
4+
but [Pull request events for forked
5+
repositories](https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-events-for-forked-repositories)
6+
7+
> When you create a pull request from a forked repository to the base repository,
8+
> GitHub sends the `pull_request` event to the base repository and no pull request events occur on the forked repository.
9+
10+
> Workflows don't run on forked repositories by default. You must enable GitHub Actions in the Actions tab of the forked repository.
11+
12+
> The permissions for the `GITHUB_TOKEN` in forked repositories is read-only.
13+
> For more information about the `GITHUB_TOKEN`, see "[Virtual environments for GitHub
14+
Actions](https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners)."
15+
16+
### In English
17+
18+
1. Commits in forked repositories won't have run the hook, which means they may have spelling errors.
19+
1. When the PR is created in this repository, it won't have permission to comment, which means you won't be able to see the cool PR comment.
20+
21+
## Proposed strategy to address this
22+
23+
Instead of relying on a PR event,
24+
I'm going to try to run a `schedule` event which looks for PRs from foreign repositories which have been updated since the last time the event was run.
25+
And that event will run the spell checker and then comment on the PR.

reporter.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"problemMatcher": [
3+
{
4+
"owner": "jsoref-spelling",
5+
"pattern": [
6+
{
7+
"regexp": "^(.+):[\\s]line\\s(\\d+),[\\s]columns\\s(\\d+)-(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$",
8+
"file": 1,
9+
"line": 2,
10+
"column": 3,
11+
"endColumn": 4,
12+
"severity": 5,
13+
"message": 6,
14+
"code": 7
15+
}
16+
]
17+
}
18+
]
19+
}
20+

0 commit comments

Comments
 (0)