Skip to content

Commit 979d64d

Browse files
GHA-189 Adjust to new Jira taxonomy (#97)
1 parent dc3be18 commit 979d64d

File tree

11 files changed

+267
-58
lines changed

11 files changed

+267
-58
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Part of
22
<!--
33
Only for standalone PRs without Jira issue in the PR title:
4-
* Replace this comment with Epic ID to create a new Task in Jira
4+
* Replace this comment with Epic ID to create a new Maintenance ticket in Jira
55
* Replace this comment with Issue ID to create a new Sub-Task in Jira
6-
* Ignore or delete this note to create a new Task in Jira without a parent
6+
* Ignore or delete this note to create a new Maintenance ticket in Jira without a parent
77
-->

.github/workflows/automated-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ on:
129129
description: "Jira issue categories to include in the release notes"
130130
required: false
131131
type: string
132-
default: "New Feature,False Positive,False Negative,Bug,Improvement,Task"
132+
default: "Feature,False Positive,False Negative,Bug,Security"
133133

134134
outputs:
135135
new-version:

.github/workflows/test-get-jira-release-notes.yml

Lines changed: 140 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,144 @@ jobs:
131131
test-default-issue-categories:
132132
name: Test Action Integration with Default Issue Categories
133133
runs-on: ubuntu-latest
134+
permissions:
135+
contents: read
136+
id-token: write
137+
steps:
138+
- name: Checkout code
139+
uses: actions/checkout@v4
140+
141+
- name: Get release notes from a sandbox project
142+
id: test-sandbox
143+
uses: ./get-jira-release-notes
144+
with:
145+
jira-project-key: 'SONARIAC'
146+
jira-version-name: '1.52'
147+
use-jira-sandbox: 'true'
148+
149+
- name: Output results
150+
run: |
151+
echo "Jira Release URL: ${{ steps.test-sandbox.outputs.jira-release-url }}"
152+
echo "Jira Release Issue Filter URL: ${{ steps.test-sandbox.outputs.jira-release-issue-filter-url }}"
153+
echo "Release Notes:"
154+
echo "${{ steps.test-sandbox.outputs.release-notes }}"
155+
echo "Jira Release Notes:"
156+
echo "${{ steps.test-sandbox.outputs.jira-release-notes }}"
157+
158+
- name: Verify Jira Release URL
159+
run: |
160+
if [[ "${{ steps.test-sandbox.outputs.jira-release-url }}" != https://sonarsource-sandbox-608.atlassian.net/projects/SONARIAC/versions/*/tab/release-report-all-issues ]]; then
161+
echo "❌ Jira Release URL format is incorrect"
162+
exit 1
163+
else
164+
echo "✅ Jira Release URL format is correct"
165+
fi
166+
167+
- name: Verify Jira Release Issue Filter URL
168+
run: |
169+
if [[ "${{ steps.test-sandbox.outputs.jira-release-issue-filter-url }}" != https://sonarsource-sandbox-608.atlassian.net/issues/?jql=fixVersion%3D23819 ]]; then
170+
echo "❌ Jira Release Issue Filter URL is incorrect"
171+
echo "Expected: https://sonarsource-sandbox-608.atlassian.net/issues/?jql=fixVersion%3D23819"
172+
echo "Got: ${{ steps.test-sandbox.outputs.jira-release-issue-filter-url }}"
173+
exit 1
174+
else
175+
echo "✅ Jira Release Issue Filter URL is correct"
176+
fi
177+
178+
- name: Verify Release Notes Content
179+
run: |
180+
if grep -q "### Feature" <<< "${{ steps.test-sandbox.outputs.release-notes }}"; then
181+
echo "✅ Release Notes contain default issue categories"
182+
else
183+
echo "❌ Release Notes are missing some default issue categories"
184+
exit 1
185+
fi
186+
187+
if grep -q "### Maintenance" <<< "${{ steps.test-sandbox.outputs.release-notes }}"; then
188+
echo "❌ Release Notes should not contain Maintenance category with default settings"
189+
exit 1
190+
else
191+
echo "✅ Release Notes correctly exclude Maintenance category"
192+
fi
193+
194+
- name: Verify Jira Release Notes Content
195+
run: |
196+
if grep -q "h3. Feature" <<< "${{ steps.test-sandbox.outputs.jira-release-notes }}"; then
197+
echo "✅ Jira Release Notes contain default issue category"
198+
else
199+
echo "❌ Jira Release Notes are missing some default issue categories"
200+
exit 1
201+
fi
202+
203+
if grep -q "h3. Maintenance" <<< "${{ steps.test-sandbox.outputs.jira-release-notes }}"; then
204+
echo "❌ Jira Release Notes should not contain Maintenance category with default settings"
205+
exit 1
206+
else
207+
echo "✅ Jira Release Notes correctly exclude Maintenance category"
208+
fi
209+
210+
test-custom-issue-categories:
211+
name: Test Action Integration with Custom Issue Categories
212+
runs-on: ubuntu-latest
213+
permissions:
214+
contents: read
215+
id-token: write
216+
steps:
217+
- name: Checkout code
218+
uses: actions/checkout@v4
219+
220+
- name: Get release notes from a sandbox project with custom issue types
221+
id: test-sandbox-custom
222+
uses: ./get-jira-release-notes
223+
with:
224+
jira-project-key: 'SONARIAC'
225+
jira-version-name: '1.52'
226+
use-jira-sandbox: 'true'
227+
issue-types: 'Maintenance,Bug,Security'
228+
229+
- name: Output results
230+
run: |
231+
echo "Jira Release URL: ${{ steps.test-sandbox-custom.outputs.jira-release-url }}"
232+
echo "Release Notes:"
233+
echo "${{ steps.test-sandbox-custom.outputs.release-notes }}"
234+
echo "Jira Release Notes:"
235+
echo "${{ steps.test-sandbox-custom.outputs.jira-release-notes }}"
236+
237+
- name: Verify Release Notes Content
238+
run: |
239+
if grep -q "### Maintenance" <<< "${{ steps.test-sandbox-custom.outputs.release-notes }}"; then
240+
echo "✅ Release Notes contain Maintenance category as specified"
241+
else
242+
echo "❌ Release Notes are missing Maintenance category"
243+
exit 1
244+
fi
245+
246+
if grep -q "### Feature" <<< "${{ steps.test-sandbox-custom.outputs.release-notes }}"; then
247+
echo "❌ Release Notes should not contain Feature category with custom settings"
248+
exit 1
249+
else
250+
echo "✅ Release Notes correctly exclude Feature category"
251+
fi
252+
253+
- name: Verify Jira Release Notes Content
254+
run: |
255+
if grep -q "h3. Maintenance" <<< "${{ steps.test-sandbox-custom.outputs.jira-release-notes }}"; then
256+
echo "✅ Jira Release Notes contain Maintenance category as specified"
257+
else
258+
echo "❌ Jira Release Notes are missing Maintenance category"
259+
exit 1
260+
fi
261+
262+
if grep -q "h3. Feature" <<< "${{ steps.test-sandbox-custom.outputs.jira-release-notes }}"; then
263+
echo "❌ Jira Release Notes should not contain Feature category with custom settings"
264+
exit 1
265+
else
266+
echo "✅ Jira Release Notes correctly exclude Feature category"
267+
fi
268+
269+
test-default-issue-categories-deprecated-taxonomy:
270+
name: Test Action Integration with Default Issue Categories on project with deprecated Jira taxonomy
271+
runs-on: ubuntu-latest
134272
permissions:
135273
contents: read
136274
id-token: write
@@ -207,8 +345,8 @@ jobs:
207345
echo "✅ Jira Release Notes correctly exclude Task category"
208346
fi
209347
210-
test-custom-issue-categories:
211-
name: Test Action Integration with Custom Issue Categories
348+
test-custom-issue-categories-deprecated-taxonomy:
349+
name: Test Action Integration with Custom Issue Categories on project with deprecated Jira taxonomy
212350
runs-on: ubuntu-latest
213351
permissions:
214352
contents: read
@@ -265,4 +403,3 @@ jobs:
265403
else
266404
echo "✅ Jira Release Notes correctly exclude Improvement category"
267405
fi
268-

.github/workflows/test-publish-github-release.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,9 @@ jobs:
124124
release-notes: |
125125
# Release notes - Test - 1.0.3
126126
127-
### New Feature
127+
### Feature
128128
[SONARIAC-2361](https://example.com) S4830: Server certificates should be verified during SSL/TLS connections
129129
[SONARIAC-2366](https://example.com) S6573: Expanded filenames should not become options
130-
131-
### Improvement
132130
[SONARIAC-2230](https://example.com) S6596 should have different message when tag is present but not compliant
133131
[SONARIAC-2301](https://example.com) Improve "ShellCmdDetector" performance
134132

create-integration-ticket/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ This action requires:
105105
## Features
106106
107107
- Creates a Jira ticket in the specified project with optional description
108-
- Automatically detects appropriate issue type (Task, Improvement, or first available)
108+
- Automatically detects appropriate issue type (Maintenance, Feature, Task, Improvement, or first available)
109109
- Links the created ticket to an existing ticket using the specified link type
110110
- Validates that the release ticket exists before creating the new ticket
111111
- Gracefully handles description field limitations (warns if description cannot be set but continues)

create-integration-ticket/create_integration_ticket.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,11 @@ def create_integration_ticket(jira_client, args):
8888
createmeta_data = jira_client.createmeta(projectKeys=args.target_jira_project, expand='projects.issuetypes')
8989
issue_types = createmeta_data['projects'][0]['issuetypes']
9090

91-
# Try to find a suitable issue type (prefer improvement, then first available)
91+
# Try to find a suitable issue type (prefer feature, then first available)
9292
issue_type = None
9393
for it in issue_types:
94-
if it['name'].lower() in ['improvement', 'task']:
94+
# Improvement and Task are included for backwards compatibility of deprecated Jira taxonomy
95+
if it['name'].lower() in ['feature', 'maintenance', 'improvement', 'task']:
9596
issue_type = it['name']
9697
break
9798

create-integration-ticket/test_create_integration_ticket.py

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,18 @@ def test_validate_release_ticket_unexpected_error(self):
129129
validate_release_ticket(mock_jira, 'REL-123')
130130
self.assertEqual(cm.exception.code, 1)
131131

132-
def test_create_integration_ticket_with_task_type(self):
133-
"""Test creating integration ticket with Task issue type."""
132+
def test_create_integration_ticket_with_maintenance_type(self):
133+
"""Test creating integration ticket with Maintenance issue type."""
134134
mock_jira = Mock()
135135
mock_project = Mock()
136136
mock_jira.project.return_value = mock_project
137137

138-
# Mock issue types with Task available
138+
# Mock issue types with Maintenance available
139139
mock_jira.createmeta.return_value = {
140140
'projects': [{
141141
'issuetypes': [
142142
{'name': 'Bug'},
143-
{'name': 'Task'},
143+
{'name': 'Maintenance'},
144144
{'name': 'Story'}
145145
]
146146
}]
@@ -164,7 +164,7 @@ def test_create_integration_ticket_with_task_type(self):
164164
# Verify the issue creation call
165165
call_args = mock_jira.create_issue.call_args[1]['fields']
166166
self.assertEqual(call_args['project'], 'INT')
167-
self.assertEqual(call_args['issuetype'], {'name': 'Task'})
167+
self.assertEqual(call_args['issuetype'], {'name': 'Maintenance'})
168168
self.assertEqual(call_args['summary'], 'Integration ticket for release')
169169
self.assertNotIn('description', call_args) # No description provided
170170

@@ -174,11 +174,11 @@ def test_create_integration_ticket_with_description(self):
174174
mock_project = Mock()
175175
mock_jira.project.return_value = mock_project
176176

177-
# Mock issue types with Task available
177+
# Mock issue types with Maintenance available
178178
mock_jira.createmeta.return_value = {
179179
'projects': [{
180180
'issuetypes': [
181-
{'name': 'Task'}
181+
{'name': 'Maintenance'}
182182
]
183183
}]
184184
}
@@ -201,7 +201,7 @@ def test_create_integration_ticket_with_description(self):
201201
# Verify the issue creation call does NOT include description
202202
call_args = mock_jira.create_issue.call_args[1]['fields']
203203
self.assertEqual(call_args['project'], 'INT')
204-
self.assertEqual(call_args['issuetype'], {'name': 'Task'})
204+
self.assertEqual(call_args['issuetype'], {'name': 'Maintenance'})
205205
self.assertEqual(call_args['summary'], 'Integration ticket for release')
206206
self.assertNotIn('description', call_args)
207207

@@ -216,7 +216,7 @@ def test_create_integration_ticket_description_update_fails(self, mock_eprint):
216216
mock_jira.project.return_value = mock_project
217217

218218
mock_jira.createmeta.return_value = {
219-
'projects': [{'issuetypes': [{'name': 'Task'}]}]
219+
'projects': [{'issuetypes': [{'name': 'Maintenance'}]}]
220220
}
221221

222222
mock_ticket = Mock()
@@ -241,8 +241,77 @@ def test_create_integration_ticket_description_update_fails(self, mock_eprint):
241241
mock_ticket.update.assert_called_once_with(fields={'description': 'This description will fail to set'})
242242

243243
# noinspection DuplicatedCode
244+
def test_create_integration_ticket_with_feature_type(self):
245+
"""Test creating integration ticket with Feature issue type when Maintenance is not available."""
246+
mock_jira = Mock()
247+
mock_project = Mock()
248+
mock_jira.project.return_value = mock_project
249+
250+
# Mock issue types with only Feature available (no Bug)
251+
mock_jira.createmeta.return_value = {
252+
'projects': [{
253+
'issuetypes': [
254+
{'name': 'Bug'},
255+
{'name': 'Feature'},
256+
]
257+
}]
258+
}
259+
260+
mock_ticket = Mock()
261+
mock_ticket.key = 'INT-124'
262+
mock_jira.create_issue.return_value = mock_ticket
263+
264+
args = Mock()
265+
args.target_jira_project = 'INT'
266+
args.ticket_summary = 'Integration ticket for release'
267+
args.ticket_description = None
268+
269+
result = create_integration_ticket(mock_jira, args)
270+
271+
self.assertEqual(result, mock_ticket)
272+
273+
# Verify the issue creation call - should use Feature
274+
call_args = mock_jira.create_issue.call_args[1]['fields']
275+
self.assertEqual(call_args['issuetype'], {'name': 'Feature'})
276+
277+
# noinspection DuplicatedCode
278+
def test_create_integration_ticket_with_task_type(self):
279+
"""Test creating integration ticket with Task issue type when Maintenance and Feature is not available."""
280+
mock_jira = Mock()
281+
mock_project = Mock()
282+
mock_jira.project.return_value = mock_project
283+
284+
# Mock issue types with Task and Improvement available (no Bug)
285+
mock_jira.createmeta.return_value = {
286+
'projects': [{
287+
'issuetypes': [
288+
{'name': 'Bug'},
289+
{'name': 'Task'},
290+
{'name': 'Improvement'},
291+
]
292+
}]
293+
}
294+
295+
mock_ticket = Mock()
296+
mock_ticket.key = 'INT-124'
297+
mock_jira.create_issue.return_value = mock_ticket
298+
299+
args = Mock()
300+
args.target_jira_project = 'INT'
301+
args.ticket_summary = 'Integration ticket for release'
302+
args.ticket_description = None
303+
304+
result = create_integration_ticket(mock_jira, args)
305+
306+
self.assertEqual(result, mock_ticket)
307+
308+
# Verify the issue creation call - should use Feature
309+
call_args = mock_jira.create_issue.call_args[1]['fields']
310+
self.assertEqual(call_args['issuetype'], {'name': 'Task'})
311+
312+
# noinspection DuplicatedCode
244313
def test_create_integration_ticket_with_improvement_type(self):
245-
"""Test creating integration ticket with Improvement issue type when Task is not available."""
314+
"""Test creating integration ticket with Improvement issue type when Maintenance, Feature and Task is not available."""
246315
mock_jira = Mock()
247316
mock_project = Mock()
248317
mock_jira.project.return_value = mock_project
@@ -270,7 +339,7 @@ def test_create_integration_ticket_with_improvement_type(self):
270339

271340
self.assertEqual(result, mock_ticket)
272341

273-
# Verify the issue creation call - should use Improvement
342+
# Verify the issue creation call - should use Feature
274343
call_args = mock_jira.create_issue.call_args[1]['fields']
275344
self.assertEqual(call_args['issuetype'], {'name': 'Improvement'})
276345

@@ -281,7 +350,7 @@ def test_create_integration_ticket_with_first_available_type(self):
281350
mock_project = Mock()
282351
mock_jira.project.return_value = mock_project
283352

284-
# Mock issue types with neither Task nor Story available
353+
# Mock issue types with neither Maintenance, Feature, Task, Improvement available
285354
mock_jira.createmeta.return_value = {
286355
'projects': [{
287356
'issuetypes': [
@@ -349,7 +418,7 @@ def test_create_integration_ticket_creation_error(self, mock_eprint):
349418
mock_jira.project.return_value = mock_project
350419

351420
mock_jira.createmeta.return_value = {
352-
'projects': [{'issuetypes': [{'name': 'Task'}]}]
421+
'projects': [{'issuetypes': [{'name': 'Maintenance'}]}]
353422
}
354423

355424
mock_response = Mock()

0 commit comments

Comments
 (0)