forked from makenotion/notion-mcp-server
-
Notifications
You must be signed in to change notification settings - Fork 0
[Self-Heal] Add self-scheduling auto-repair workflow #59
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
Draft
badMade
wants to merge
1
commit into
main
Choose a base branch
from
feature/self-healing-pipeline-4064027269009872807
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
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,3 @@ | ||
| SELFHEAL_SCHEDULE: '0 0 * * 0' | ||
| RATIONALE: 'Dormant repository, running weekly' | ||
| LAST_UPDATED: '2026-06-06T00:54:18.270Z' |
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,58 @@ | ||
| name: Compute Self-Heal Schedule | ||
|
|
||
| on: | ||
| schedule: | ||
| - cron: '0 0 * * 0' # Weekly default baseline | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| compute-schedule: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| actions: read | ||
| if: github.ref == 'refs/heads/main' | ||
| steps: | ||
| - name: Checkout Code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Setup Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'npm' | ||
|
|
||
| - name: Install Tools | ||
| run: | | ||
| npm ci | ||
|
|
||
| - name: Compute New Schedule | ||
| run: | | ||
| node scripts/compute_schedule.mjs | ||
|
|
||
| - name: Create PR (if schedule changed) | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| if [ -z "$(git status --porcelain)" ]; then | ||
| echo "Schedule unchanged. Exiting." | ||
| exit 0 | ||
| fi | ||
|
|
||
| git config --global user.name "github-actions[bot]" | ||
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| BRANCH_NAME="selfheal-schedule-$(date +%s)" | ||
| git checkout -b "$BRANCH_NAME" | ||
| git add .github/self-heal-schedule.yml .github/workflows/self-heal.yml | ||
| git commit -m "Update self-heal schedule cadence" | ||
| git push origin "$BRANCH_NAME" | ||
|
|
||
| gh pr create --title "[Self-Heal Schedule] Update cadence" \ | ||
| --body "Automated PR adjusting the self-healing schedule based on recent repository activity metrics." \ | ||
| --label "automation,self-heal-schedule" \ | ||
| --base main |
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,137 @@ | ||
| name: Self-Heal Repair | ||
|
|
||
| on: | ||
| schedule: | ||
| - cron: '0 0 * * 0' # AUTO-UPDATED | ||
| workflow_run: | ||
| workflows: ["ci"] | ||
| types: | ||
| - completed | ||
| workflow_dispatch: | ||
|
|
||
| concurrency: | ||
| group: selfheal-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| repair: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| actions: read | ||
| if: | | ||
| !startsWith(github.ref_name, 'selfheal-') && | ||
| ( | ||
| github.event_name == 'schedule' || | ||
| github.event_name == 'workflow_dispatch' || | ||
| (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'failure') | ||
| ) | ||
| steps: | ||
| - name: Checkout Code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Setup Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'npm' | ||
|
|
||
| - name: Install Tools | ||
| run: | | ||
| npm ci | ||
|
|
||
| - name: Cleanup Stale PRs | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| DATE=$(date -d "7 days ago" +%Y-%m-%d) | ||
| gh pr list --label self-heal --search "created:<$DATE" --json number --jq '.[].number' | xargs -I {} gh pr close {} --comment "Closing stale self-heal PR" || true | ||
|
|
||
| - name: Guard against Duplicate PRs | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| RECENT_PR=$(gh pr list --label self-heal --state open --json createdAt --jq '.[0].createdAt') | ||
| if [ ! -z "$RECENT_PR" ] && [ "$RECENT_PR" != "null" ]; then | ||
| echo "A self-heal PR is already open. Exiting to prevent duplication." | ||
| exit 0 | ||
| fi | ||
|
|
||
| - name: Pre-Repair Healthcheck | ||
| run: | | ||
| node scripts/healthcheck.mjs > pre-check.log 2>&1 || true | ||
|
|
||
| - name: Run Idempotent Repair Pipeline | ||
| id: repair | ||
| run: | | ||
| node scripts/self_heal.mjs > repair.log 2>&1 | ||
|
|
||
| - name: Post-Repair Healthcheck | ||
| if: steps.repair.outcome == 'success' | ||
| run: | | ||
| node scripts/healthcheck.mjs > post-check.log 2>&1 | ||
|
|
||
| - name: Upload Logs | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: self-heal-logs | ||
| path: | | ||
| pre-check.log | ||
| repair.log | ||
| post-check.log | ||
|
|
||
| - name: Check Diff & Entropy | ||
| if: steps.repair.outcome == 'success' | ||
| id: diff | ||
| run: | | ||
| git status --porcelain | ||
| if [ -z "$(git status --porcelain)" ]; then | ||
| echo "No diff found. Exiting." | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Stage specific allowed paths | ||
| for path in src/ tests/ package.json package-lock.json eslint.config.mjs; do | ||
| git add "$path" 2>/dev/null || true | ||
| done | ||
|
|
||
| if grep -iE '(key|token|secret|password|bearer).*[0-9a-zA-Z]{16,}' $(git diff --name-only --cached); then | ||
| echo "Potential secrets detected in diff. Aborting." | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Create PR | ||
| if: steps.repair.outcome == 'success' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| git config --global user.name "github-actions[bot]" | ||
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| # Ensure there are actually staged files before committing | ||
| if git diff --cached --quiet; then | ||
| echo "No allowed files staged. Exiting." | ||
| exit 0 | ||
| fi | ||
|
|
||
| BRANCH_NAME="selfheal-$(date +%s)" | ||
| git checkout -b "$BRANCH_NAME" | ||
| git commit -m "Auto-repair via self-healing pipeline" | ||
| git push origin "$BRANCH_NAME" | ||
|
|
||
| TITLE="[Self-Heal Reactive] CI fix" | ||
| if [ "${{ github.event_name }}" == "schedule" ]; then | ||
| TITLE="[Self-Heal Scheduled] Drift fixes" | ||
| elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | ||
| TITLE="[Self-Heal Manual] Repair" | ||
| fi | ||
|
|
||
| gh pr create --title "$TITLE" \ | ||
| --body "Automated self-healing PR. Please review the attached logs in GitHub Actions before merging." \ | ||
| --label "automation,self-heal" \ | ||
| --base main |
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 |
|---|---|---|
|
|
@@ -10,3 +10,4 @@ bin/ | |
| .cursor | ||
|
|
||
| .DS_Store | ||
| *.log | ||
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,29 @@ | ||
| # Self-Healing Pipeline Setup | ||
|
|
||
| This project utilizes an automated self-healing CI pipeline to detect and fix common drift or CI failures automatically. | ||
|
|
||
| ## How It Works | ||
|
|
||
| The pipeline is triggered via three methods: | ||
| 1. **Scheduled Runs:** Runs periodically to detect project drift (e.g. out-of-date snapshots, new lint rules). | ||
| 2. **Reactive Runs:** Triggers on failure of the `ci` workflow run. | ||
| 3. **Manual Dispatch:** Can be run at any time via GitHub Actions UI. | ||
|
|
||
| ## The Repair Pipeline | ||
| The pipeline is designed to be idempotent and executes the following steps in order, exiting early if it reaches a healthy state and successfully produces a fixing diff: | ||
| 1. Rebuild/reinstall (clears and installs fresh dependencies). | ||
| 2. Lint auto-fix (runs linters and formatters). | ||
| 3. Snapshot updates (regenerates test snapshots). | ||
| 4. Type stubs (ensures dependency typings are resolved). | ||
| 5. Dependency resolution (updates lockfiles cautiously). | ||
| 6. Static asset generation (rebuilds the output). | ||
|
|
||
| ## Dynamic Scheduling | ||
| The schedule is computed dynamically using repository telemetry (e.g., number of commits). It runs on an adaptive cadence so that high-activity periods get frequent checks, while low-activity periods save CI resources. | ||
| If you need to manually override the schedule, edit `.github/self-heal-schedule.yml` and `.github/workflows/self-heal.yml` to match. The pipeline will respect manual overrides as long as they adhere to the standard schedule format. | ||
|
|
||
| ## Reviewer Guidelines | ||
| When reviewing a PR prefixed with `[Self-Heal...]`: | ||
| 1. Check the associated GitHub Actions run for the pre and post log artifacts to understand what was fixed. | ||
| 2. Confirm the diff only touches relevant files (e.g., source code, test snapshots, config files) and has not modified sensitive configs unprompted. | ||
| 3. Once approved, merge the PR as usual. |
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,33 @@ | ||
| import eslintJs from "@eslint/js"; | ||
| import tseslint from "typescript-eslint"; | ||
| import globals from "globals"; | ||
|
|
||
| export default tseslint.config( | ||
| { | ||
| ignores: [ | ||
| "build/**", | ||
| "dist/**", | ||
| "coverage/**", | ||
| "bin/**", | ||
| "node_modules/**" | ||
| ] | ||
| }, | ||
| eslintJs.configs.recommended, | ||
| ...tseslint.configs.recommended, | ||
| { | ||
| languageOptions: { | ||
| globals: { | ||
| ...globals.node, | ||
| ...globals.browser, | ||
| ...globals.jest, | ||
| ...globals.vitest | ||
| } | ||
| }, | ||
| rules: { | ||
| "@typescript-eslint/no-explicit-any": "off", | ||
| "@typescript-eslint/no-unused-vars": "off", | ||
| "@typescript-eslint/ban-ts-comment": "off", | ||
| "prefer-const": "off" | ||
| } | ||
| } | ||
| ); | ||
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.
Disabling core TypeScript and ESLint rules globally (such as
@typescript-eslint/no-unused-vars,@typescript-eslint/no-explicit-any, andprefer-const) reduces the effectiveness of static analysis. It is highly recommended to keep these rules enabled (or set them towarn) to maintain code quality and type safety, and only disable them via inline comments where absolutely necessary.