@codyswann/lisa 2.196.0 → 2.196.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa-agy/plugin.json +1 -1
  5. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  6. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  7. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  8. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  9. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  11. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa-expo-agy/plugin.json +1 -1
  15. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  19. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  20. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  25. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  29. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  30. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  34. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  35. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-rails-agy/plugin.json +1 -1
  40. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  45. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  50. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  52. package/scripts/lisa-github-repo-setup.sh +11 -1
  53. package/scripts/lisa-github-rulesets.sh +80 -17
  54. package/scripts/setup-deploy-key.sh +5 -4
  55. package/cdk/github-rulesets/cdk-validation.json +0 -43
package/package.json CHANGED
@@ -94,7 +94,7 @@
94
94
  "ws": ">=8.20.1"
95
95
  },
96
96
  "name": "@codyswann/lisa",
97
- "version": "2.196.0",
97
+ "version": "2.196.1",
98
98
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
99
99
  "main": "dist/index.js",
100
100
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.196.0",
3
+ "version": "2.196.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -56,7 +56,17 @@ echo "==> Step 3/3: deploy key"
56
56
  if [[ "$DRY_RUN" == "true" ]]; then
57
57
  echo "[DRY RUN] Would ensure a write-access deploy key + DEPLOY_KEY secret exist"
58
58
  else
59
- (cd "$PROJECT_PATH" && bash "$SCRIPT_DIR/setup-deploy-key.sh" --yes)
59
+ deploy_output=$(cd "$PROJECT_PATH" && bash "$SCRIPT_DIR/setup-deploy-key.sh" --yes 2>&1)
60
+ deploy_rc=$?
61
+ echo "$deploy_output"
62
+ if [[ $deploy_rc -ne 0 ]]; then
63
+ if echo "$deploy_output" | grep -qi "deploy keys are disabled"; then
64
+ # Org policy, not a repo problem — settings/rulesets still applied.
65
+ echo "⚠ Deploy keys are disabled by organization policy — skipped. Release workflows needing DEPLOY_KEY will not work until an org admin re-enables deploy keys."
66
+ else
67
+ exit $deploy_rc
68
+ fi
69
+ fi
60
70
  fi
61
71
 
62
72
  echo ""
@@ -344,32 +344,95 @@ apply_ruleset() {
344
344
  return 0
345
345
  fi
346
346
 
347
- # Create temp file for the request body
348
- local temp_file
349
- temp_file=$(mktemp)
350
- echo "$clean_template" > "$temp_file"
351
-
352
347
  if [[ -n "$existing_id" ]]; then
353
348
  log_info "Updating ruleset '$ruleset_name' (id: $existing_id)..."
354
- if gh api -X PUT "repos/$repo/rulesets/$existing_id" --input "$temp_file" > /dev/null; then
355
- log_success "Updated ruleset '$ruleset_name'"
356
- else
357
- log_error "Failed to update ruleset '$ruleset_name'"
358
- rm -f "$temp_file"
359
- return 1
360
- fi
361
349
  else
362
350
  log_info "Creating ruleset '$ruleset_name'..."
363
- if gh api -X POST "repos/$repo/rulesets" --input "$temp_file" > /dev/null; then
364
- log_success "Created ruleset '$ruleset_name'"
351
+ fi
352
+
353
+ if apply_with_integration_fallback "$repo" "$ruleset_name" "$clean_template" "$existing_id"; then
354
+ return 0
355
+ fi
356
+ log_error "Failed to apply ruleset '$ruleset_name'"
357
+ return 1
358
+ }
359
+
360
+ # Send the ruleset to GitHub. App-based required checks (CodeRabbit,
361
+ # GitGuardian, ...) are rejected with "Invalid integration ids" on repos
362
+ # where that app is not installed — and no user-token API can list per-repo
363
+ # installations up front. So on that specific error, retry with app-based
364
+ # checks progressively removed: first each single app id, then all of them,
365
+ # keeping as many checks as the repo actually supports.
366
+ apply_with_integration_fallback() {
367
+ local repo="$1"
368
+ local ruleset_name="$2"
369
+ local payload="$3"
370
+ local existing_id="$4"
371
+
372
+ local temp_file error_output
373
+ temp_file=$(mktemp)
374
+
375
+ # Capture stdout AND stderr — gh prints the API error body (which carries
376
+ # the "Invalid integration ids" detail) on stdout, not stderr.
377
+ send_ruleset() {
378
+ echo "$1" > "$temp_file"
379
+ if [[ -n "$existing_id" ]]; then
380
+ error_output=$(gh api -X PUT "repos/$repo/rulesets/$existing_id" --input "$temp_file" 2>&1)
365
381
  else
366
- log_error "Failed to create ruleset '$ruleset_name'"
367
- rm -f "$temp_file"
368
- return 1
382
+ error_output=$(gh api -X POST "repos/$repo/rulesets" --input "$temp_file" 2>&1)
369
383
  fi
384
+ }
385
+
386
+ if send_ruleset "$payload"; then
387
+ log_success "Applied ruleset '$ruleset_name'"
388
+ rm -f "$temp_file"
389
+ return 0
370
390
  fi
371
391
 
392
+ if ! echo "$error_output" | grep -qi "invalid integration ids"; then
393
+ log_error "$error_output"
394
+ rm -f "$temp_file"
395
+ return 1
396
+ fi
397
+
398
+ local app_ids
399
+ app_ids=$(echo "$payload" | jq --argjson actions "$ACTIONS_INTEGRATION_ID" \
400
+ '[.rules[]? | select(.type=="required_status_checks") | .parameters.required_status_checks[]?.integration_id | select(. != null and . != $actions)] | unique | .[]')
401
+
402
+ local drop_filter='
403
+ .rules |= (
404
+ map(
405
+ if .type == "required_status_checks" then
406
+ .parameters.required_status_checks |= map(select((.integration_id // -1) as $i | ($drop | index($i)) | not))
407
+ else . end
408
+ )
409
+ | map(select(.type != "required_status_checks" or (.parameters.required_status_checks | length) > 0))
410
+ )'
411
+
412
+ # Each single app id first (keep the most checks), then all app ids.
413
+ local candidates=()
414
+ local app_id
415
+ for app_id in $app_ids; do
416
+ candidates+=("[$app_id]")
417
+ done
418
+ candidates+=("$(echo "$app_ids" | jq -s -c .)")
419
+
420
+ local drop attempt
421
+ for drop in "${candidates[@]}"; do
422
+ attempt=$(echo "$payload" | jq --argjson drop "$drop" --argjson actions "$ACTIONS_INTEGRATION_ID" "$drop_filter")
423
+ if [[ $(echo "$attempt" | jq '(.rules // [1]) | length') -eq 0 ]]; then
424
+ continue
425
+ fi
426
+ if send_ruleset "$attempt"; then
427
+ log_warning "Applied ruleset '$ruleset_name' without app integration id(s) $drop — app(s) not installed on this repository"
428
+ rm -f "$temp_file"
429
+ return 0
430
+ fi
431
+ done
432
+
433
+ log_error "$error_output"
372
434
  rm -f "$temp_file"
435
+ return 1
373
436
  }
374
437
 
375
438
  ##############################################################################
@@ -89,8 +89,9 @@ if [[ "$YES_MODE" == "true" ]]; then
89
89
  exit 1
90
90
  fi
91
91
 
92
- HAS_KEY=$(gh repo deploy-key list --repo "$OWNER/$REPO" --json title \
93
- --jq --arg t "$KEY_TITLE" '[.[] | select(.title == $t)] | length' 2>/dev/null || echo 0)
92
+ # NOTE: gh's --jq flag does not support jq --arg; pipe through jq instead.
93
+ HAS_KEY=$(gh repo deploy-key list --repo "$OWNER/$REPO" --json title 2>/dev/null \
94
+ | jq --arg t "$KEY_TITLE" '[.[] | select(.title == $t)] | length' 2>/dev/null || echo 0)
94
95
  HAS_SECRET=$(gh secret list --repo "$OWNER/$REPO" --json name \
95
96
  --jq '[.[] | select(.name == "DEPLOY_KEY")] | length' 2>/dev/null || echo 0)
96
97
  if [[ "$HAS_KEY" -gt 0 && "$HAS_SECRET" -gt 0 ]]; then
@@ -107,8 +108,8 @@ if [[ "$YES_MODE" == "true" ]]; then
107
108
 
108
109
  # A stale key under the same title blocks re-adding; replace it.
109
110
  if [[ "$HAS_KEY" -gt 0 ]]; then
110
- gh repo deploy-key list --repo "$OWNER/$REPO" --json id,title \
111
- --jq --arg t "$KEY_TITLE" '.[] | select(.title == $t) | .id' 2>/dev/null \
111
+ gh repo deploy-key list --repo "$OWNER/$REPO" --json id,title 2>/dev/null \
112
+ | jq -r --arg t "$KEY_TITLE" '.[] | select(.title == $t) | .id' \
112
113
  | while read -r key_id; do
113
114
  gh repo deploy-key delete "$key_id" --repo "$OWNER/$REPO" || true
114
115
  done
@@ -1,43 +0,0 @@
1
- {
2
- "name": "cdk validation",
3
- "target": "branch",
4
- "enforcement": "active",
5
- "conditions": {
6
- "ref_name": {
7
- "exclude": [],
8
- "include": [
9
- "~DEFAULT_BRANCH",
10
- "refs/heads/dev",
11
- "refs/heads/staging",
12
- "refs/heads/main"
13
- ]
14
- }
15
- },
16
- "bypass_actors": [
17
- {
18
- "actor_id": null,
19
- "actor_type": "DeployKey",
20
- "bypass_mode": "always"
21
- },
22
- {
23
- "actor_id": 5,
24
- "actor_type": "RepositoryRole",
25
- "bypass_mode": "always"
26
- }
27
- ],
28
- "rules": [
29
- {
30
- "type": "required_status_checks",
31
- "parameters": {
32
- "strict_required_status_checks_policy": false,
33
- "do_not_enforce_on_create": true,
34
- "required_status_checks": [
35
- {
36
- "context": "🏗️ CDK Validation",
37
- "integration_id": 15368
38
- }
39
- ]
40
- }
41
- }
42
- ]
43
- }