Skip to content

ci: catch a title that calls the repository a feature of wikven - #748

Merged
lens0021 merged 1 commit into
mainfrom
claude/guard-repository-only
Sep 10, 2026
Merged

lens0021 merged 1 commit into
mainfrom
claude/guard-repository-only

Conversation

@lens0021

@lens0021 lens0021 commented Sep 10, 2026 •

Copy link
Copy Markdown
Collaborator

There already is a check for this. semantic-pull-request.yml carries a second job that refuses feat: and fix: on a pull request touching nothing but documentation, for exactly the reason #744 turned out to matter: the title becomes the squash commit's subject, and release-please reads it.

#744 went through it twice over.

Its list was too narrow. It read docs/, *.md and LICENSE. A ruleset under .tf/ is none of those, so the job said the change was wikven's own and let feat: stand. Widened here to everything that is the repository rather than the program — the two above plus .tf/ and .github/.

It could not have blocked anything anyway. The job is not in the required checks, so a red result leaves the pull request mergeable, and auto-merge would have merged it regardless. Added to the list in .tf/ruleset.tf.

Renamed docs-only → repository-only, since it no longer reads only documentation, and the required check has to name it.

#746 and #747 gave release-please exclude-paths for .tf and docs. That is a net under the mistake: the commit is dropped silently, and nobody learns anything. This is where it gets caught and said out loud, which is also why the check's list is wider than exclude-paths — the latter can only name directories, so *.md and LICENSE cannot appear in it.

Exercised

The job's own script, lifted out of the workflow with gh api stubbed, against ten pull requests:

title files result
feat: … .tf/ruleset.tf refused
feat: … .github/workflows/a.yml refused
feat: … docs/a.wikitext, README.md refused
feat: … LICENSE refused
fix(build): … .tf/ruleset.tf refused
feat!: … .tf/ruleset.tf refused
feat: … includes/A.php allowed
feat: … docs/a.wikitext, includes/A.php allowed
docs: … .tf/ruleset.tf allowed
ci: … .tf/ruleset.tf allowed

Run locally, and it has to be: the workflow triggers on pull_request_target, which runs the version on the base branch. The check reporting on this pull request is docs-only from main — the widened job first runs on whatever comes after this. The same goes for the required-check entry, which needs a tofu apply; until then repository-only reports without blocking.

Two consequences of that worth knowing about. Between merging and applying, docs-only no longer exists while nothing requires repository-only, so for that window neither name blocks. And this pull request cannot check its own title — it touches only .github/ and .tf/, so ci: is what the new rule would allow, but the rule is not the one that ran.

🤖 Generated with Claude Code

https://claude.ai/code/session_019ghEx26MRm9V5CnCLrdUQn

The check that refuses feat: and fix: on a documentation-only pull request read docs/, the readmes
and the licence. #744 was a ruleset under .tf/, so it went through and reached 1.1.0's changelog as
a feature. Widen it to everything that is the repository rather than the program, and make it a
required check: it was never one, so a red result would not have stopped the merge either.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ghEx26MRm9V5CnCLrdUQn
@github-actions

Copy link
Copy Markdown
Contributor

OpenTofu Plan

github_repository.this: Preparing import... [id=wikven]
github_repository.this: Refreshing state... [id=wikven]
github_repository_pages.this: Preparing import... [id=wikven]
github_repository_ruleset.default: Preparing import... [id=wikven:17638220]
github_repository_pages.this: Refreshing state... [id=436976489]
github_repository_ruleset.default: Refreshing state... [id=17638220]

OpenTofu used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
  ~ update in-place (current -> planned)

OpenTofu will perform the following actions:

  # github_repository.this will be imported
  # (imported from "wikven")
    resource "github_repository" "this" {
        allow_auto_merge            = true
        allow_forking               = true
        allow_merge_commit          = false
        allow_rebase_merge          = false
        allow_squash_merge          = true
        allow_update_branch         = true
        archived                    = false
        auto_init                   = false
        default_branch              = "main"
        delete_branch_on_merge      = true
        description                 = "A static web site generator using MediaWiki."
        etag                        = "W/\"fffdf2cdcc60e806abe60aaa6edd83b4168e746dc2fa8afe1143424f3e2b7df2\""
        fork                        = "false"
        full_name                   = "chaotic-ground/wikven"
        git_clone_url               = "git://github.com/chaotic-ground/wikven.git"
        has_discussions             = false
        has_downloads               = false
        has_issues                  = true
        has_projects                = false
        has_wiki                    = false
        homepage_url                = "https://chaotic-ground.github.io/wikven/"
        html_url                    = "https://github.com/chaotic-ground/wikven"
        http_clone_url              = "https://github.com/chaotic-ground/wikven.git"
        id                          = "wikven"
        is_template                 = false
        merge_commit_message        = "PR_BODY"
        merge_commit_title          = "PR_TITLE"
        name                        = "wikven"
        node_id                     = "R_kgDOGgu7aQ"
        primary_language            = "PHP"
        private                     = false
        repo_id                     = 436976489
        squash_merge_commit_message = "PR_BODY"
        squash_merge_commit_title   = "PR_TITLE"
        ssh_clone_url               = "git@github.com:chaotic-ground/wikven.git"
        svn_url                     = "https://github.com/chaotic-ground/wikven"
        topics                      = [
            "docker-image",
            "mediawiki",
            "static-site-generator",
            "wikitext",
        ]
        visibility                  = "public"
        web_commit_signoff_required = false
    }

  # github_repository_pages.this will be imported
  # (imported from "wikven")
    resource "github_repository_pages" "this" {
        api_url        = "https://api.github.com/repos/chaotic-ground/wikven/pages"
        build_status   = "built"
        build_type     = "legacy"
        custom_404     = false
        html_url       = "https://chaotic-ground.github.io/wikven/"
        https_enforced = true
        id             = "436976489"
        public         = true
        repository     = "wikven"
        repository_id  = 436976489

        source {
            branch = "gh-pages"
            path   = "/"
        }
    }

  # github_repository_ruleset.default will be updated in-place
  # (imported from "wikven:17638220")
  ~ resource "github_repository_ruleset" "default" {
        enforcement = "active"
        etag        = "W/\"a5271de79950ddd471eeda42c157072735fc9ea8141412ccdbe12958cdf78f34\""
        id          = "17638220"
        name        = "default"
        node_id     = "RRS_lACqUmVwb3NpdG9yec4aC7tpzgENI0w"
        repository  = "wikven"
        ruleset_id  = 17638220
        target      = "branch"

        conditions {
            ref_name {
                exclude = []
                include = [
                    "~DEFAULT_BRANCH",
                ]
            }
        }

      ~ rules {
            creation                      = false
            deletion                      = true
            non_fast_forward              = true
            required_linear_history       = false
            required_signatures           = false
            update                        = false
            update_allows_fetch_and_merge = false

            pull_request {
                allowed_merge_methods             = [
                    "merge",
                    "squash",
                    "rebase",
                ]
                dismiss_stale_reviews_on_push     = false
                require_code_owner_review         = false
                require_last_push_approval        = false
                required_approving_review_count   = 0
                required_review_thread_resolution = false
            }

          ~ required_status_checks {
                do_not_enforce_on_create             = false
                strict_required_status_checks_policy = false

                required_check {
                    context        = "biome"
                    integration_id = 15368
                }
                required_check {
                    context        = "caddy"
                    integration_id = 15368
                }
                required_check {
                    context        = "composer-test"
                    integration_id = 15368
                }
                required_check {
                    context        = "coverage"
                    integration_id = 15368
                }
                required_check {
                    context        = "docker-image"
                    integration_id = 15368
                }
                required_check {
                    context        = "mago"
                    integration_id = 15368
                }
                required_check {
                    context        = "phan (REL1_46)"
                    integration_id = 15368
                }
                required_check {
                    context        = "phan (master)"
                    integration_id = 15368
                }
                required_check {
                    context        = "phpcs"
                    integration_id = 15368
                }
                required_check {
                    context        = "phpunit (REL1_46)"
                    integration_id = 15368
                }
                required_check {
                    context        = "phpunit (master)"
                    integration_id = 15368
                }
                required_check {
                    context        = "rumdl"
                    integration_id = 15368
                }
                required_check {
                    context        = "semantic-pull-request"
                    integration_id = 15368
                }
                required_check {
                    context        = "smoke"
                    integration_id = 15368
                }
                required_check {
                    context        = "taplo"
                    integration_id = 15368
                }
                required_check {
                    context        = "typos"
                    integration_id = 15368
                }
                required_check {
                    context        = "yamllint"
                    integration_id = 15368
                }
                required_check {
                    context        = "zizmor"
                    integration_id = 15368
                }
              + required_check {
                  + context        = "repository-only"
                  + integration_id = 15368
                }
            }
        }
    }

  # github_repository_ruleset.pages will be created
  + resource "github_repository_ruleset" "pages" {
      + enforcement = "active"
      + etag        = (known after apply)
      + id          = (known after apply)
      + name        = "gh-pages"
      + node_id     = (known after apply)
      + repository  = "wikven"
      + ruleset_id  = (known after apply)
      + target      = "branch"

      + conditions {
          + ref_name {
              + exclude = []
              + include = [
                  + "refs/heads/gh-pages",
                ]
            }
        }

      + rules {
          + deletion                      = true
          + update_allows_fetch_and_merge = false
        }
    }

Plan: 3 to import, 1 to add, 1 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so OpenTofu can't
guarantee to take exactly these actions if you run "tofu apply" now.

View run

@lens0021
lens0021 merged commit 1487bc8 into main Sep 10, 2026
28 checks passed
@lens0021
lens0021 deleted the claude/guard-repository-only branch September 10, 2026 22:54
lens0021 added a commit that referenced this pull request Sep 17, 2026
Following #751, the same thing in three more comments: most of their
length goes on what went wrong once rather than on what is true now. In
each, the rule that came out of it was already there in the next
sentence.

Sixteen lines become nine. No behaviour changes.

## `smoke.yml` — the timeout

Five lines on one afternoon: a mirror that stopped answering, which file
it had already fetched, where apt fell back to. What survives is the
reason every job in the repository carries a timeout at all.

```diff
-    # Every job in this repository carries one of these, and this is the job that earned them. On
-    # 2026-08-18 the runner's Ubuntu mirror stopped answering during `playwright install
-    # --with-deps`; apt fell back to archive.ubuntu.com, fetched the release files and then sat
-    # there. With no timeout the job waited out GitHub's six-hour default before anyone was told
-    # anything. The mirror is not ours to fix; how long we wait to hear about it is.
+    # Every job in this repository carries one of these: a runner that stops answering otherwise
+    # waits out GitHub's six-hour default before anybody is told anything.
```

The paragraph under it — why thirty minutes and not ten — is untouched.

## `smoke.yml` — the browser install

The same mirror, twice more, by date. And a local run that passed once,
which is a measurement rather than a fact about the code.

```diff
-      # on the machine before we ask for anything; --with-deps was buying nothing and paying for it.
-      # Twice -- 2026-08-18 and 2026-08-19 -- azure.archive.ubuntu.com answered nothing at all, apt
-      # fell back to archive.ubuntu.com, took the four InRelease files and then went quiet on the
-      # package indexes until the job was killed. A mirror that is not ours, on a path we do not need.
+      # on the machine before we ask for anything, and an apt call is a mirror that is not ours on a
+      # path we do not need.
```

The sentence about what Playwright says when either half is not enough
stays: that is about any future run, not a past one.

## `semantic-pull-request.yml` — mine, from #748

I wrote this one three days ago and it has the same fault, so it goes
the same way.

```diff
-  # It read the documentation alone until #744, a ruleset under .tf/ that called itself a feature
-  # and reached 1.1.0's changelog as one. release-please now skips those paths outright, but that
-  # is a net under the mistake; this is the place it gets caught, and told to whoever made it.
+  # release-please skips these paths as well, which is a net under the mistake. This is the place it
+  # is caught and said to whoever made it.
```

## What is deliberately left alone

Comments that explain **why the code is the way it is** — this
repository has a word budget for them and they are the reason it passes.
Only past-tense narration goes. A regression test's docblock naming the
failure it catches stays: that is what the test is for, not a story
about it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_019ghEx26MRm9V5CnCLrdUQn

---
_Generated by [Claude
Code](https://claude.ai/code/session_019ghEx26MRm9V5CnCLrdUQn)_

Co-authored-by: Claude <noreply@anthropic.com>
lens0021 added a commit that referenced this pull request Sep 17, 2026
…750)

Two corrections to **Continuous integration** on `Development`. Both are
in translation unit `T:23`, which is the whole bullet list, so they
cannot be separate pull requests without one waiting on the other.

## `tofu.yml` does not apply anything

The page said:

> `updatecli.yml` moves the version pins the image and the docs site
carry, and `tofu.yml` **applies** the repository's own settings from
`.tf/`.

It does not. The action it runs plans, and applies only when the plan
contains nothing but imports —
[`lens0021/repo-settings-as-code`](https://github.com/lens0021/repo-settings-as-code/blob/main/action.yml):

```bash
tofu plan -out="$tfplan" || true
if tofu show -json "$tfplan" | jq -e '
     [.resource_changes[]? |
      select(.change.actions != ["no-op"] and .change.actions != ["read"])] | length == 0
   '; then
  tofu apply -auto-approve "$tfplan"
fi
```

So the imports that adopt what GitHub already has go through; a create
or an update does not. #744 is the proof: merged, and its ruleset still
does not exist, which the plan on every `.tf/` pull request since has
been saying as `1 to add`.

The sentence now says that, and says a merged `.tf/` change is live once
somebody runs `tofu apply` and not before — which is the thing a reader
most needs to know and the page did not tell them.

## One workflow was never named

The list names every workflow in `.github/workflows/` except one:

```
$ for f in .github/workflows/*.yml; do
    grep -q "$(basename "$f")" docs/Development.wikitext || echo "not mentioned: $(basename "$f")"
  done
not mentioned: semantic-pull-request.yml
```

That is the one a contributor meets first and can look up nowhere — and
since #748 it carries a required check that refuses `feat:` and `fix:`
on a change to the repository rather than to wikven. A bullet for it,
beside the others.

## Translation

Korean in the same commit, and restamped with the repository's own
`StalenessComputer`, which is what `check-translations` judges with:

```
units: 56, not ok: none
```

Only `T:23`'s stamp moves — `@29ddac02` → `@b34c3152`. No other unit's
hash changes, so nothing that was current before this is stale after it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_019ghEx26MRm9V5CnCLrdUQn

---
_Generated by [Claude
Code](https://claude.ai/code/session_019ghEx26MRm9V5CnCLrdUQn)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants