Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub CI job to verify tags are on expected branches #2170

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
12 changes: 12 additions & 0 deletions .github/workflows/misc-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,15 @@ jobs:
- if: ${{ matrix.os != 'windows-latest' }}
name: Run tests
run: cmake --build "path has spaces/build-fips" --target run_tests
git-tag-check:
if: github.repository_owner == 'aws'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-tags: true
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Check for git tag
run: python ./util/git-tag-check/git-tag-check.py
119 changes: 119 additions & 0 deletions util/git-tag-check/git-tag-check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/usr/bin/env python3

import os
import subprocess
import json
import re
from typing import List, Tuple
from pathlib import Path

REMOTE_NAME = "origin"
TAG_BRANCH_JSON = Path(__file__).parent / 'tag-branch.json'
REPO_PATH = Path(__file__).parent.parent


class GitError(Exception):
pass


def run_git_command(args: List[str], error_msg: str) -> subprocess.CompletedProcess:
try:
return subprocess.run(
args,
capture_output=True,
text=True,
check=True
)
except subprocess.CalledProcessError as e:
raise GitError(f"{error_msg}: {e.stderr.strip()}")


def get_git_tags() -> List[str]:
result = run_git_command(
['git', '-C', str(REPO_PATH), 'tag', '--list'],
"Error getting tags"
)
return [tag for tag in result.stdout.strip().split('\n') if tag]


def get_commit_sha(ref: str) -> str:
result = run_git_command(
['git', '-C', str(REPO_PATH), 'rev-parse', ref],
f"Error getting SHA for {ref}"
)
return result.stdout.strip()


def verify_ref_exists(ref: str) -> None:
run_git_command(
['git', '-C', str(REPO_PATH), 'rev-parse', '--verify', ref],
f"Reference {ref} does not exist"
)


def is_tag_reachable(tag: str, branch: str) -> bool:
# Verify both references exist
verify_ref_exists(tag)
verify_ref_exists(branch)

tag_sha = get_commit_sha(tag)
branch_sha = get_commit_sha(branch)
if tag_sha != branch_sha:
# An exception will occur if the return code != 0
run_git_command(
['git', '-C', str(REPO_PATH), 'merge-base', '--is-ancestor', tag, branch],
f"Error checking if {tag} is ancestor of {branch}"
)

return True



def load_branch_tag_patterns() -> List[dict]:
try:
with open(TAG_BRANCH_JSON) as file:
patterns = json.load(file)
if not patterns:
raise Exception("Empty JSON file")
return patterns
except json.JSONDecodeError as e:
raise Exception(f"Invalid JSON file: {e}")
except IOError as e:
raise Exception(f"Error reading JSON file: {e}")


def main():
try:
branch_tag_patterns = load_branch_tag_patterns()

run_git_command(
['git', '-C', str(REPO_PATH), 'fetch', '--tags', REMOTE_NAME],
"Error fetching tags"
)

# Get tags
tags = get_git_tags()
if not tags:
raise GitError("No tags found")

# Process patterns
for item in branch_tag_patterns:
branch = item['branch']
tag_pattern = item['tag_pattern']
print(f"Processing branch: '{branch}', pattern: '{tag_pattern}'")

for tag in tags:
if re.match(tag_pattern, tag):
full_branch = f"{REMOTE_NAME}/{branch}"
if is_tag_reachable(tag, full_branch):
print(f"Tag found: {tag} on branch: {branch}")
else:
raise GitError(f"Tag NOT found: {tag} on branch: {branch}")

except GitError as e:
print(f"Error: {e}")
exit(1)


if __name__ == '__main__':
main()
18 changes: 18 additions & 0 deletions util/git-tag-check/tag-branch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"tag_pattern": "AWS-LC-FIPS-1\\..*",
"branch": "fips-2021-10-20"
},
{
"tag_pattern": "AWS-LC-FIPS-2\\..*",
"branch": "fips-2022-11-02"
},
{
"tag_pattern": "AWS-LC-FIPS-3\\..*",
"branch": "fips-2024-09-27"
},
{
"tag_pattern": "v1\\..*",
"branch": "main"
}
]
Loading