Seed from NAS prod snapshot 20260130-190531
This commit is contained in:
117
.gitea/workflows/auto-label-issues.yml
Normal file
117
.gitea/workflows/auto-label-issues.yml
Normal file
@@ -0,0 +1,117 @@
|
||||
name: Auto-label issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Apply labels from Type/State/Category
|
||||
env:
|
||||
FORGE_BASE: ${{ vars.FORGE_API || vars.FORGE_BASE }}
|
||||
FORGE_TOKEN: ${{ secrets.FORGE_TOKEN }}
|
||||
REPO_FULL: ${{ gitea.repository }}
|
||||
EVENT_PATH: ${{ github.event_path }}
|
||||
run: |
|
||||
python3 - <<'PY'
|
||||
import json, os, re, urllib.request, urllib.error
|
||||
|
||||
forge = os.environ["FORGE_BASE"].rstrip("/")
|
||||
token = os.environ["FORGE_TOKEN"]
|
||||
owner, repo = os.environ["REPO_FULL"].split("/", 1)
|
||||
event_path = os.environ["EVENT_PATH"]
|
||||
|
||||
with open(event_path, "r", encoding="utf-8") as f:
|
||||
ev = json.load(f)
|
||||
|
||||
issue = ev.get("issue") or {}
|
||||
title = issue.get("title") or ""
|
||||
body = issue.get("body") or ""
|
||||
number = issue.get("number") or issue.get("index")
|
||||
if not number:
|
||||
raise SystemExit("No issue number/index in event payload")
|
||||
|
||||
def pick_line(key: str) -> str:
|
||||
m = re.search(rf"^\s*{re.escape(key)}\s*:\s*([^\n\r]+)", body, flags=re.M)
|
||||
return m.group(1).strip() if m else ""
|
||||
|
||||
desired = set()
|
||||
|
||||
t = pick_line("Type")
|
||||
s = pick_line("State")
|
||||
c = pick_line("Category")
|
||||
|
||||
print("PARSED:", {"Type": t, "State": s, "Category": c})
|
||||
|
||||
# 1) explicite depuis le body
|
||||
if t:
|
||||
desired.add(t)
|
||||
if s:
|
||||
desired.add(s)
|
||||
if c:
|
||||
desired.add(c)
|
||||
|
||||
# 2) fallback depuis le titre si Type absent
|
||||
if not t:
|
||||
if title.startswith("[Correction]"):
|
||||
desired.add("type/correction")
|
||||
elif title.startswith("[Fact-check]") or title.startswith("[Vérification]"):
|
||||
desired.add("type/fact-check")
|
||||
|
||||
# 3) fallback State si absent
|
||||
if not s:
|
||||
if "type/fact-check" in desired:
|
||||
desired.add("state/a-sourcer")
|
||||
elif "type/correction" in desired:
|
||||
desired.add("state/recevable")
|
||||
|
||||
if not desired:
|
||||
print("No labels to apply.")
|
||||
raise SystemExit(0)
|
||||
|
||||
api = forge + "/api/v1"
|
||||
headers = {
|
||||
"Authorization": f"token {token}",
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "archicratie-auto-label/1.0",
|
||||
}
|
||||
|
||||
def jreq(method, url, payload=None):
|
||||
data = None if payload is None else json.dumps(payload).encode("utf-8")
|
||||
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=20) as r:
|
||||
b = r.read()
|
||||
return json.loads(b.decode("utf-8")) if b else None
|
||||
except urllib.error.HTTPError as e:
|
||||
b = e.read().decode("utf-8", errors="replace")
|
||||
raise RuntimeError(f"HTTP {e.code} {method} {url}\n{b}") from e
|
||||
|
||||
# labels repo
|
||||
labels = jreq("GET", f"{api}/repos/{owner}/{repo}/labels?limit=1000") or []
|
||||
name_to_id = {x.get("name"): x.get("id") for x in labels}
|
||||
|
||||
missing = [x for x in desired if x not in name_to_id]
|
||||
if missing:
|
||||
raise SystemExit("Missing labels in repo: " + ", ".join(sorted(missing)))
|
||||
|
||||
wanted_ids = [name_to_id[x] for x in desired]
|
||||
|
||||
# labels actuels de l'issue
|
||||
current = jreq("GET", f"{api}/repos/{owner}/{repo}/issues/{number}/labels") or []
|
||||
current_ids = {x.get("id") for x in current if x.get("id") is not None}
|
||||
|
||||
final_ids = sorted(current_ids.union(wanted_ids))
|
||||
|
||||
# set labels = union (n'enlève rien)
|
||||
url = f"{api}/repos/{owner}/{repo}/issues/{number}/labels"
|
||||
try:
|
||||
jreq("PUT", url, {"labels": final_ids})
|
||||
except Exception:
|
||||
jreq("PUT", url, final_ids)
|
||||
|
||||
print(f"OK labels #{number}: {sorted(desired)}")
|
||||
PY
|
||||
100
.gitea/workflows/ci.yaml
Normal file
100
.gitea/workflows/ci.yaml
Normal file
@@ -0,0 +1,100 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
NODE_OPTIONS: --dns-result-order=ipv4first
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build-and-anchors:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/devcontainers/javascript-node:22-bookworm
|
||||
|
||||
steps:
|
||||
- name: Tools sanity
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git --version
|
||||
node --version
|
||||
npm --version
|
||||
npm ping --registry=https://registry.npmjs.org
|
||||
|
||||
- name: Checkout (from event.json, no external actions)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
export EVENT_JSON="/var/run/act/workflow/event.json"
|
||||
test -f "$EVENT_JSON" || { echo "❌ Missing $EVENT_JSON"; exit 1; }
|
||||
|
||||
eval "$(node --input-type=module -e 'import fs from "node:fs";
|
||||
const ev = JSON.parse(fs.readFileSync(process.env.EVENT_JSON,"utf8"));
|
||||
const repo =
|
||||
ev?.repository?.clone_url ||
|
||||
(ev?.repository?.html_url ? (ev.repository.html_url.replace(/\/$/,"") + ".git") : "");
|
||||
const sha =
|
||||
ev?.after ||
|
||||
ev?.pull_request?.head?.sha ||
|
||||
ev?.head_commit?.id ||
|
||||
ev?.sha ||
|
||||
"";
|
||||
if (!repo) throw new Error("No repository url in event.json");
|
||||
if (!sha) throw new Error("No sha in event.json");
|
||||
process.stdout.write(`REPO_URL=${JSON.stringify(repo)}\nSHA=${JSON.stringify(sha)}\n`);
|
||||
')"
|
||||
|
||||
echo "Repo URL: $REPO_URL"
|
||||
echo "SHA: $SHA"
|
||||
|
||||
rm -rf .git
|
||||
git init -q
|
||||
git remote add origin "$REPO_URL"
|
||||
git fetch --depth 1 origin "$SHA"
|
||||
git -c advice.detachedHead=false checkout -q FETCH_HEAD
|
||||
git log -1 --oneline
|
||||
|
||||
- name: Anchor aliases schema
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node scripts/check-anchor-aliases.mjs
|
||||
|
||||
- name: NPM harden
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm config set fetch-retries 5
|
||||
npm config set fetch-retry-mintimeout 20000
|
||||
npm config set fetch-retry-maxtimeout 120000
|
||||
npm config set registry https://registry.npmjs.org
|
||||
npm config get registry
|
||||
|
||||
- name: Install deps
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm ci
|
||||
|
||||
- name: Inline scripts syntax check
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node scripts/check-inline-js.mjs
|
||||
|
||||
- name: Build (includes postbuild injection + pagefind)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm run build
|
||||
|
||||
- name: Anchors contract
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm run test:anchors
|
||||
|
||||
- name: Verify anchor aliases injected in dist
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node scripts/verify-anchor-aliases-in-dist.mjs
|
||||
103
.gitea/workflows/ci.yml
Normal file
103
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,103 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push: {}
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
NODE_OPTIONS: --dns-result-order=ipv4first
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build-and-anchors:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/devcontainers/javascript-node:22-bookworm
|
||||
|
||||
steps:
|
||||
- name: Tools sanity
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git --version
|
||||
node --version
|
||||
npm --version
|
||||
npm ping --registry=https://registry.npmjs.org
|
||||
|
||||
- name: Checkout (from event.json, no external actions)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
EVENT_JSON="/var/run/act/workflow/event.json"
|
||||
test -f "$EVENT_JSON" || (echo "❌ Missing $EVENT_JSON" && exit 1)
|
||||
|
||||
eval "$(node - <<'NODE'
|
||||
import fs from "node:fs";
|
||||
const ev = JSON.parse(fs.readFileSync("/var/run/act/workflow/event.json","utf8"));
|
||||
const repo =
|
||||
ev?.repository?.clone_url ||
|
||||
(ev?.repository?.html_url ? (ev.repository.html_url.replace(/\/$/,'') + ".git") : "");
|
||||
const sha =
|
||||
ev?.after ||
|
||||
ev?.pull_request?.head?.sha ||
|
||||
ev?.head_commit?.id ||
|
||||
ev?.sha ||
|
||||
"";
|
||||
if (!repo) { console.error("No repository.clone_url/html_url in event.json"); process.exit(1); }
|
||||
if (!sha) { console.error("No sha/after/pull_request.head.sha in event.json"); process.exit(1); }
|
||||
console.log(`REPO_URL=${JSON.stringify(repo)}`);
|
||||
console.log(`SHA=${JSON.stringify(sha)}`);
|
||||
NODE
|
||||
)"
|
||||
|
||||
echo "Repo URL: $REPO_URL"
|
||||
echo "SHA: $SHA"
|
||||
|
||||
rm -rf .git
|
||||
git init
|
||||
git remote add origin "$REPO_URL"
|
||||
git fetch --depth 1 origin "$SHA"
|
||||
git checkout -q FETCH_HEAD
|
||||
git log -1 --oneline
|
||||
|
||||
- name: Anchor aliases schema
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node scripts/check-anchor-aliases.mjs
|
||||
|
||||
- name: NPM harden
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm config set fetch-retries 5
|
||||
npm config set fetch-retry-mintimeout 20000
|
||||
npm config set fetch-retry-maxtimeout 120000
|
||||
npm config set registry https://registry.npmjs.org
|
||||
npm config get registry
|
||||
|
||||
- name: Install deps
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm ci
|
||||
|
||||
- name: Inline scripts syntax check
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node scripts/check-inline-js.mjs
|
||||
|
||||
- name: Build (includes postbuild injection + pagefind)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm run build
|
||||
|
||||
- name: Anchors contract
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm run test:anchors
|
||||
|
||||
- name: Verify anchor aliases injected in dist
|
||||
run: |
|
||||
set -euo pipefail
|
||||
node scripts/verify-anchor-aliases-in-dist.mjs
|
||||
9
.gitea/workflows/smoke.yml
Normal file
9
.gitea/workflows/smoke.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
name: SMOKE
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: node -v && npm -v
|
||||
- run: echo "runner OK"
|
||||
Reference in New Issue
Block a user