Skip to content

Commit

Permalink
ci: validate issue title on create and update (#1070)
Browse files Browse the repository at this point in the history
  • Loading branch information
seia-soto authored Jan 9, 2025
1 parent 25a90b4 commit c4cf073
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 2 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/validate-issue-title.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Validate issue title

on:
issues:
types: [opened, edited]
workflow_dispatch:

jobs:
validate-and-label:
runs-on: ubuntu-latest
name: Validate issue title
permissions:
issues: write
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- name: Validate issue title
env:
NAME: ${{ github.event.issue.title }}
run: |
deno install
{
echo 'VALERR<<EOF'
echo "$(deno run './src/validate-issue-title.ts' "${name}" 2>&1 >/dev/null)"
echo EOF
} >> "$GITHUB_ENV"
- name: In case of an invalid issue title, comment about the error and label the issue
if: ${{ env.VALERR != '' && contains(github.event.issue.labels.*.name, 'checks/invalid-issue-title') != true }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
VALERR: ${{ env.VALERR }}
run: |
gh issue comment "${NUMBER}" --body "$(cat <<EOF
❌ The issue title is not properly formatted:
\`\`\`
${VALERR}
\`\`\`
EOF
)"
gh issue edit "${NUMBER}" --add-label 'checks/invalid-issue-title'
- name: In case of a valid issue title with an invalid label, remove the label from the issue
if: ${{ env.VALERR == '' && contains(github.event.issue.labels.*.name, 'checks/invalid-issue-title') == true }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
run: >
gh issue edit "${NUMBER}" --remove-label 'checks/invalid-issue-title'
3 changes: 3 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
"build": "deno run -R -W ./src/build.js",
"lint": "deno fmt --check ./src ./test",
"tests": "deno test --allow-read"
},
"imports": {
"tldts": "npm:tldts@^6.1.71"
}
}
20 changes: 18 additions & 2 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions src/validate-issue-title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as process from "node:process";
import { parse } from "npm:tldts";

// Convert decimal notation of ip address into 32 bit unsigned integer
function addr(decimalNotation: string): number {
return decimalNotation.split(".").reduce(
(state, part, index) => state | (parseInt(part, 10) << ((3 - index) * 8)),
0,
) >>> 0;
}

const title = process.argv.slice(2)[0];

if (/[A-Z]/.test(title)) {
console.error("Given string includes an upper-case character!");
process.exit(1);
}

const parsed = parse(title);

if (parsed.hostname === null) {
console.error("Given string is not a valid domain name or IP address!");
process.exit(1);
}

if (parsed.hostname !== title) {
console.error("Given string is not a pure hostname!");
process.exit(1);
}

if (parsed.isIp) {
const ip = addr(title);

// https://datatracker.ietf.org/doc/html/rfc1918#section-3
if (
(ip >= addr("10.0.0.0") && ip <= addr("10.255.255.255")) ||
(ip >= addr("172.16.0.0") && ip <= addr("172.31.255.255")) ||
(ip >= addr("192.168.0.0") && ip <= addr("192.168.255.255"))
) {
console.error("IP address is not in the public address space!");
process.exit(1);
}
} else if (!parsed.isIcann) {
console.error("TLD is not registered to ICANN list!");
process.exit(1);
}

0 comments on commit c4cf073

Please sign in to comment.