Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/scripts/tag-jira.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import base64
import json
import os
import re
import urllib.error
import urllib.request

base_url = os.environ['JIRA_BASE_URL']
tag = os.environ['RELEASE_TAG']
auth = base64.b64encode(
f"{os.environ['JIRA_USER_EMAIL']}:{os.environ['JIRA_API_TOKEN']}".encode()
).decode()
headers = {
'Authorization': f'Basic {auth}',
'Content-Type': 'application/json',
'Accept': 'application/json',
}


def jira(method, path, body=None):
url = f"{base_url}/rest/api/3{path}"
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(url, data=data, headers=headers, method=method)
try:
with urllib.request.urlopen(req) as r:
text = r.read()
return json.loads(text) if text else None
except urllib.error.HTTPError as e:
print(f" WARN {e.code} {method} {path}: {e.read().decode()[:200]}")
return None


tickets = sorted(set(re.findall(r'AAI-\d+', os.environ['RELEASE_BODY'])))
if not tickets:
print("No AAI-* tickets found in release notes — nothing to tag.")
raise SystemExit(0)
print(f"Tickets in {tag}: {', '.join(tickets)}")

project = jira('GET', '/project/AAI')
if not project:
raise SystemExit("ERROR: could not fetch AAI project from JIRA")

versions = jira('GET', '/project/AAI/versions') or []
existing = next((v for v in versions if v['name'] == tag), None)
if existing:
version_id = existing['id']
print(f"Reusing existing JIRA version '{tag}' (id={version_id})")
else:
created = jira('POST', '/version', {
'name': tag,
'projectId': project['id'],
'released': True,
})
if not created:
raise SystemExit("ERROR: could not create JIRA version")
version_id = created['id']
print(f"Created JIRA version '{tag}' (id={version_id})")

for ticket in tickets:
issue = jira('GET', f'/issue/{ticket}?fields=fixVersions,summary')
if not issue:
print(f" SKIP {ticket}: issue not found or inaccessible")
continue
current = issue['fields'].get('fixVersions', [])
if any(v['id'] == version_id for v in current):
print(f" SKIP {ticket}: already tagged with {tag}")
continue
jira('PUT', f'/issue/{ticket}', {
'fields': {'fixVersions': current + [{'id': version_id}]}
})
print(f" DONE {ticket}: {issue['fields'].get('summary', '')[:60]}")

print(f"\nTagged {len(tickets)} ticket(s) with fix version '{tag}'.")
20 changes: 20 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jobs:
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
body: ${{ steps.release.outputs.body }}
steps:
- id: release
uses: googleapis/release-please-action@v4
Expand Down Expand Up @@ -89,3 +90,22 @@ jobs:
sbom: false
cache-from: type=gha
cache-to: type=gha,mode=max

notify-jira:
name: Tag JIRA Tickets for Release
needs: release
if: needs.release.outputs.release_created == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4

- name: Tag JIRA tickets with fix version
env:
JIRA_BASE_URL: https://biocloud.atlassian.net
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
RELEASE_TAG: ${{ needs.release.outputs.tag_name }}
RELEASE_BODY: ${{ needs.release.outputs.body }}
run: python3 .github/scripts/tag-jira.py
Loading