Skip to content

Verify native CI approval on generated version PRs #100

Open

Description

@coisa

Status and operational boundary

Root cause confirmed: version preparation uses the built-in GITHUB_TOKEN. GitHub deliberately places PR workflows triggered by that token into an approval-required state. This is not a PHP/test failure or a fork-origin mismatch. Automatic native CI is supported through the Changelog's existing GitHub App integration; adoption is proposed below, not configured or executed.

Verified cause — 2026-10-28

  • GitHub's current token rules distinguish pull_request opened, synchronize and reopened: these events generated with GITHUB_TOKEN create approval-required runs. Other token-generated events mostly remain suppressed. GitHub introduced this behavior in its June 11, 2026 announcement.
  • The consumer caller passes no App credentials or alternative token. Both version-preparation runs used reusable revision 203db95e68fc974e95ba1a921f08d01f88851be1. Its authentication selector falls back to the job's github.token.
  • The actual creation job and update job show empty App/alternative-token inputs and their respective created/updated PR chore(release): prepare 3.0.1 for publication #129 results. This proves the fallback path in these runs, rather than merely assuming a token from the Bot name.
  • The public repository's PR head and base are the same repository (ID 98326226). Actions are enabled, and the read-back first-time-contributor fork policy does not explain this same-repository case. The enabled “allow Actions to create/approve PRs” setting governs PR operations; it does not remove the distinct workflow-execution approval gate.

Options and recommendation

Option Assessment
Keep GITHUB_TOKEN and approve exact-head runs manually No new credential, but CI remains attended.
Use the existing dedicated GitHub App integration Recommended for automatic native PR CI. Uses the supported authentication path instead of adding a parallel workflow or approval engine.
Auto-approve through an Actions API bot Not recommended: adds Actions-write authority and a security-sensitive approval decision. The public fork-approval endpoint is not proof that the generating token can self-approve this particular gate.
Dispatch a separate CI run More complex: another event context would need correct PR/check/coverage attribution.
Substitute a personal PAT GitHub generally supports PAT-triggered events, but it is not a direct fit for this Changelog's configured Bot and verified signed-commit contract.

GitHub explicitly documents a separate App installation token for automatically starting these PR workflows. The current Changelog App guide already supports it on the repository's chosen @v0 compatibility branch; no upstream feature is missing.

Proposed implementation, subject to owner approval

  1. Create or reuse a dedicated App installed only for the selected repository. Permission ceiling: Contents write, Pull requests write, Issues read, Commit statuses write and implicit Metadata read. No Actions write, Workflows write, Administration or protection bypass.

  2. Configure repository variables CHANGELOG_APP_CLIENT_ID and CHANGELOG_APP_BOT, plus the Actions secret CHANGELOG_APP_PRIVATE_KEY. Do not put a key in Git or a conversation. The caller currently supplies none of these inputs; no credential has been installed by this investigation.

  3. In the existing reusable job, add only:

    with:
      app-client-id: ${{ vars.CHANGELOG_APP_CLIENT_ID }}
      automation-actor: ${{ vars.CHANGELOG_APP_BOT }}
    
    secrets:
      app-private-key: ${{ secrets.CHANGELOG_APP_PRIVATE_KEY }}

    Retain the existing caller options, @v0, event filters, job permissions and owner-approved publication behavior. No new script, autoapproval job or parallel CI workflow is needed.

  4. Review the small caller change separately; then observe native CI on a legitimately created App-owned version PR and a natural update of that same PR before closing this issue.

The upstream authenticator already limits each short-lived token to one repository and the operation's permissions, checks the trusted event/ref and Bot identity, and revokes the token at job completion. The lifecycle does not forward the App key to its PR-head contribution-check job. Keep ordinary external-contribution gates, human code review and owner merge/release authority. Never execute a PR head under pull_request_target to evade approval.

A persistent App private key is an added credential and the trusted reusable jobs can access it. Limit installation scope, protect and rotate/revoke the key, and retain awareness that the selected mutable @v0 branch is an upstream trust boundary. This is a bounded authentication proposal, not a claim of zero additional risk. App creation/installation, credential setup and caller deployment have not been performed.

Upstream PR #76 compatibility review — 2026-10-28

The maintainer is developing Changelog PR #76. Reviewed head: 11ac2cf136d092265dded8ea6aa66464dd29a8f0, including the earlier 6d22cdae snapshot; the final incremental change only formats a workflow test.

  • Its channel promotion is repository-internal to Changelog: branches v0/v1, moving latest tag, release events and the dedicated channel App/rules are not consumer requirements. Error Handler has no downstream release-event channel job to migrate.
  • The new lifecycle inputs publish-app-client-id, publish-environment and secret publish-app-private-key are optional and affect only publication. They deliberately preserve the existing managed-PR author and other lifecycle credentials. Adopting only them would leave this issue's GITHUB_TOKEN approval cause unchanged.
  • Automatic native CI still uses the existing authoring-App contract: app-client-id, matching automation-actor and secret app-private-key. PR Require merged version-PR provenance before native publication #76 is not a missing prerequisite for that existing capability; no App is being created or configured by this assessment.
  • No immediate caller change is required for compatibility. Keep the owner's @v0 choice. The currently verified latest release and channel remain v0.4.1 / 203db95e68fc974e95ba1a921f08d01f88851be1; do not add the draft's new inputs until a verified published release containing them actually reaches that channel.
  • When deliberately adopting the new release/skill, review skills.json: its ^0.3.0 constraint excludes later 0.4+ minors. Update it to the selected published release's intended range and align the release guide/caller's reviewed-version references. Composer synchronizes the ignored .agents/ copy; never hand-edit or commit it.
  • There is no reason to copy Changelog's App ID, environment, rulesets or actions-tagger job into Error Handler. Publication-only App configuration would be a separate optional choice if this repository later needs genuine downstream release events.

The draft was inspected, not installed or executed. This note refines the existing proposal; it does not authorize upstream activation, consumer credentials, workflow deployment, merge or publication.

Latest natural update: PR #129

PR #129 prepared 3.0.1. It was created at 2026-10-28T20:01:09Z, naturally updated at 20:03:03Z, then merged by the owner at 20:03:37Z as c0bd18543ad57e9baeb35aabb316d455e8645277.

Stage Exact head Changelog base
Created df1eba21d272ebd02163b6476261ab3a69c7cc69 f743d89efd0832c3e6e7f729b286e8cc929f436c
Updated in the same PR 00019c85e5e732141358926bcc55e8d2762fee4f 3282d4f319a1256d27a84245fab0c6ef9f0ca5d3

The commit history and native check suite 110485644507 record the previous/new heads. The updated commit has both the previous head and new master as parents. The native run pages explicitly identify opened versus synchronize for PR #129. The PR only changed CHANGELOG and removed its two consumed fragments; it did not alter workflow files.

Workflow Created-head run Updated-head run
PHP CI 40759493998 40759795955
Documentation 40759492524 40759795990
PHP style 40759493456 40759796790
Changelog 40759493961 40759797497

All eight native pull_request runs ended failure, on attempt 1, with zero jobs. Each native run page reports: “This workflow run required approval but was not approved before it expired.” The updated-head runs were created at 20:03:13–14Z and completed at 20:03:38Z, immediately after the merge.

There is no PHPUnit coverage report on PR #129. Its only sticky Changelog comment still attributes the created head; that comment and post-merge publication checks do not prove native test execution for the updated head. No run was approved or rerun retrospectively to manufacture evidence.

Completion criteria

  • Identify the native gate and prove the effective token, same-repository origin and exact created/updated heads.
  • Verify actual native jobs, exact-head attribution and sticky coverage on the earlier manually approved creation paths.
  • Observe a genuine update to the same managed PR and retain native events, runs/attempts and the gate outcome.
  • Compare supported automation options and prepare the minimal existing-App integration with its security boundaries.
  • Obtain owner approval for App installation/credential configuration and the reviewed caller change; do not broaden repository or fork policies.
  • Verify a naturally created App-owned version PR and a natural update execute real PHP/style/docs/Changelog jobs without this token-origin approval gate; record previous/new heads, exact-head status, tested SHA and sticky coverage.
  • Preserve the configurable 80% coverage floor, native failures, untrusted-contribution controls and human merge/release authority; confirm no App key reaches PR-head execution.
  • Close only after the native execution evidence is recorded. A configured App or a successful post-merge master build alone is insufficient.

Next action and evidence boundary

Review the proposed scoped App setup above. Until it is approved and configured, the supported existing route is manual approval of the exact-head workflows before merging. Do not fabricate a version PR, alter versions or force an update solely to demonstrate the case. Do not retrospectively rerun merged PR #129 as a substitute for normal lifecycle evidence.

This investigation changed no workflow, setting, credential or source, approved/reran no run, and performed no dispatch, merge or publication. Earlier evidence was gathered without a new App; the maintainer's current request explicitly asks to evaluate secure automation, which is why an optional App is now a proposed next step.

Earlier verified creation paths

PR #123 prepared 3.0.0 at head b382bef6522f4cde80595161917b4ac7afc862cc. As recorded in the earlier evidence, native approval let all four original runs execute on attempt 2: PHP CI 40716169019, Documentation 40716169070, style 40716169624 and Changelog 40716170709. The sticky coverage report attributed 95.02% → 95.02%, the unchanged 80% floor and tested merge commit 70728ac18d73443a861ae2773bfb25ffd086090a. This proved creation after approval, not an updated head.

PR #122 prepared 2.5.5 at head b05d57937c24e30c670f6eb0b95c049080623e26, based on master e8341f6a505af45796a2bd7a38ddc45ee0c541fe. Four native runs initially required approval with zero jobs. After native approval, attempt 2 ran actual jobs against the same head: PHP CI 39493142496 (all 14 jobs), Documentation 39493142553, style 39493143103 and Changelog 39493143826 succeeded; publication was skipped. Its coverage comment records 97.16% → 97.16%, the unchanged 80% floor and tested merge commit 675e095c98e632083e160d6fc4cafe5e871b2f3b, whose parents are the recorded master and PR head.

Older gate evidence retained

PR #120, head f96616b566d2e13758ad327e3f9b32b03c7166c1, had PHP run 39478415446 with zero jobs/check runs and the same native approval-expired annotation. The owner merged it at 2026-10-20T18:53:47Z. Master run 39478742581 executed 14 genuine jobs, but was not proof for the version-PR head.

PR #117 had created head 38dd3c3a8ff6f9bc661cdaed16243cd9223f300e / run 39069535032 requiring approval with zero jobs. Its updated head c63f565bed7d9e13f651485fdc74db99c3413908 / run 39069596315 also had zero jobs after merge. This is historical update evidence with an unsatisfied gate, not a demonstrated suite failure or a successful approved update.

Activity

  1. changed the title [-][RFC / CI] Validate automatic Changesets PRs before requiring CI checks[/-] [+]Run native CI on generated Changesets PR heads before requiring checks[/+] on Oct 17, 2026
  2. added this to the 2.x maintenance milestone on Oct 17, 2026
  3. changed the title [-]Run native CI on generated Changesets PR heads before requiring checks[/-] [+]Run native CI on automation-generated version PR heads before requiring checks[/+] on Oct 17, 2026
  4. removed this from the 2.x maintenance milestone on Oct 20, 2026
  5. changed the title [-]Run native CI on automation-generated version PR heads before requiring checks[/-] [+]Verify native CI approval on generated version PRs[/+] on Oct 20, 2026
  6. coisa commented on Oct 28, 2026

    @coisa
    OwnerAuthor

    Natural 3.0.0 version-PR creation: native execution verified

    Merging PR 3 naturally created PR 123 at 2026-10-28T15:27:35Z, preparing 3.0.0 on changelog/version against master e8add53fe4d5152ab806ffac1815247160250fff. Its single observed commit/head remains b382bef6522f4cde80595161917b4ac7afc862cc.

    The four native pull_request runs initially reported action_required with zero jobs on attempt 1. The primary agent then approved execution through GitHub's native API under the owner's current task authorization. With no change to the PR head or workflows, the same runs executed real jobs on attempt 2:

    Workflow Verified result at head b382bef
    PHP CI 40716169019 Success: all 14 actual jobs, including PHP 8.3–8.5 quality, five production graphs, four Symfony combinations and coverage/report
    Documentation 40716169070 Success
    PHP style 40716169624 Success
    Changelog 40716170709 Success; publication skipped

    The native sticky coverage report records 95.02% → 95.02%, the unchanged 80% floor, the exact PR head and tested merge commit 70728ac18d73443a861ae2773bfb25ffd086090a.

    This verifies creation followed by native approval and real execution. It does not prove a natural update to the same generated PR. That remaining completion criterion stays open: retain old/new heads, event/run/attempt, any approval requirement, actual jobs and resulting coverage when a genuine update occurs.

    No current PHP or workflow implementation defect was demonstrated. No versions, workflow policy, token/App or branch were changed to force the missing observation, and no synthetic dispatch was used. Native execution approval is not code-review approval, merging the version PR or authorization to publish. PR 123 remains open; no tag or release was created by this investigation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions