Skip to content

Commit

Permalink
Merge pull request #666 from gerrod3/ci-streamline
Browse files Browse the repository at this point in the history
Update CI to be more streamline
  • Loading branch information
ggainey authored Sep 24, 2024
2 parents 2a9e6b3 + bccd950 commit c130256
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 38 deletions.
60 changes: 60 additions & 0 deletions .ci/scripts/pr_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/env python3

# This script is running with elevated privileges from the main branch against pull requests.

import re
import sys
import tomllib
from pathlib import Path

from git import Repo


def main():
assert len(sys.argv) == 3

with open("pyproject.toml", "rb") as fp:
PYPROJECT_TOML = tomllib.load(fp)
BLOCKING_REGEX = re.compile(r"DRAFT|WIP|NO\s*MERGE|DO\s*NOT\s*MERGE|EXPERIMENT")
ISSUE_REGEX = re.compile(r"(?:fixes|closes)[\s:]+#(\d+)")
CHERRY_PICK_REGEX = re.compile(r"^\s*\(cherry picked from commit [0-9a-f]*\)\s*$")
try:
CHANGELOG_EXTS = {
f".{item['directory']}" for item in PYPROJECT_TOML["tool"]["towncrier"]["type"]
}
except KeyError:
CHANGELOG_EXTS = {"feature", "bugfix", "doc", "removal", "misc"}

repo = Repo(".")

base_commit = repo.commit(sys.argv[1])
head_commit = repo.commit(sys.argv[2])

pr_commits = list(repo.iter_commits(f"{base_commit}..{head_commit}"))

labels = {
"multi-commit": len(pr_commits) > 1,
"cherry-pick": False,
"no-issue": False,
"no-changelog": False,
"wip": False,
}
for commit in pr_commits:
labels["wip"] |= BLOCKING_REGEX.search(commit.summary) is not None
no_issue = ISSUE_REGEX.search(commit.message, re.IGNORECASE) is None
labels["no-issue"] |= no_issue
cherry_pick = CHERRY_PICK_REGEX.search(commit.message) is not None
labels["cherry-pick"] |= cherry_pick
changelog_snippets = [
k
for k in commit.stats.files
if k.startswith("CHANGES/") and Path(k).suffix in CHANGELOG_EXTS
]
labels["no-changelog"] |= not changelog_snippets

print("ADD_LABELS=" + ",".join((k for k, v in labels.items() if v)))
print("REMOVE_LABELS=" + ",".join((k for k, v in labels.items() if not v)))


if __name__ == "__main__":
main()
57 changes: 26 additions & 31 deletions .ci/scripts/validate_commit_message.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# WARNING: DO NOT EDIT!
#
# This file was generated by plugin_template, and is managed by bootstrap.py. Please use
# bootstrap.py to update this file.
# This file was generated by plugin_template and copied over to this repository :)
#
# For more info visit https://github.com/pulp/plugin_template

import glob
import os
import re
import subprocess
import sys

from pathlib import Path
import subprocess
import os
import warnings
from github import Github

KEYWORDS = ["fixes", "closes", "re", "ref"]
NO_ISSUE = "[noissue]"
CHANGELOG_EXTS = [".feature", ".bugfix", ".doc", ".removal", ".misc", ".deprecation", ".dev"]
CHANGELOG_EXTS = [".feature", ".bugfix", ".doc", ".removal", ".misc", ".deprecation"]
KEYWORDS = ["fixes", "closes"]

sha = sys.argv[1]
message = subprocess.check_output(["git", "log", "--format=%B", "-n 1", sha]).decode("utf-8")

g = Github(os.environ.get("GITHUB_TOKEN"))
repo = g.get_repo("pulp/pulp-oci-images")

Expand All @@ -27,41 +26,37 @@ def __check_status(issue):
gi = repo.get_issue(int(issue))
if gi.pull_request:
sys.exit(f"Error: issue #{issue} is a pull request.")
if gi.closed_at:
if gi.closed_at and "cherry picked from commit" not in message:
warnings.warn(
"When backporting, use the -x flag to append a line that says "
"'(cherry picked from commit ...)' to the original commit message."
)
sys.exit(f"Error: issue #{issue} is closed.")


def __check_changelog(issue):
matches = glob.glob("CHANGES/{issue}.*".format(issue=issue))
matches = list(Path("CHANGES").rglob(f"{issue}.*"))

if len(matches) < 1:
sys.exit("Could not find changelog entry in CHANGES/ for {issue}.".format(issue=issue))
sys.exit(f"Could not find changelog entry in CHANGES/ for {issue}.")
for match in matches:
if os.path.splitext(match)[1] not in CHANGELOG_EXTS:
sys.exit("Invalid extension for changelog entry '{match}'.".format(match=match))
if match.suffix not in CHANGELOG_EXTS:
sys.exit(f"Invalid extension for changelog entry '{match}'.")
if match.suffix == ".feature" and "cherry picked from commit" in message:
sys.exit(f"Can not backport '{match}' as it is a feature.")


print("Checking commit message for {sha}.".format(sha=sha[0:7]))

# validate the issue attached to the commit
if NO_ISSUE in message:
print("Commit {sha} has no issue attached. Skipping issue check".format(sha=sha[0:7]))
elif "Merge" in message and "cherry picked from commit" in message:
pass
else:
regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS))
pattern = re.compile(regex, re.IGNORECASE)
regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS))
pattern = re.compile(regex, re.IGNORECASE)

issues = pattern.findall(message)
issues = pattern.findall(message)

if issues:
for issue in pattern.findall(message):
__check_status(issue)
__check_changelog(issue)
else:
sys.exit(
"Error: no attached issues found for {sha}. If this was intentional, add "
" '{tag}' to the commit message.".format(sha=sha[0:7], tag=NO_ISSUE)
)
if issues:
for issue in pattern.findall(message):
__check_status(issue)
__check_changelog(issue)

print("Commit message for {sha} passed.".format(sha=sha[0:7]))
9 changes: 4 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: pulp-oci-images CI

on:
pull_request:
paths:
- "images/**"
- ".github/**"
- ".ci/**"
env:
COLORTERM: 'yes'
TERM: 'xterm-256color'
Expand Down Expand Up @@ -41,12 +45,7 @@ jobs:
done
shell: bash

docs:
needs: lint
uses: "./.github/workflows/docs-ci.yml"

base-images:
needs: docs
runs-on: ubuntu-latest
outputs:
image_variants: "${{ steps.image_variants.outputs.image_variants }}"
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/docs-ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: "Docs CI"

on:
workflow_call:
pull_request:

jobs:
test:
Expand All @@ -17,4 +17,3 @@ jobs:
pip install -r doc_requirements.txt
- name: Build docs
run: make docs

66 changes: 66 additions & 0 deletions .github/workflows/pr_checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# WARNING: DO NOT EDIT!
#
# This file was generated by plugin_template and copied over to this repository :)
#
# For more info visit https://github.com/pulp/plugin_template

---
name: "Pulp-OCI-Images PR static checks"
on:
pull_request_target:
types: ["opened", "synchronize", "reopened"]

# This workflow runs with elevated permissions.
# Do not even think about running a single bit of code from the PR.
# Static analysis should be fine however.

concurrency:
group: "${{ github.event.pull_request.number }}-${{ github.workflow }}"
cancel-in-progress: true

jobs:
apply_labels:
runs-on: "ubuntu-latest"
name: "Label PR"
permissions:
pull-requests: "write"
steps:
- uses: "actions/checkout@v4"
with:
fetch-depth: 0
- uses: "actions/setup-python@v5"
with:
python-version: "3.11"
- name: "Determine PR labels"
run: |
pip install GitPython==3.1.42
git fetch origin ${{ github.event.pull_request.head.sha }}
python .ci/scripts/pr_labels.py "origin/${{ github.base_ref }}" "${{ github.event.pull_request.head.sha }}" >> "$GITHUB_ENV"
- uses: "actions/github-script@v7"
name: "Apply PR Labels"
with:
script: |
const { ADD_LABELS, REMOVE_LABELS } = process.env;
if (REMOVE_LABELS.length) {
for await (const labelName of REMOVE_LABELS.split(",")) {
try {
await github.rest.issues.removeLabel({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
name: labelName,
});
} catch(err) {
}
}
}
if (ADD_LABELS.length) {
await github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ADD_LABELS.split(","),
});
}
...

0 comments on commit c130256

Please sign in to comment.