Public Access
DEVX-34: fix: retrospective fixes for CI/CD friction
Post-merge / detect-type (push) Successful in 8s
Post-merge / validate-commit-msg (push) Successful in 13s
Post-merge / configure-repo (push) Successful in 25s
Post-merge / release (push) Successful in 50s
Post-merge / vikunja (push) Successful in 10s
Post-merge / sync-wiki (push) Successful in 41s
Post-merge / badges (push) Successful in 40s
Post-merge / detect-type (push) Successful in 8s
Post-merge / validate-commit-msg (push) Successful in 13s
Post-merge / configure-repo (push) Successful in 25s
Post-merge / release (push) Successful in 50s
Post-merge / vikunja (push) Successful in 10s
Post-merge / sync-wiki (push) Successful in 41s
Post-merge / badges (push) Successful in 40s
This commit was merged in pull request #57.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Auto-merge PR when all CI checks pass.
|
||||
|
||||
Runs as the final job in ci.yml. Reads the task ID from ``.taskid`` file
|
||||
(falling back to branch name extraction for backwards compatibility),
|
||||
Runs as the final job in ci.yml. Reads the task ID from the branch name
|
||||
(falling back to ``.taskid`` file for branches without a task ID prefix),
|
||||
validates the PR title, and squash-merges with a conventional commit
|
||||
message prefixed by the task ID.
|
||||
|
||||
@@ -68,15 +68,38 @@ def read_taskid(branch: str) -> str:
|
||||
The branch name is the primary source of truth for the task ID
|
||||
(e.g., ``DEVX-31-fix-foo`` → ``DEVX-31``). The ``.taskid`` file
|
||||
is a legacy fallback for branches without a task ID prefix.
|
||||
|
||||
If both sources exist and disagree, a warning is printed and the
|
||||
branch task ID is preferred (it is the current source of truth).
|
||||
"""
|
||||
branch_task_id = extract_task_id(branch)
|
||||
if branch_task_id:
|
||||
# Check for stale .taskid file that disagrees with branch name
|
||||
path = Path(TASKID_FILE)
|
||||
if path.exists():
|
||||
file_task_id = path.read_text(encoding="utf-8").strip()
|
||||
if file_task_id and file_task_id != branch_task_id:
|
||||
click.echo(
|
||||
_(
|
||||
"WARNING: .taskid file ({file_id}) disagrees with branch name ({branch_id}). "
|
||||
"Using branch task ID. Update or delete .taskid to silence this warning.",
|
||||
file_id=file_task_id,
|
||||
branch_id=branch_task_id,
|
||||
)
|
||||
)
|
||||
return branch_task_id
|
||||
# Fallback: read from .taskid file
|
||||
path = Path(TASKID_FILE)
|
||||
if path.exists():
|
||||
task_id = path.read_text(encoding="utf-8").strip()
|
||||
if task_id:
|
||||
click.echo(
|
||||
_(
|
||||
"Task ID from .taskid file: {task_id} (not found in branch name '{branch}')",
|
||||
task_id=task_id,
|
||||
branch=branch,
|
||||
)
|
||||
)
|
||||
return task_id
|
||||
return ""
|
||||
|
||||
|
||||
+3
-2
@@ -13,8 +13,9 @@ import re
|
||||
GITEA_API_URL = os.getenv("DEVX_GITEA_API_URL", "https://git.oblachno.oblachno.fyi/api/v1")
|
||||
VIKUNJA_API_URL = os.getenv("DEVX_VIKUNJA_API_URL", "https://work.oblachno.oblachno.fyi/api/v1")
|
||||
|
||||
# Organization defaults
|
||||
REPO_OWNER = os.getenv("DEVX_REPO_OWNER", "oblachno-oss")
|
||||
# Organization defaults — each project MUST set DEVX_REPO_OWNER explicitly.
|
||||
# No default: prevents silent 404s when the wrong owner is used.
|
||||
REPO_OWNER = os.getenv("DEVX_REPO_OWNER", "")
|
||||
|
||||
# Task prefix for Vikunja task IDs — each project sets its own (GRM, DEVX, INFRA, etc.)
|
||||
TASK_PREFIX = os.getenv("DEVX_TASK_PREFIX", "DEVX")
|
||||
|
||||
@@ -155,6 +155,19 @@ def main(repo: str | None, owner: str | None, branch: str, api_url: str | None)
|
||||
if not repo:
|
||||
raise click.ClickException(_("ERROR: Repository name not specified. Use --repo or set DEVX_REPO_NAME."))
|
||||
|
||||
# If DEVX_REPO_NAME contains a slash (e.g. "oblachno/infra"), split into owner/repo.
|
||||
# This prevents 404s when workflows set DEVX_REPO_NAME to the full path.
|
||||
if "/" in repo and owner is None:
|
||||
parts = repo.split("/", 1)
|
||||
owner, repo = parts[0], parts[1]
|
||||
click.echo(
|
||||
_(
|
||||
"Parsed owner={owner}, repo={repo} from DEVX_REPO_NAME",
|
||||
owner=owner,
|
||||
repo=repo,
|
||||
)
|
||||
)
|
||||
|
||||
if owner is None:
|
||||
owner = REPO_OWNER
|
||||
|
||||
|
||||
@@ -811,6 +811,13 @@
|
||||
"ru": "Ой! Публикация в PyPI не удалась:\n{stderr}",
|
||||
"zh": "哎呀!PyPI 发布失败:\n{stderr}"
|
||||
},
|
||||
"Parsed owner={owner}, repo={repo} from DEVX_REPO_NAME": {
|
||||
"bg": "Разбор на owner={owner}, repo={repo} от DEVX_REPO_NAME",
|
||||
"de": "Owner={owner}, repo={repo} aus DEVX_REPO_NAME analysiert",
|
||||
"en": "Parsed owner={owner}, repo={repo} from DEVX_REPO_NAME",
|
||||
"ru": "Извлечён owner={owner}, repo={repo} из DEVX_REPO_NAME",
|
||||
"zh": "从 DEVX_REPO_NAME 解析 owner={owner}, repo={repo}"
|
||||
},
|
||||
"PASSED: {pair}": {
|
||||
"bg": "PASSED: {pair}",
|
||||
"de": "PASSED: {pair}",
|
||||
@@ -986,6 +993,13 @@
|
||||
"ru": "Task ID: {task_id}",
|
||||
"zh": "Task ID: {task_id}"
|
||||
},
|
||||
"Task ID from .taskid file: {task_id} (not found in branch name '{branch}')": {
|
||||
"bg": "Task ID от .taskid файл: {task_id} (не е намерен в името на клона '{branch}')",
|
||||
"de": "Task ID aus .taskid-Datei: {task_id} (nicht im Branch-Namen '{branch}' gefunden)",
|
||||
"en": "Task ID from .taskid file: {task_id} (not found in branch name '{branch}')",
|
||||
"ru": "Task ID из файла .taskid: {task_id} (не найден в имени ветки '{branch}')",
|
||||
"zh": "来自 .taskid 文件的 Task ID: {task_id}(在分支名 '{branch}' 中未找到)"
|
||||
},
|
||||
"Test '{name}' took {elapsed:.2f}s (limit: {limit}s). Optimise: use lighter fixtures, reduce I/O, or mock external calls.": {
|
||||
"bg": "Test '{name}' took {elapsed:.2f}s (limit: {limit}s). Optimise: use lighter fixtures, reduce I/O, or mock external calls.",
|
||||
"de": "Test '{name}' took {elapsed:.2f}s (limit: {limit}s). Optimise: use lighter fixtures, reduce I/O, or mock external calls.",
|
||||
@@ -1070,6 +1084,13 @@
|
||||
"ru": "WARNING: --skip-tests passed — skipping test verification.",
|
||||
"zh": "WARNING: --skip-tests passed — skipping test verification."
|
||||
},
|
||||
"WARNING: .taskid file ({file_id}) disagrees with branch name ({branch_id}). Using branch task ID. Update or delete .taskid to silence this warning.": {
|
||||
"bg": "ВНИМАНИЕ: .taskid файл ({file_id}) не съвпада с името на клона ({branch_id}). Използва се task ID от клона. Актуализирайте или изтрийте .taskid за да премахнете това предупреждение.",
|
||||
"de": "WARNUNG: .taskid-Datei ({file_id}) stimmt nicht mit Branch-Namen ({branch_id}) überein. Branch-Task-ID wird verwendet. Aktualisieren oder löschen Sie .taskid, um diese Warnung zu unterdrücken.",
|
||||
"en": "WARNING: .taskid file ({file_id}) disagrees with branch name ({branch_id}). Using branch task ID. Update or delete .taskid to silence this warning.",
|
||||
"ru": "ВНИМАНИЕ: файл .taskid ({file_id}) не совпадает с именем ветки ({branch_id}). Используется Task ID из ветки. Обновите или удалите .taskid, чтобы скрыть это предупреждение.",
|
||||
"zh": "警告:.taskid 文件 ({file_id}) 与分支名 ({branch_id}) 不一致。使用分支 Task ID。更新或删除 .taskid 以消除此警告。"
|
||||
},
|
||||
"Warning: could not fetch tags from origin.": {
|
||||
"bg": "Warning: could not fetch tags from origin.",
|
||||
"de": "Warning: could not fetch tags from origin.",
|
||||
|
||||
Reference in New Issue
Block a user