💰 Copilot FinOps Automation v3
Govern GitHub Copilot AI-credit spend as code. v3 is a ground-up rewrite: the Bash/gh/jq scripts are gone, replaced by a single self-contained Node.js GitHub Action you can drop into any enterprise config repo — no fork required.
# your enterprise repo's workflow
- uses: amgdy/copilot-finops-automation@v3
with:
operation: apply
enterprise: ${{ vars.COPILOT_FINOPS_ENTERPRISE }}
token: ${{ secrets.COPILOT_FINOPS_TOKEN }}
dry-run: "true"✨ Highlights
- 🧩 Reusable hosted action — load
amgdy/copilot-finops-automation@v3. Your repo owns only its reviewed config, secret, variable, and schedule; the engine lives in the action. No more forking the whole automation repo per enterprise. - 🎯 No member sync — a
teambudget assigns the team itself to a cost center and GitHub expands the cap across members; anorganizationbudget is written directly. The engine never enumerates members, so the token no longer needsread:orgor enterprise-team read. - ⚙️ Rebuilt on Node.js (
node24) — self-contained, committeddist/, nogh/jq/yq/pipxon the runner. - 🛡️ Safe by default —
applypreviews as a dry run (the preview is the audit), config is validated against a JSON Schema (draft 2020-12) before any API call, and it never deletes budgets. - 📝 Budgets-first config — one reviewed
config/copilot-finops.yml(version: 3); every change ships through a pull request.
🆕 Added
- Two operations:
validate(schema + semantic lint, token-free) andapply(dry-run default; live writes withadmin:enterprise). - Two workflows:
finops-validate.yml(runs on PRs touching config/schema/action) andfinops-apply.yml(manual dry-run + weekly live schedule). - Six budget scopes:
all_users,user,cost_center,team,organization,enterprise. metered_credits_only(cost_center/team/org) — collective metered cap vs. per-user pool+metered.enforce— hard stop vs. alert-only, gated to metered/collective budgets.allow_shared_cost_center— opt in to budget a cost center that also holds other resources (otherwise skipped and reported).log-levelinput (off/error/warn/info/debug, defaultinfo) with sensitive-field redaction in debug traces.max-retriesinput — rate-limit-aware retries honoringretry-after/x-ratelimit-reset, else exponential backoff.- Outputs:
changedandsummary-path; every run writes a full markdown job summary. - Local CLI
bin/copilot-finops.js(validate/apply/migrate) with.envsupport. - v2 → v3 migration codemod:
node bin/copilot-finops.js migrate <v2-file> <v3-out>. - Copilot skill to author config conversationally, plus generated field reference
docs/config-schema.md.
🔁 Changed (breaking)
-
version: 2→version: 3. -
Config is now a single
budgets:list. v2'sai_credit_spend_policies+team_cost_center_mappingsare consolidated. -
Vocabulary renamed:
v2 v3 ai_credit_spend_policies:budgets:credit_scope: metered_onlymetered_credits_only: truecredit_scope: pool_then_metered(default)omit metered_credits_onlystop_at_limit: falseenforce: falsealert_admins: [...]alerts: [...]team: [a, b]/teams:one scope: teambudget per teamenterprise_slug:(doc field)action enterpriseinput -
Enterprise slug is no longer a config field — it's an action input (a repo/org Variable), keeping real slugs out of tracked config.
-
organizationscope is now always a direct collective metered cap on the enterprise endpoint (no cost center). Per-member org budgets aren't supported — useall_users/user, or put the users in an enterprise team and budget withscope: team. -
teamcost centers are auto-resolved or created — you no longer map them explicitly.
🗑️ Removed
- The entire Bash implementation and its runner dependencies (
gh,jq,yq). - Ongoing member sync —
team_cost_center_mappings,remove_extra_members, andcost-center-members.yml(membership is managed in GitHub). - v1/v2 schemas and the two-file (
budget-policies.yml+cost-center-members.yml) config model. - Per-policy
enterprise:override.
🔒 Security & permissions
applyneeds a classic PAT withadmin:enterprise;validateneeds no token and makes no network calls.- No
read:org/ enterprise-team read required — the engine never calls membership APIs. - Debug logs redact token/secret/password/authorization fields.
🔼 Upgrading from v2
- Migrate your config:
Review the printed warnings (org teams, per-member org caps, dropped mappings).
node bin/copilot-finops.js migrate config/copilot-finops.v2.yml config/copilot-finops.yml
- Set the enterprise slug as a Variable (
COPILOT_FINOPS_ENTERPRISE) instead of a config field. - Point your workflows at
amgdy/copilot-finops-automation@v3. - Run
finops-apply.ymlwithdry_run=trueand review the job summary before going live.
📚 Docs
README.md · docs/workflows.md · docs/setup.md · docs/permissions.md · docs/config-schema.md · docs/troubleshooting.md
Full config reference: see config/copilot-finops.example.yml (covers every scope).