Skip to content

Commit d75736a

Browse files
per1234umbynos
andcommitted
Add infrastructure for checking project filesystem
There are differences in the filename restrictions between operating systems. The use of filenames that are not valid one one operating system in the project will cause problems for contributors or users (e.g., not possible to check out the repository). Tasks are added to check for non-portable filenames: - Presence of characters prohibited by an operating system in filenames - Use of filenames reserved by an operating system Tasks are also added to check for problems with symbolic links ("symlinks") contained in the project: - Broken symlinks - Circular symlinks A GitHub Actions workflow is included to run the tasks on any change to the project files in order to avoid the introduction of problems with the project filesystem, and periodically in order to catch breakage caused by external changes. Co-authored-by: Umberto Baldi <[email protected]>
1 parent 627ce9e commit d75736a

File tree

6 files changed

+429
-0
lines changed

6 files changed

+429
-0
lines changed

Diff for: .github/workflows/check-files-task.yml

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-files-task.md
2+
name: Check Files
3+
4+
# See: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows
5+
on:
6+
create:
7+
push:
8+
pull_request:
9+
schedule:
10+
# Run periodically to catch breakage caused by external changes.
11+
- cron: "0 8 * * THU"
12+
workflow_dispatch:
13+
repository_dispatch:
14+
15+
jobs:
16+
run-determination:
17+
runs-on: ubuntu-latest
18+
outputs:
19+
result: ${{ steps.determination.outputs.result }}
20+
steps:
21+
- name: Determine if the rest of the workflow should run
22+
id: determination
23+
run: |
24+
RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x"
25+
# The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead.
26+
if [[
27+
"${{ github.event_name }}" != "create" ||
28+
"${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX
29+
]]; then
30+
# Run the other jobs.
31+
RESULT="true"
32+
else
33+
# There is no need to run the other jobs.
34+
RESULT="false"
35+
fi
36+
37+
echo "result=$RESULT" >> $GITHUB_OUTPUT
38+
39+
check-filenames:
40+
needs: run-determination
41+
if: needs.run-determination.outputs.result == 'true'
42+
runs-on: ubuntu-latest
43+
44+
steps:
45+
- name: Checkout repository
46+
uses: actions/checkout@v3
47+
48+
- name: Install Task
49+
uses: arduino/setup-task@v1
50+
with:
51+
repo-token: ${{ secrets.GITHUB_TOKEN }}
52+
version: 3.x
53+
54+
- name: Check filenames
55+
run: task --silent general:check-filenames
56+
57+
check-symlinks:
58+
needs: run-determination
59+
if: needs.run-determination.outputs.result == 'true'
60+
runs-on: ubuntu-latest
61+
62+
steps:
63+
- name: Checkout repository
64+
uses: actions/checkout@v3
65+
66+
- name: Install Task
67+
uses: arduino/setup-task@v1
68+
with:
69+
repo-token: ${{ secrets.GITHUB_TOKEN }}
70+
version: 3.x
71+
72+
- name: Check symlinks
73+
run: task --silent general:check-symlinks

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
[![Check ClangFormat Configuration status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-clang-format.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-clang-format.yml)
44
[![Check Dependabot Configuration status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-dependabot.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-dependabot.yml)
55
[![Check ESLint Configuration status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-eslint.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-eslint.yml)
6+
[![Check Files status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-files-task.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-files-task.yml)
67
[![Check Issue Templates status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-issue-templates.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-issue-templates.yml)
78
[![Check JavaScript status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-javascript-task.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-javascript-task.yml)
89
[![Check Label Configuration status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-labels.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-labels.yml)

Diff for: Taskfile.yml

+97
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,76 @@ tasks:
401401
-s "{{.SCHEMA_PATH}}" \
402402
-d "{{.PROJECT_FOLDER}}/{{.DATA_PATH}}"
403403
404+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-files-task/Taskfile.yml
405+
general:check-filenames:
406+
desc: Check for non-portable filenames
407+
cmds:
408+
- |
409+
find . \
410+
-type d -name '.git' -prune -o \
411+
-type d -name '.licenses' -prune -o \
412+
-type d -name '__pycache__' -prune -o \
413+
-type d -name 'node_modules' -prune -o \
414+
-exec \
415+
sh \
416+
-c \
417+
' \
418+
basename "$0" | \
419+
grep \
420+
--perl-regexp \
421+
--regexp='"'"'([<>:"/\\|?*\x{0000}-\x{001F}])|(.+\.$)'"'"' \
422+
--silent \
423+
&& \
424+
echo "$0"
425+
' \
426+
'{}' \
427+
\; \
428+
-execdir \
429+
false \
430+
'{}' \
431+
+ \
432+
|| \
433+
{
434+
echo
435+
echo "Prohibited characters found in filenames"
436+
echo "See:"
437+
echo "https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions:~:text=except%20for%20the%20following"
438+
false
439+
}
440+
- |
441+
find . \
442+
-type d -name '.git' -prune -o \
443+
-type d -name '.licenses' -prune -o \
444+
-type d -name '__pycache__' -prune -o \
445+
-type d -name 'node_modules' -prune -o \
446+
-exec \
447+
sh \
448+
-c \
449+
' \
450+
basename "$0" | \
451+
grep \
452+
--ignore-case \
453+
--extended-regexp \
454+
--regexp='"'"'^(con|prn|aux|nul|com[0-9]+|lpt[0-9]+)$'"'"' \
455+
--silent \
456+
&& \
457+
echo "$0"
458+
' \
459+
'{}' \
460+
\; \
461+
-execdir \
462+
false \
463+
'{}' \
464+
+ \
465+
|| \
466+
{
467+
echo
468+
echo "Reserved filenames found"
469+
echo "See:"
470+
echo "https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions:~:text=use%20the%20following-,reserved%20names,-for%20the%20name"
471+
false
472+
}
473+
404474
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-general-formatting-task/Taskfile.yml
405475
general:check-formatting:
406476
desc: Check basic formatting style of all files
@@ -420,6 +490,33 @@ tasks:
420490
cmds:
421491
- poetry run codespell
422492

493+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-files-task/Taskfile.yml
494+
general:check-symlinks:
495+
desc: Check for bad symlinks
496+
cmds:
497+
- |
498+
find . \
499+
-type d -name '.git' -prune -o \
500+
-type d -name '.licenses' -prune -o \
501+
-type d -name '__pycache__' -prune -o \
502+
-type d -name 'node_modules' -prune -o \
503+
-type l \
504+
-execdir \
505+
test ! -e '{}' \
506+
\; \
507+
-exec \
508+
echo '{}' \
509+
\; \
510+
-execdir \
511+
false \
512+
'{}' \
513+
+ \
514+
|| \
515+
{
516+
echo 'Broken or circular symlink found'
517+
false
518+
}
519+
423520
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check-task/Taskfile.yml
424521
general:correct-spelling:
425522
desc: Correct commonly misspelled words where possible
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# See: https://taskfile.dev/#/usage
2+
version: "3"
3+
4+
tasks:
5+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-files-task/Taskfile.yml
6+
general:check-filenames:
7+
desc: Check for non-portable filenames
8+
cmds:
9+
- |
10+
find . \
11+
-type d -name '.git' -prune -o \
12+
-type d -name '.licenses' -prune -o \
13+
-type d -name '__pycache__' -prune -o \
14+
-type d -name 'node_modules' -prune -o \
15+
-exec \
16+
sh \
17+
-c \
18+
' \
19+
basename "$0" | \
20+
grep \
21+
--perl-regexp \
22+
--regexp='"'"'([<>:"/\\|?*\x{0000}-\x{001F}])|(.+\.$)'"'"' \
23+
--silent \
24+
&& \
25+
echo "$0"
26+
' \
27+
'{}' \
28+
\; \
29+
-execdir \
30+
false \
31+
'{}' \
32+
+ \
33+
|| \
34+
{
35+
echo
36+
echo "Prohibited characters found in filenames"
37+
echo "See:"
38+
echo "https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions:~:text=except%20for%20the%20following"
39+
false
40+
}
41+
- |
42+
find . \
43+
-type d -name '.git' -prune -o \
44+
-type d -name '.licenses' -prune -o \
45+
-type d -name '__pycache__' -prune -o \
46+
-type d -name 'node_modules' -prune -o \
47+
-exec \
48+
sh \
49+
-c \
50+
' \
51+
basename "$0" | \
52+
grep \
53+
--ignore-case \
54+
--extended-regexp \
55+
--regexp='"'"'^(con|prn|aux|nul|com[0-9]+|lpt[0-9]+)$'"'"' \
56+
--silent \
57+
&& \
58+
echo "$0"
59+
' \
60+
'{}' \
61+
\; \
62+
-execdir \
63+
false \
64+
'{}' \
65+
+ \
66+
|| \
67+
{
68+
echo
69+
echo "Reserved filenames found"
70+
echo "See:"
71+
echo "https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions:~:text=use%20the%20following-,reserved%20names,-for%20the%20name"
72+
false
73+
}
74+
75+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-files-task/Taskfile.yml
76+
general:check-symlinks:
77+
desc: Check for bad symlinks
78+
cmds:
79+
- |
80+
find . \
81+
-type d -name '.git' -prune -o \
82+
-type d -name '.licenses' -prune -o \
83+
-type d -name '__pycache__' -prune -o \
84+
-type d -name 'node_modules' -prune -o \
85+
-type l \
86+
-execdir \
87+
test ! -e '{}' \
88+
\; \
89+
-exec \
90+
echo '{}' \
91+
\; \
92+
-execdir \
93+
false \
94+
'{}' \
95+
+ \
96+
|| \
97+
{
98+
echo 'Broken or circular symlink found'
99+
false
100+
}

Diff for: workflow-templates/check-files-task.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# "Check Files" (Task)
2+
3+
Infrastructure for checking the project's filesystem.
4+
5+
[Tasks](https://taskfile.dev/) are provided to check for filesystem problems with the project content:
6+
7+
- Presence of characters prohibited by an operating system in filenames
8+
- Use of filenames reserved by an operating system
9+
- Broken symlinks
10+
- Circular symlinks
11+
12+
A GitHub Actions workflow is included to run the tasks on any change to the project files, and periodically.
13+
14+
## Installation
15+
16+
### Workflow
17+
18+
Install the [`check-files-task.yml`](check-files-task.yml) GitHub Actions workflow to `.github/workflows/`
19+
20+
### Assets
21+
22+
- [`Taskfile.yml`](assets/check-files-task/Taskfile.yml) - file check [tasks](https://taskfile.dev/).
23+
- Install to: repository root (or merge into the existing `Taskfile.yml`).
24+
25+
### Readme badge
26+
27+
Markdown badge:
28+
29+
```markdown
30+
[![Check Files status](https://github.com/TODO_REPO_OWNER/TODO_REPO_NAME/actions/workflows/check-files-task.yml/badge.svg)](https://github.com/TODO_REPO_OWNER/TODO_REPO_NAME/actions/workflows/check-files-task.yml)
31+
```
32+
33+
Replace the `TODO_REPO_OWNER` and `TODO_REPO_NAME` placeholders in the URLs with the final repository owner and name ([example](https://raw.githubusercontent.com/arduino-libraries/ArduinoIoTCloud/master/README.md)).
34+
35+
---
36+
37+
Asciidoc badge:
38+
39+
```adoc
40+
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-files-task.yml/badge.svg["Check Files status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-files-task.yml"]
41+
```
42+
43+
Define the `{repository-owner}` and `{repository-name}` attributes and use them throughout the readme ([example](https://raw.githubusercontent.com/arduino-libraries/WiFiNINA/master/README.adoc)).
44+
45+
## Commit message
46+
47+
```text
48+
Add infrastructure for checking project filesystem
49+
50+
There are differences in the filename restrictions between operating systems. The use of filenames that are not valid
51+
on one operating system in the project will cause problems for contributors or users (e.g., not possible to check out
52+
the repository).
53+
54+
Tasks are added to check for non-portable filenames:
55+
56+
- Presence of characters prohibited by an operating system in filenames
57+
- Use of filenames reserved by an operating system
58+
59+
Tasks are also added to check for problems with symbolic links ("symlinks") contained in the project:
60+
61+
- Broken symlinks
62+
- Circular symlinks
63+
64+
A GitHub Actions workflow is included to run the tasks on any change to the project files in order to avoid the
65+
introduction of problems with the project filesystem, and periodically in order to catch breakage caused by external
66+
changes.
67+
```
68+
69+
## PR message
70+
71+
```markdown
72+
There are differences in the filename restrictions between operating systems. The use of filenames that are not valid on one operating system in the project will cause problems for contributors or users (e.g., not possible to check out the repository).
73+
74+
Tasks are added to check for non-portable filenames:
75+
76+
- Presence of characters prohibited by an operating system in filenames
77+
- Use of filenames reserved by an operating system
78+
79+
Tasks are also added to check for problems with symbolic links ("symlinks") contained in the project:
80+
81+
- Broken symlinks
82+
- Circular symlinks
83+
84+
A GitHub Actions workflow is included to run the tasks on any change to the project files in order to avoid the introduction of problems with the project filesystem, and periodically in order to catch breakage caused by external changes.
85+
```

0 commit comments

Comments
 (0)