5 Commits

Author SHA1 Message Date
2d1facfb41 fix(ci): call scripts/pr_lgtm_scanner.py instead of inline python
All checks were successful
CI / Detect Changes (pull_request) Successful in 3s
PR → Build → devicectl Deploy → LGTM / Detect Changes (pull_request) Successful in 4s
CI / Deploy (pull_request) Has been skipped
PR → Build → devicectl Deploy → LGTM / Build & Deploy to iPhone (devicectl) (pull_request) Successful in 4m39s
CI / YouTube Worker (pull_request) Has been skipped
PR → Build → devicectl Deploy → LGTM / Wait for LGTM comment (pull_request) Successful in 11m52s
The inline python3 -c body in wait-approval raised IndentationError: unexpected indent because YAML block scalars dedent content to the first line's indent, leaving the python body with leading whitespace.

Replace with a call to scripts/pr_lgtm_scanner.py (added in the previous commit). Add a shallow Checkout step to wait-approval so the script is present on the runner.

This is the third indentation fix attempt for this scanner:
  - column-0 python  → YAML parse failure
  - indented python  → Python IndentationError
  - standalone file  → no indentation concerns (this commit)
2026-07-20 09:34:29 +02:00
7196cce237 add scripts/pr_lgtm_scanner.py — LGTM/KO scanner for pr-iphone-deploy
Standalone Python scanner extracted from the inline python in wait-approval. Embedding multi-line Python in a YAML run: | block scalar is fragile: YAML dedents block-scalar content to the first line's indent, which produced both YAML parse failures and Python IndentationErrors in earlier iterations of this workflow. A standalone script file sidesteps all of that and is testable locally.

Behavior preserved:
  - json.loads + \bLGTM\b / \bKO\b word-boundary regex (case-insensitive)
  - skip bot comments tagged with <!-- tabatago:ready-to-test -->
  - KO checked BEFORE LGTM (PR with both signals blocks)

Verified locally across 8 scenarios (bot-only, LGTM, KO, both, empty, usage error, KOM/LGTMX non-match, case-insensitive).
2026-07-20 09:34:28 +02:00
47106ff281 fix(ci): indent python3 -c body so YAML block scalar parses
Some checks failed
CI / Deploy (pull_request) Has been skipped
PR → Build → devicectl Deploy → LGTM / Build & Deploy to iPhone (devicectl) (pull_request) Successful in 2m39s
PR → Build → devicectl Deploy → LGTM / Wait for LGTM comment (pull_request) Failing after 31s
PR → Build → devicectl Deploy → LGTM / Detect Changes (pull_request) Successful in 3s
CI / Detect Changes (pull_request) Successful in 4s
CI / YouTube Worker (pull_request) Has been skipped
The python3 inline script in wait-approval was written at column 0 (lines 257-283), but YAML block scalars require content to be more indented than the parent key. YAML exited the run: | block at the first column-0 line ("import json, re, sys") and tried to parse the python as YAML, failing with "could not find expected :" at line 257 — which prevented pr-iphone-deploy.yml from running at all (no run was ever created for PRs that touched only the workflow file).

Fix: switch to python3 -c with the body indented to sit inside the run: | block scalar.

Verified locally:
  - yaml.safe_load parses the workflow cleanly (jobs: changes, build-deploy, wait-approval).
  - The extracted python, run exactly as act will execute it, returns:
      bot-only            -> PENDING  (was self-merging before)
      bot + reviewer LGTM -> LGTM     (squash-merge still fires)
      bot + reviewer KO   -> KO       (block still fires)
2026-07-20 09:21:28 +02:00
semantic-release-bot
7a1a70af87 chore(release): 1.0.2 [skip ci]
## [1.0.2](https://gitea.1000co.fr/millianlmx/tabatago/compare/v1.0.1...v1.0.2) (2026-07-19)

### Bug Fixes

* **ci:** pr-iphone-deploy no longer self-merges on its own comment ([98f4f82](98f4f82db2)), closes [#6937a36](https://gitea.1000co.fr/millianlmx/tabatago/issues/6937a36) [#12](#12)
* **ci:** replace trigger-level paths: with dorny/paths-filter (Gitea ignores on.pull_request.paths) ([27f9c6b](27f9c6b7b6)), closes [#13](#13)
2026-07-19 20:17:03 +00:00
e2532a8136 Merge pull request 'fix(ci): pr-iphone-deploy no longer self-merges on its own comment' (#13) from fix/ci-lgtm-self-match into main
All checks were successful
CI / Detect Changes (push) Successful in 4s
Admin Web Docker / Docker Build Validation (push) Has been skipped
Admin Web Docker / Semantic Release (push) Successful in 12s
CI / YouTube Worker (push) Has been skipped
Admin Web Docker / Build & Push Docker Image (push) Successful in 53s
CI / Deploy (push) Has been skipped
Admin Web Docker / Admin Web Tests (push) Successful in 33s
Reviewed-on: #13
2026-07-19 22:16:12 +02:00
4 changed files with 90 additions and 31 deletions

View File

@@ -215,6 +215,15 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout
# Shallow clone — wait-approval only needs scripts/pr_lgtm_scanner.py,
# nothing else from the repo. Same raw-git pattern as build-deploy's
# Checkout step (avoids actions/checkout setup).
run: |
git clone --depth 1 -b ${{ github.head_ref }} https://x-access-token:${PR_TOKEN}@gitea.1000co.fr/${{ github.repository }}.git .
env:
PR_TOKEN: ${{ secrets.PR_API_TOKEN }}
- name: Poll for LGTM
env:
GT_TOKEN: ${{ secrets.PR_API_TOKEN }}
@@ -233,8 +242,8 @@ jobs:
# edits — e.g. a reviewer changing "KO" → "LGTM". Negligible cost for
# PRs with <50 comments.
#
# Parsing is done with python3 (preinstalled on the macOS runner and
# already used by scripts/ci-status.py) rather than grep over raw JSON:
# The LGTM/KO decision is computed by scripts/pr_lgtm_scanner.py
# (a standalone Python file) rather than grep over raw JSON:
# - the bot's "Ready to test" comment body literally contains the
# words LGTM/KO as instructions to the reviewer, so any naive
# body grep would self-match and auto-merge ~30s after deploy.
@@ -253,33 +262,13 @@ jobs:
COMMENTS=$(curl -s -H "Authorization: token ${GT_TOKEN}" \
"${API}/issues/${PR}/comments?limit=50&page=1")
DECISION=$(python3 -c '
import json, re, sys
MARKER = "<!-- tabatago:ready-to-test -->"
try:
comments = json.loads(sys.argv[1] or "[]")
except Exception:
comments = []
lgtm = re.compile(r"\bLGTM\b", re.IGNORECASE)
ko = re.compile(r"\bKO\b", re.IGNORECASE)
hit_lgtm = hit_ko = False
for c in comments:
body = c.get("body") or ""
if MARKER in body:
# Skip bot comments — their body contains LGTM/KO as reviewer
# instructions and would otherwise self-trigger a merge.
continue
if ko.search(body):
hit_ko = True
if lgtm.search(body):
hit_lgtm = True
if hit_ko:
print("KO")
elif hit_lgtm:
print("LGTM")
else:
print("PENDING")
' "$COMMENTS")
# The LGTM/KO scanner lives in scripts/pr_lgtm_scanner.py rather
# than inline here. Embedding multi-line Python in a YAML `run: |`
# block scalar is fragile — YAML dedents block-scalar content to
# the first line, which produced both YAML parse failures and
# Python IndentationErrors in earlier iterations of this workflow.
# A standalone script sidesteps all of that and is testable locally.
DECISION=$(python3 scripts/pr_lgtm_scanner.py "$COMMENTS")
case "$DECISION" in
LGTM)

View File

@@ -1,6 +1,6 @@
{
"name": "my-app",
"version": "1.0.1",
"version": "1.0.2",
"private": true,
"scripts": {
"dev": "next dev",

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
"""LGTM/KO scanner for the pr-iphone-deploy workflow's wait-approval job.
Reads a Gitea PR comments JSON array (as returned by
``/api/v1/repos/{owner}/{repo}/issues/{pr}/comments``) on argv[1] and prints
exactly one of: ``LGTM``, ``KO``, ``PENDING``.
Rules
-----
* The bot's own "Ready to test" comment body literally contains the words
``LGTM`` and ``KO`` as instructions to the reviewer — without filtering it
out, the workflow would self-merge ~30s after deploy. Bot comments are
tagged with the sentinel ``<!-- tabatago:ready-to-test -->`` and skipped.
* ``KO`` is checked BEFORE ``LGTM`` — a PR with both signals blocks (matches
the existing "KO blocks" intent).
* Word-boundary regex (``\\bLGTM\\b`` / ``\\bKO\\b``, case-insensitive) so
"Tested, LGTM!" counts and "KOM" / "LGTMX" do not.
This script lives in ``scripts/`` (not inline in the workflow) because
embedding multi-line Python inside a YAML ``run: |`` block scalar is fragile:
YAML dedents block-scalar content to the first line, which produces either a
YAML parse failure or a Python ``IndentationError`` depending on how the
body is indented. A standalone file sidesteps all of that.
"""
import json
import re
import sys
MARKER = "<!-- tabatago:ready-to-test -->"
LGTM_RE = re.compile(r"\bLGTM\b", re.IGNORECASE)
KO_RE = re.compile(r"\bKO\b", re.IGNORECASE)
def decide(comments_json: str) -> str:
"""Return 'KO', 'LGTM', or 'PENDING' for the given comments JSON payload."""
try:
comments = json.loads(comments_json or "[]")
except Exception:
comments = []
hit_lgtm = False
hit_ko = False
for comment in comments:
body = comment.get("body") or ""
if MARKER in body:
# Skip the bot's own "Ready to test" comment — its body mentions
# LGTM/KO as instructions and would otherwise self-trigger.
continue
if KO_RE.search(body):
hit_ko = True
if LGTM_RE.search(body):
hit_lgtm = True
if hit_ko:
return "KO"
if hit_lgtm:
return "LGTM"
return "PENDING"
def main() -> int:
if len(sys.argv) != 2:
print("usage: pr_lgtm_scanner.py <comments_json>", file=sys.stderr)
return 2
print(decide(sys.argv[1]))
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1,3 +1,3 @@
{
"version": "1.0.1"
"version": "1.0.2"
}