@codyswann/lisa 1.52.2 → 1.52.4

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 (39) hide show
  1. package/dist/core/config.d.ts +2 -0
  2. package/dist/core/config.d.ts.map +1 -1
  3. package/dist/core/config.js.map +1 -1
  4. package/dist/core/lisa.d.ts.map +1 -1
  5. package/dist/core/lisa.js +5 -0
  6. package/dist/core/lisa.js.map +1 -1
  7. package/expo/create-only/.github/workflows/ci.yml +2 -2
  8. package/expo/create-only/.github/workflows/deploy.yml +1 -1
  9. package/expo/deletions.json +8 -0
  10. package/nestjs/create-only/.github/workflows/ci.yml +1 -1
  11. package/nestjs/create-only/.github/workflows/deploy.yml +1 -1
  12. package/nestjs/deletions.json +7 -1
  13. package/package.json +1 -1
  14. package/typescript/create-only/.github/workflows/auto-update-pr-branches.yml +24 -0
  15. package/typescript/create-only/.github/workflows/claude-ci-auto-fix.yml +20 -0
  16. package/typescript/create-only/.github/workflows/claude-code-review-response.yml +20 -0
  17. package/typescript/create-only/.github/workflows/claude-deploy-auto-fix.yml +20 -0
  18. package/typescript/create-only/.github/workflows/claude-nightly-code-complexity.yml +14 -0
  19. package/typescript/create-only/.github/workflows/claude-nightly-test-coverage.yml +14 -0
  20. package/typescript/create-only/.github/workflows/claude-nightly-test-improvement.yml +25 -0
  21. package/typescript/create-only/.github/workflows/claude.yml +25 -0
  22. package/typescript/deletions.json +20 -0
  23. package/expo/copy-overwrite/.github/workflows/build.yml +0 -75
  24. package/expo/copy-overwrite/.github/workflows/lighthouse.yml +0 -88
  25. package/expo/copy-overwrite/.github/workflows/zap-baseline.yml +0 -107
  26. package/nestjs/copy-overwrite/.github/workflows/load-test.yml +0 -285
  27. package/nestjs/copy-overwrite/.github/workflows/zap-baseline.yml +0 -123
  28. package/typescript/copy-overwrite/.github/workflows/auto-update-pr-branches.yml +0 -45
  29. package/typescript/copy-overwrite/.github/workflows/claude-ci-auto-fix.yml +0 -145
  30. package/typescript/copy-overwrite/.github/workflows/claude-code-review-response.yml +0 -112
  31. package/typescript/copy-overwrite/.github/workflows/claude-deploy-auto-fix.yml +0 -143
  32. package/typescript/copy-overwrite/.github/workflows/claude-nightly-code-complexity.yml +0 -130
  33. package/typescript/copy-overwrite/.github/workflows/claude-nightly-test-coverage.yml +0 -127
  34. package/typescript/copy-overwrite/.github/workflows/claude-nightly-test-improvement.yml +0 -129
  35. package/typescript/copy-overwrite/.github/workflows/claude.yml +0 -55
  36. package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +0 -115
  37. package/typescript/copy-overwrite/.github/workflows/create-issue-on-failure.yml +0 -176
  38. package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +0 -197
  39. package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +0 -269
@@ -1,129 +0,0 @@
1
- # This file is managed by Lisa.
2
- # Do not edit directly — changes will be overwritten on the next `lisa` run.
3
-
4
- name: Claude Nightly Test Improvement
5
-
6
- on:
7
- schedule:
8
- - cron: '0 3 * * 1-5'
9
- workflow_dispatch:
10
- inputs:
11
- mode:
12
- description: 'Analysis mode'
13
- required: true
14
- default: 'nightly'
15
- type: choice
16
- options:
17
- - nightly
18
- - general
19
-
20
- jobs:
21
- improve-tests:
22
- if: vars.ENABLE_CLAUDE_NIGHTLY == 'true'
23
- runs-on: ubuntu-latest
24
- permissions:
25
- contents: write
26
- pull-requests: write
27
- issues: write
28
- id-token: write
29
- steps:
30
- - name: Checkout repository
31
- uses: actions/checkout@v6
32
- with:
33
- fetch-depth: 0
34
-
35
- - name: Determine mode
36
- id: mode
37
- run: echo "value=${{ github.event.inputs.mode || 'nightly' }}" >> "$GITHUB_OUTPUT"
38
-
39
- - name: Detect changed files (nightly mode)
40
- id: changes
41
- if: steps.mode.outputs.value == 'nightly'
42
- run: |
43
- CHANGED_FILES=$(git log --since="24 hours ago" --name-only --pretty=format:"" -- '*.ts' '*.tsx' '*.js' '*.jsx' | sort -u | grep -v '^\s*$' || true)
44
- if [ -z "$CHANGED_FILES" ]; then
45
- echo "skip=true" >> "$GITHUB_OUTPUT"
46
- echo "No source files changed in the last 24 hours."
47
- else
48
- echo "skip=false" >> "$GITHUB_OUTPUT"
49
- EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
50
- echo "files<<$EOF" >> "$GITHUB_OUTPUT"
51
- echo "$CHANGED_FILES" >> "$GITHUB_OUTPUT"
52
- echo "$EOF" >> "$GITHUB_OUTPUT"
53
- echo "Changed files:"
54
- echo "$CHANGED_FILES"
55
- fi
56
-
57
- - name: Check for existing PR
58
- if: steps.changes.outputs.skip != 'true'
59
- id: check-pr
60
- uses: actions/github-script@v7
61
- with:
62
- script: |
63
- const pulls = await github.rest.pulls.list({
64
- owner: context.repo.owner,
65
- repo: context.repo.repo,
66
- state: 'open',
67
- per_page: 100,
68
- });
69
- const existing = pulls.data.find(pr =>
70
- pr.head.ref.startsWith('claude/nightly-test-improvement-')
71
- );
72
- core.setOutput('has_existing_pr', existing ? 'true' : 'false');
73
- if (existing) {
74
- console.log(`Found existing PR: #${existing.number} - ${existing.title}`);
75
- }
76
-
77
- - name: Run Claude Code to improve tests (nightly)
78
- if: |
79
- steps.mode.outputs.value == 'nightly' &&
80
- steps.changes.outputs.skip != 'true' &&
81
- steps.check-pr.outputs.has_existing_pr != 'true'
82
- uses: anthropics/claude-code-action@v1
83
- with:
84
- claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
85
- show_full_output: true
86
- branch_prefix: claude/nightly-test-improvement-
87
- prompt: |
88
- Analyze and improve tests related to recently changed source files.
89
-
90
- The following source files were changed in the last 24 hours:
91
- ${{ steps.changes.outputs.files }}
92
-
93
- Instructions:
94
- 1. Read CLAUDE.md and package.json for project conventions
95
- 2. For each changed source file above, find its corresponding test file(s)
96
- 3. Analyze those test files for: missing edge cases, weak assertions (toBeTruthy instead of specific values), missing error path coverage, tests that test implementation rather than behavior
97
- 4. Improve the test files with the most impactful changes
98
- 5. Run the full test suite to verify all tests pass
99
- 6. Commit changes with conventional commit messages
100
- 7. Create a PR with `gh pr create` summarizing what was improved and why
101
- claude_args: |
102
- --allowedTools "Edit,MultiEdit,Write,Read,Glob,Grep,Bash(*),Skill(*)"
103
- --max-turns 30
104
- --system-prompt "You are improving test quality for recently changed files. Read CLAUDE.md for project rules. Follow TDD practices. Focus on making tests more robust, not just adding more tests. Prefer behavior testing over implementation testing."
105
-
106
- - name: Run Claude Code to improve tests (general)
107
- if: |
108
- steps.mode.outputs.value == 'general' &&
109
- steps.check-pr.outputs.has_existing_pr != 'true'
110
- uses: anthropics/claude-code-action@v1
111
- with:
112
- claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
113
- show_full_output: true
114
- branch_prefix: claude/nightly-test-improvement-
115
- prompt: |
116
- Analyze the test suite and improve test quality.
117
-
118
- Instructions:
119
- 1. Read CLAUDE.md and package.json for project conventions
120
- 2. Scan the test files to find weak, brittle, or poorly-written tests
121
- 3. Look for: missing edge cases, weak assertions (toBeTruthy instead of specific values), missing error path coverage, tests that test implementation rather than behavior
122
- 4. Improve 3-5 test files with the most impactful changes
123
- 5. Run the full test suite to verify all tests pass
124
- 6. Commit changes with conventional commit messages
125
- 7. Create a PR with `gh pr create` summarizing what was improved and why
126
- claude_args: |
127
- --allowedTools "Edit,MultiEdit,Write,Read,Glob,Grep,Bash(*),Skill(*)"
128
- --max-turns 30
129
- --system-prompt "You are improving test quality. Read CLAUDE.md for project rules. Follow TDD practices. Focus on making tests more robust, not just adding more tests. Prefer behavior testing over implementation testing."
@@ -1,55 +0,0 @@
1
- # This file is managed by Lisa.
2
- # Do not edit directly — changes will be overwritten on the next `lisa` run.
3
-
4
- name: Claude Code
5
-
6
- on:
7
- issue_comment:
8
- types: [created]
9
- pull_request_review_comment:
10
- types: [created]
11
- issues:
12
- types: [opened, assigned]
13
- pull_request_review:
14
- types: [submitted]
15
-
16
- jobs:
17
- claude:
18
- if: |
19
- (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
20
- (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
21
- (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
22
- (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
23
- runs-on: ubuntu-latest
24
- permissions:
25
- contents: write
26
- pull-requests: write
27
- issues: write
28
- id-token: write
29
- actions: read # Required for Claude to read CI results on PRs
30
- steps:
31
- - name: Checkout repository
32
- uses: actions/checkout@v6
33
- with:
34
- fetch-depth: 1
35
-
36
- - name: Run Claude Code
37
- id: claude
38
- uses: anthropics/claude-code-action@v1
39
- with:
40
- claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
41
- show_full_output: true
42
-
43
- # This is an optional setting that allows Claude to read CI results on PRs
44
- additional_permissions: |
45
- actions: read
46
-
47
- # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
48
- # prompt: 'Update the pull request description to include a summary of changes.'
49
-
50
- # Optional: Add claude_args to customize behavior and configuration
51
- # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
52
- # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
53
- claude_args: |
54
- --allowedTools "Edit,MultiEdit,Write,Read,Glob,Grep,Bash(*),Skill(*)"
55
- --system-prompt "Follow our coding standards. Ensure all new code has tests. Look at package.json for scripts. Make sure all quality checks pass before committing. Reuse existing helper functions when possible."
@@ -1,115 +0,0 @@
1
- # This file is managed by Lisa.
2
- # Do not edit directly — changes will be overwritten on the next `lisa` run.
3
- # -----------------------------------------------------------------------------
4
- # GitHub Issue Creation Workflow
5
- # -----------------------------------------------------------------------------
6
- # ⚠️ WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT MANUALLY! ⚠️
7
- # Any changes may be overwritten by the generation process.
8
- # This workflow creates a GitHub issue when another workflow fails.
9
- # It captures details about the failure and creates a standardized issue
10
- # to help track and resolve CI/CD problems.
11
- #
12
- # Example usage in another workflow:
13
- # ```yaml
14
- # create_github_issue_on_failure:
15
- # if: failure()
16
- # uses: ./.github/workflows/github-issue-on-failure.yml
17
- # with:
18
- # workflow_name: 'My Workflow'
19
- # failed_job: 'build_and_test'
20
- # secrets:
21
- # PAT: ${{ secrets.PAT }}
22
- # ```
23
-
24
- name: 🚨 GitHub Issue on Workflow Failure
25
-
26
- on:
27
- workflow_call:
28
- inputs:
29
- workflow_name:
30
- required: true
31
- type: string
32
- description: 'Name of the workflow that failed'
33
- failed_job:
34
- required: false
35
- type: string
36
- description: 'Name of the job that failed (optional)'
37
- node_version:
38
- description: 'Node.js version to use'
39
- required: false
40
- default: '22.21.1'
41
- type: string
42
- package_manager:
43
- description: 'Package manager to use (npm, yarn, or bun)'
44
- required: false
45
- default: 'npm'
46
- type: string
47
- working_directory:
48
- description: 'Directory to run commands in (if not root)'
49
- required: false
50
- default: ''
51
- type: string
52
- secrets:
53
- PAT:
54
- required: false
55
- description: 'Personal Access Token with repo scope (falls back to GITHUB_TOKEN)'
56
-
57
- # Concurrency is managed by the parent workflow that calls this one
58
- # This avoids deadlocks between parent and child workflows
59
-
60
- jobs:
61
- create_issue:
62
- name: 📝 Create GitHub Issue
63
- runs-on: ubuntu-latest
64
- timeout-minutes: 5
65
- steps:
66
- - name: 📥 Checkout repository
67
- uses: actions/checkout@v4
68
-
69
- - name: 🔧 Setup Node.js
70
- uses: actions/setup-node@v4
71
- with:
72
- node-version: ${{ inputs.node_version }}
73
- cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
74
-
75
- - name: 🔖 Create Issue
76
- uses: actions/github-script@v7
77
- with:
78
- github-token: ${{ secrets.PAT || github.token }}
79
- script: |
80
- // Get repository and run information
81
- const { owner, repo } = context.repo;
82
- const runId = context.runId;
83
- const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`;
84
-
85
- // Get workflow information from inputs
86
- const workflowName = '${{ inputs.workflow_name }}';
87
- const failedJob = '${{ inputs.failed_job }}' || 'Unknown';
88
-
89
- // Create standardized issue title and body
90
- const title = `🚨 Workflow Failure: ${workflowName}${failedJob !== 'Unknown' ? ` - ${failedJob}` : ''}`;
91
- const body = `
92
- ## Workflow Failure
93
-
94
- The "${workflowName}" workflow has failed${failedJob !== 'Unknown' ? ` in job: **${failedJob}**` : ''}.
95
-
96
- ### Details
97
- - **Workflow Run**: [View Run Details](${runUrl})
98
- - **Commit**: ${context.sha}
99
- - **Commit Message**: ${context.payload.head_commit ? context.payload.head_commit.message : 'N/A'}
100
- - **Triggered by**: ${context.actor}
101
- - **Failed at**: ${new Date().toISOString()}
102
-
103
- Please investigate the workflow logs for more details on the failure.
104
- `;
105
-
106
- // Create the issue
107
- await github.rest.issues.create({
108
- owner,
109
- repo,
110
- title,
111
- body,
112
- labels: ['bug', 'automation', 'ci-failure']
113
- });
114
-
115
- console.log(`Issue created for workflow failure: ${runUrl}`);
@@ -1,176 +0,0 @@
1
- # This file is managed by Lisa.
2
- # Do not edit directly — changes will be overwritten on the next `lisa` run.
3
- # -----------------------------------------------------------------------------
4
- # Cascading Issue Creation Workflow
5
- # -----------------------------------------------------------------------------
6
- # ⚠️ WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT MANUALLY! ⚠️
7
- # Any changes may be overwritten by the generation process.
8
- #
9
- # This is a dispatcher workflow that intelligently routes failures to the
10
- # appropriate issue tracking system based on available credentials:
11
- #
12
- # 1. If Sentry credentials exist → Create Sentry issue
13
- # 2. Else if Jira credentials exist → Create Jira issue
14
- # 3. Else → Create GitHub issue (fallback)
15
- #
16
- # Example usage in another workflow:
17
- # ```yaml
18
- # create_issue_on_failure:
19
- # if: failure()
20
- # uses: ./.github/workflows/create-issue-on-failure.yml
21
- # with:
22
- # workflow_name: 'My Workflow'
23
- # failed_job: 'build_and_test'
24
- # secrets: inherit
25
- # ```
26
- #
27
- # The workflow automatically detects which system to use based on repository
28
- # variables and secrets. No configuration needed in the calling workflow.
29
-
30
- name: 📌 Create Issue on Failure (Auto-Dispatch)
31
-
32
- on:
33
- workflow_call:
34
- inputs:
35
- workflow_name:
36
- required: true
37
- type: string
38
- description: 'Name of the workflow that failed'
39
- failed_job:
40
- required: false
41
- type: string
42
- description: 'Name of the job that failed (optional)'
43
- issue_type:
44
- required: false
45
- type: string
46
- default: 'Bug'
47
- description: 'Type of issue to create (Bug, Task, etc.)'
48
- environment:
49
- required: false
50
- type: string
51
- default: 'production'
52
- description: 'Environment where the failure occurred'
53
- level:
54
- required: false
55
- type: string
56
- default: 'error'
57
- description: 'Severity level (debug, info, warning, error, fatal)'
58
- node_version:
59
- description: 'Node.js version to use'
60
- required: false
61
- default: '22.21.1'
62
- type: string
63
- package_manager:
64
- description: 'Package manager to use (npm, yarn, or bun)'
65
- required: false
66
- default: 'npm'
67
- type: string
68
- working_directory:
69
- description: 'Directory to run commands in (if not root)'
70
- required: false
71
- default: ''
72
- type: string
73
- secrets:
74
- SENTRY_AUTH_TOKEN:
75
- required: false
76
- description: 'Sentry Auth Token (if using Sentry)'
77
- JIRA_API_TOKEN:
78
- required: false
79
- description: 'Jira API token (if using Jira)'
80
- PAT:
81
- required: false
82
- description: 'Personal Access Token (if using GitHub Issues)'
83
-
84
- # Concurrency is managed by the parent workflow that calls this one
85
- # This avoids deadlocks between parent and child workflows
86
-
87
- jobs:
88
- # Dispatch job determines which system to use based on available credentials
89
- dispatch:
90
- name: 🧭 Determine Issue Tracking System
91
- runs-on: ubuntu-latest
92
- timeout-minutes: 5
93
- outputs:
94
- use_sentry: ${{ steps.check.outputs.sentry }}
95
- use_jira: ${{ steps.check.outputs.jira }}
96
- use_github: ${{ steps.check.outputs.github }}
97
- steps:
98
- - name: 🔍 Check Available Credentials
99
- id: check
100
- run: |
101
- # Check for Sentry (highest priority)
102
- if [ -n "${{ vars.SENTRY_ORG }}" ] && [ -n "${{ vars.SENTRY_PROJECT }}" ] && [ -n "${{ secrets.SENTRY_AUTH_TOKEN }}" ]; then
103
- echo "sentry=true" >> $GITHUB_OUTPUT
104
- echo "jira=false" >> $GITHUB_OUTPUT
105
- echo "github=false" >> $GITHUB_OUTPUT
106
- echo "✓ Using Sentry for issue tracking"
107
- exit 0
108
- fi
109
-
110
- # Check for Jira (second priority)
111
- if [ -n "${{ vars.JIRA_BASE_URL }}" ] && [ -n "${{ vars.JIRA_USER_EMAIL }}" ] && [ -n "${{ vars.JIRA_PROJECT_KEY }}" ] && [ -n "${{ secrets.JIRA_API_TOKEN }}" ]; then
112
- echo "sentry=false" >> $GITHUB_OUTPUT
113
- echo "jira=true" >> $GITHUB_OUTPUT
114
- echo "github=false" >> $GITHUB_OUTPUT
115
- echo "✓ Using Jira for issue tracking"
116
- exit 0
117
- fi
118
-
119
- # Fall back to GitHub (always available)
120
- echo "sentry=false" >> $GITHUB_OUTPUT
121
- echo "jira=false" >> $GITHUB_OUTPUT
122
- echo "github=true" >> $GITHUB_OUTPUT
123
- echo "✓ Using GitHub Issues for issue tracking (fallback)"
124
-
125
- # Create Sentry issue (if available)
126
- create_sentry_issue:
127
- name: 📌 Create Sentry Issue
128
- needs: [dispatch]
129
- if: ${{ needs.dispatch.outputs.use_sentry == 'true' }}
130
- uses: ./.github/workflows/create-sentry-issue-on-failure.yml
131
- with:
132
- workflow_name: ${{ inputs.workflow_name }}
133
- failed_job: ${{ inputs.failed_job }}
134
- SENTRY_ORG: ${{ vars.SENTRY_ORG }}
135
- SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }}
136
- environment: ${{ inputs.environment }}
137
- level: ${{ inputs.level }}
138
- node_version: ${{ inputs.node_version }}
139
- package_manager: ${{ inputs.package_manager }}
140
- working_directory: ${{ inputs.working_directory }}
141
- secrets:
142
- SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
143
-
144
- # Create Jira issue (if available)
145
- create_jira_issue:
146
- name: 📌 Create Jira Issue
147
- needs: [dispatch]
148
- if: ${{ needs.dispatch.outputs.use_jira == 'true' }}
149
- uses: ./.github/workflows/create-jira-issue-on-failure.yml
150
- with:
151
- workflow_name: ${{ inputs.workflow_name }}
152
- failed_job: ${{ inputs.failed_job }}
153
- issue_type: ${{ inputs.issue_type }}
154
- JIRA_BASE_URL: ${{ vars.JIRA_BASE_URL }}
155
- JIRA_USER_EMAIL: ${{ vars.JIRA_USER_EMAIL }}
156
- JIRA_PROJECT_KEY: ${{ vars.JIRA_PROJECT_KEY }}
157
- node_version: ${{ inputs.node_version }}
158
- package_manager: ${{ inputs.package_manager }}
159
- working_directory: ${{ inputs.working_directory }}
160
- secrets:
161
- JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
162
-
163
- # Create GitHub issue (fallback)
164
- create_github_issue:
165
- name: 📌 Create GitHub Issue
166
- needs: [dispatch]
167
- if: ${{ needs.dispatch.outputs.use_github == 'true' }}
168
- uses: ./.github/workflows/create-github-issue-on-failure.yml
169
- with:
170
- workflow_name: ${{ inputs.workflow_name }}
171
- failed_job: ${{ inputs.failed_job }}
172
- node_version: ${{ inputs.node_version }}
173
- package_manager: ${{ inputs.package_manager }}
174
- working_directory: ${{ inputs.working_directory }}
175
- secrets:
176
- PAT: ${{ secrets.PAT }}
@@ -1,197 +0,0 @@
1
- # This file is managed by Lisa.
2
- # Do not edit directly — changes will be overwritten on the next `lisa` run.
3
- # -----------------------------------------------------------------------------
4
- # Jira Issue Creation Workflow
5
- # -----------------------------------------------------------------------------
6
- # ⚠️ WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT MANUALLY! ⚠️
7
- # Any changes may be overwritten by the generation process.
8
- # This workflow creates a Jira issue when another workflow fails.
9
- # It captures details about the failure and creates a standardized issue
10
- # to help track and resolve CI/CD problems in Jira.
11
- #
12
- # Example usage in another workflow:
13
- # ```yaml
14
- # create_jira_issue_on_failure:
15
- # if: failure()
16
- # uses: ./.github/workflows/jira-issue-on-failure.yml
17
- # with:
18
- # workflow_name: 'My Workflow'
19
- # failed_job: 'build_and_test'
20
- # JIRA_BASE_URL: ${{ vars.JIRA_BASE_URL }}
21
- # JIRA_USER_EMAIL: ${{ vars.JIRA_USER_EMAIL }}
22
- # JIRA_PROJECT_KEY: ${{ vars.JIRA_PROJECT_KEY }}
23
- # secrets:
24
- # JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
25
- # ```
26
-
27
- name: 🔖 Jira Issue on Workflow Failure
28
-
29
- on:
30
- workflow_call:
31
- inputs:
32
- workflow_name:
33
- required: true
34
- type: string
35
- description: 'Name of the workflow that failed'
36
- failed_job:
37
- required: false
38
- type: string
39
- description: 'Name of the job that failed (optional)'
40
- issue_type:
41
- required: false
42
- type: string
43
- default: 'Bug'
44
- description: 'Type of Jira issue to create (Bug, Task, etc.)'
45
- JIRA_BASE_URL:
46
- required: true
47
- type: string
48
- description: 'Jira instance base URL (e.g., https://your-domain.atlassian.net)'
49
- JIRA_USER_EMAIL:
50
- required: true
51
- type: string
52
- description: 'Email address of the Jira user associated with the API token'
53
- JIRA_PROJECT_KEY:
54
- required: true
55
- type: string
56
- description: 'The key of the Jira project where issues should be created'
57
- node_version:
58
- description: 'Node.js version to use'
59
- required: false
60
- default: '22.21.1'
61
- type: string
62
- package_manager:
63
- description: 'Package manager to use (npm, yarn, or bun)'
64
- required: false
65
- default: 'npm'
66
- type: string
67
- working_directory:
68
- description: 'Directory to run commands in (if not root)'
69
- required: false
70
- default: ''
71
- type: string
72
- secrets:
73
- JIRA_API_TOKEN:
74
- required: true
75
- description: 'Jira API token for authentication'
76
-
77
- # Concurrency is managed by the parent workflow that calls this one
78
- # This avoids deadlocks between parent and child workflows
79
-
80
- jobs:
81
- create_jira_issue:
82
- name: 📝 Create Jira Issue
83
- runs-on: ubuntu-latest
84
- timeout-minutes: 5
85
- steps:
86
- - name: 📥 Checkout repository
87
- uses: actions/checkout@v4
88
-
89
- - name: 🔧 Setup Node.js
90
- uses: actions/setup-node@v4
91
- with:
92
- node-version: ${{ inputs.node_version }}
93
- cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
94
-
95
- - name: 🔖 Create Jira Issue
96
- id: create_jira_issue
97
- run: |
98
- cd "${{ inputs.working_directory || '.' }}"
99
-
100
- # Set variables
101
- WORKFLOW_NAME="${{ inputs.workflow_name }}"
102
- FAILED_JOB="${{ inputs.failed_job || 'Unknown' }}"
103
- ISSUE_TYPE="${{ inputs.issue_type }}"
104
- RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
105
-
106
- # Get commit message, handling special characters properly
107
- # Remove leading/trailing whitespace and escape for shell
108
- COMMIT_MESSAGE="${{ github.event.head_commit.message || 'N/A' }}"
109
-
110
- # Create summary with failure details
111
- if [ "$FAILED_JOB" != "Unknown" ]; then
112
- SUMMARY="🚨 CI Failure: ${WORKFLOW_NAME} - ${FAILED_JOB}"
113
- else
114
- SUMMARY="🚨 CI Failure: ${WORKFLOW_NAME}"
115
- fi
116
-
117
- # Create Jira description with properly escaped values
118
- FAILED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
119
-
120
- # Create JSON payload for Jira API using jq for proper escaping
121
- # All dynamic content is passed as jq arguments to ensure proper escaping
122
- PAYLOAD=$(jq -n \
123
- --arg key "${{ inputs.JIRA_PROJECT_KEY }}" \
124
- --arg summary "${SUMMARY}" \
125
- --arg workflow_name "${WORKFLOW_NAME}" \
126
- --arg failed_job "${FAILED_JOB}" \
127
- --arg run_url "${RUN_URL}" \
128
- --arg repository "${{ github.repository }}" \
129
- --arg commit "${{ github.sha }}" \
130
- --arg commit_message "${COMMIT_MESSAGE}" \
131
- --arg triggered_by "${{ github.actor }}" \
132
- --arg failed_at "${FAILED_AT}" \
133
- --arg issuetype "${ISSUE_TYPE}" \
134
- '{
135
- "fields": {
136
- "project": {
137
- "key": $key
138
- },
139
- "summary": $summary,
140
- "description": ("h2. Workflow Failure\n\nThe \"" + $workflow_name + "\" workflow has failed" + (if $failed_job != "Unknown" then " in job: *" + $failed_job + "*" else "" end) + ".\n\nh3. Details\n* *Workflow Run*: [View Run Details|" + $run_url + "]\n* *Repository*: " + $repository + "\n* *Commit*: " + $commit + "\n* *Commit Message*: " + $commit_message + "\n* *Triggered by*: " + $triggered_by + "\n* *Failed at*: " + $failed_at + "\n\nPlease investigate the workflow logs for more details on the failure."),
141
- "issuetype": {
142
- "name": $issuetype
143
- },
144
- "labels": ["ci-failure", "automated"]
145
- }
146
- }')
147
-
148
- # Debug: Print the payload to see what's being sent
149
- echo "Debug: Generated payload:"
150
- echo "$PAYLOAD" | jq .
151
-
152
- # Call Jira API to create issue
153
- RESPONSE=$(curl -s -D- \
154
- -u "${{ inputs.JIRA_USER_EMAIL }}:${{ secrets.JIRA_API_TOKEN }}" \
155
- -X POST \
156
- -H "Content-Type: application/json" \
157
- --data "${PAYLOAD}" \
158
- "${{ inputs.JIRA_BASE_URL }}/rest/api/2/issue")
159
-
160
- # Extract issue key from response
161
- ISSUE_KEY=$(echo "$RESPONSE" | grep -o 'key":"[^"]*' | cut -d'"' -f3)
162
-
163
- if [ -n "$ISSUE_KEY" ]; then
164
- echo "Successfully created Jira issue: $ISSUE_KEY"
165
- echo "issue_key=$ISSUE_KEY" >> $GITHUB_OUTPUT
166
- echo "issue_url=${{ inputs.JIRA_BASE_URL }}/browse/$ISSUE_KEY" >> $GITHUB_OUTPUT
167
- else
168
- echo "Failed to create Jira issue. API response:"
169
- echo "$RESPONSE"
170
-
171
- # Extract HTTP status code for better error diagnosis
172
- HTTP_STATUS=$(echo "$RESPONSE" | grep -oE "^HTTP/[0-9.]+ [0-9]+" | awk '{print $2}')
173
- if [ -n "$HTTP_STATUS" ]; then
174
- echo "HTTP Status Code: $HTTP_STATUS"
175
-
176
- if [ "$HTTP_STATUS" = "404" ]; then
177
- echo "Error: API endpoint not found. Please check JIRA_BASE_URL configuration."
178
- elif [ "$HTTP_STATUS" = "401" ]; then
179
- echo "Error: Authentication failed. Please check JIRA_USER_EMAIL and JIRA_API_TOKEN."
180
- elif [ "$HTTP_STATUS" = "403" ]; then
181
- echo "Error: Permission denied. Please check user permissions."
182
- fi
183
- fi
184
-
185
- # Print payload for debugging (with sensitive data redacted)
186
- echo "Request payload (redacted):"
187
- echo "$PAYLOAD" | sed 's/"key":"[^"]*"/"key":"***"/g'
188
-
189
- exit 1
190
- fi
191
-
192
- - name: 📢 Report Issue Creation
193
- if: steps.create_jira_issue.outputs.issue_key
194
- run: |
195
- cd "${{ inputs.working_directory || '.' }}"
196
- echo "Created Jira issue: ${{ steps.create_jira_issue.outputs.issue_key }}"
197
- echo "Issue URL: ${{ steps.create_jira_issue.outputs.issue_url }}"