-
Notifications
You must be signed in to change notification settings - Fork 4
Scheduled drift detection: weekly full-suite re-run against fresh resolves #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| name: Drift | ||
|
|
||
| # Scheduled drift detection: re-run the full test workflow (unit matrix + | ||
| # notebook execution) against a fresh dependency resolve of an unchanged | ||
| # main. No lockfile is committed AND this repo has no push-to-main CI at | ||
| # all, so between PRs nothing else proves main still works. | ||
| # Failures file ONE deduped `drift`-labeled issue; green runs close it. | ||
| on: | ||
| schedule: | ||
| - cron: "20 5 * * 1" # weekly | ||
| workflow_dispatch: | ||
| inputs: | ||
| force_fail: | ||
| description: "Exercise the drift-issue path without a real failure" | ||
| type: boolean | ||
| default: false | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| tests: | ||
| # Only `report` needs issue-write; the token that runs freshly-resolved | ||
| # third-party test code should not carry it. | ||
| permissions: | ||
| contents: read | ||
| uses: ./.github/workflows/run_tests.yml | ||
|
|
||
|
Comment on lines
+22
to
+28
|
||
| report: | ||
| needs: [tests] | ||
| if: always() | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| issues: write | ||
| # One issue reconciler at a time: the read at `gh issue list` and the write | ||
| # below are not atomic, so an overlapping dispatch could file a duplicate. | ||
| concurrency: | ||
| group: drift-issue-${{ github.repository }} | ||
| cancel-in-progress: false | ||
| steps: | ||
| - name: Create, update, or close the deduped drift issue | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| RESULT_TESTS: ${{ needs.tests.result }} | ||
| FORCE_FAIL: ${{ inputs.force_fail }} | ||
| run: | | ||
| set -euo pipefail | ||
| KEY="drift-key: LANfactory-scheduled" | ||
| TITLE="drift: LANfactory scheduled checks failing" | ||
| RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" | ||
|
|
||
| FAILED_JOBS="" | ||
| if [ "$RESULT_TESTS" = "failure" ]; then | ||
| FAILED_JOBS=" tests" | ||
| fi | ||
| if [ "$FORCE_FAIL" = "true" ]; then | ||
| FAILED_JOBS="$FAILED_JOBS (force_fail rehearsal)" | ||
| fi | ||
|
|
||
| EXISTING=$(gh issue list --repo "$GITHUB_REPOSITORY" --label drift \ | ||
| --state open --search "in:body \"$KEY\"" \ | ||
| --json number --jq '.[0].number // empty') | ||
|
|
||
| # Only a genuine success closes the issue. `report` runs under | ||
| # `if: always()`, which includes cancellation, and a cancelled or | ||
| # never-started test job is no evidence of health — treating it as | ||
| # green would silently retire a real drift issue. | ||
| if [ -z "$FAILED_JOBS" ]; then | ||
| if [ "$RESULT_TESTS" = "success" ]; then | ||
| if [ -n "$EXISTING" ]; then | ||
| gh issue close "$EXISTING" --repo "$GITHUB_REPOSITORY" \ | ||
| --comment "Scheduled drift checks green again: $RUN_URL" | ||
| fi | ||
| else | ||
| echo "::notice::Inconclusive run (tests: $RESULT_TESTS) —" \ | ||
| "drift issue state left unchanged." | ||
| fi | ||
| exit 0 | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| fi | ||
|
|
||
| if [ -n "$EXISTING" ]; then | ||
| gh issue comment "$EXISTING" --repo "$GITHUB_REPOSITORY" \ | ||
| --body "Still failing (${FAILED_JOBS# }): $RUN_URL" | ||
| else | ||
| gh label create drift --repo "$GITHUB_REPOSITORY" \ | ||
| --description "scheduled drift detection failure" \ | ||
| --force 2>/dev/null || true | ||
| BODY=$(printf '%s\n' \ | ||
| "<!-- $KEY -->" \ | ||
| "Scheduled drift run failed in:${FAILED_JOBS}" \ | ||
| "Run: $RUN_URL" \ | ||
| "" \ | ||
| "This re-runs the existing test workflow against a fresh dependency resolve of an unchanged main — a failure usually means an upstream or toolchain release, not a code change." \ | ||
| "Triage via the spine's audit-drift skill.") | ||
| gh issue create --repo "$GITHUB_REPOSITORY" --label drift \ | ||
| --title "$TITLE" --body "$BODY" | ||
| fi | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: lnccbrown/LANfactory
Length of output: 8701
🌐 Web query:
GitHub reusable workflows github.ref default branch input ref workflow_dispatch workflow_call💡 Result:
In GitHub Actions, the
github.refcontext and the calling mechanism for reusable workflows have specific behaviors you should be aware of regarding branches, workflow dispatch, and workflow calls. ### Using References in Reusable Workflows You cannot use expressions or context variables (like${{ github.ref }}or${{ github.sha }}) inside theuseskeyword when calling a reusable workflow [1][2][3]. GitHub Actions requires a static reference—a branch name, tag, or commit SHA—to parse the workflow file at execution time [2][3]. * Same Repository: If your reusable workflow is in the same repository, you should omit the@{ref}suffix entirely (e.g.,uses: ./.github/workflows/my-workflow.yml) [1][2][3]. When you omit this, GitHub automatically executes the workflow version from the same commit as the caller workflow [1][2]. * External Repositories: If calling a workflow from another repository, you must hardcode the version (e.g.,uses: octo-org/repo/.github/workflows/my-workflow.yml@v1) [1][3]. ### ThegithubContext in Reusable Workflows When a reusable workflow is triggered, thegithubcontext (includinggithub.ref) is associated with the caller workflow, not the called reusable workflow [4][5]. This means the reusable workflow does not inherently "know" which specific branch or tag was used to call it if it was referenced by a tag or branch name [5]. If your reusable workflow needs to act on a specific branch or tag (e.g., foractions/checkout), you must explicitly pass that reference as an input [5][3]: 1. Define an input in the reusable workflow'son.workflow_call.inputssection [6][4]. 2. Pass the value from the caller using${{ github.ref }}or${{ github.ref_name }}inside thejobs.<job_id>.withblock [4][5]. ### Workflow Dispatch vs. Workflow Call * Workflow Dispatch: Theworkflow_dispatchevent allows you to trigger a workflow manually [6][7]. It is distinct fromworkflow_call(reusable workflows) and only receives events when the workflow file exists on the default branch [6]. * Inputs: While bothworkflow_dispatchandworkflow_callsupport inputs, they serve different purposes [6][4].workflow_callallows one workflow to use another as a component, whereasworkflow_dispatchis typically used for on-demand execution [6][7]. Remember that theinputscontext inside a reusable workflow is populated only by the values defined in its ownon.workflow_callconfiguration [4][8]. Attempting to accessinputsin the caller workflow's job-levelifconditions will fail, as those inputs exist only within the scope of the called workflow [8].Citations:
🌐 Web query:
site:docs.github.com GitHub Actions reusable workflows workflow_dispatch branch workflow_call ref input github.ref default branch💡 Result:
GitHub Actions utilizes specific mechanisms for triggering, referencing, and passing data to workflows, with distinct behaviors for reusable and manually dispatched workflows. 1. Reusable Workflows (workflow_call) Reusable workflows are defined using the workflow_call trigger [1][2]. They can be called from another workflow (the caller) by referencing their file path and a specific version (ref) [1][3]. - Referencing: You can reference a reusable workflow using the syntax {owner}/{repo}/.github/workflows/{filename}@{ref} [1][4]. The {ref} can be a branch name, a release tag, or a commit SHA [4][5]. - Context and Inputs: When a reusable workflow is triggered, the github context is associated with the caller workflow, not the called workflow [5][6]. Inputs are defined in the called workflow under on.workflow_call.inputs [2] and passed from the caller workflow using the with keyword in a job [1][2]. - Repository Context: Actions within a reusable workflow run as if they were part of the caller workflow; for example, actions/checkout will check out the caller repository's code, not the reusable workflow's repository [3]. 2. Manually Triggered Workflows (workflow_dispatch) The workflow_dispatch trigger allows workflows to be run manually [7]. - Default Branch Requirement: Traditionally, for a workflow to be triggered via workflow_dispatch, the workflow file must exist on the repository's default branch [8][7]. - Branch Execution: While the file must reside on the default branch to be visible and available for manual triggering, you can execute the workflow on a different branch by specifying the ref (e.g., using the --ref flag in the GitHub CLI: gh workflow run WORKFLOW --ref BRANCH) [7]. - Inputs: Inputs for workflow_dispatch are defined in the workflow file and accessed within the workflow via the inputs context or github.event.inputs [8][2][9]. 3. Key Considerations for github.ref - github.ref: This context variable represents the fully-formed ref (e.g., refs/heads/<branch_name> or refs/tags/<tag_name>) of the branch or tag that triggered the workflow [10]. In the context of reusable workflows, because the github context is inherited from the caller [5][6], github.ref will point to the branch or tag of the caller repository that initiated the run, not the branch of the repository hosting the reusable workflow [10].
Citations:
Restrict drift reporting to the default branch.
workflow_dispatchcan run this call from a non-default branch when a ref is supplied. Thetestsjob then runs that branch, butreport: always()usesneeds.tests.resultto create or close the shared drift issue, so a passing branch can close an open issue and a failing branch can create a false drift issue. Drive both jobs from the default branch before using the result for issue updates.🤖 Prompt for AI Agents