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
2 changes: 1 addition & 1 deletion .github/workflows/release-on-resolved-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
shell: bash
run: |
set -euo pipefail
query='query($owner:String!, $repo:String!, $sha:String!) { repository(owner:$owner, name:$repo) { object(expression:$sha) { ... on Commit { associatedPullRequests(first:100) { pageInfo { hasNextPage } nodes { number mergeCommit { oid } labels(first:20) { pageInfo { hasNextPage } nodes { name } } closingIssuesReferences(first:20) { pageInfo { hasNextPage } nodes { number repository { nameWithOwner } labels(first:30) { pageInfo { hasNextPage } nodes { name } } } } } } } } } } }'
query="$(< scripts/release_eligibility.graphql)"
result="$(gh api graphql -f query="$query" -f owner="${GITHUB_REPOSITORY_OWNER}" -f repo="${GITHUB_REPOSITORY#*/}" -f sha="$TESTED_SHA")"
repository="$(jq -ce '{pullRequests: (.data.repository.object.associatedPullRequests // error("tested SHA is not a commit"))}' <<< "$result")"
if outcome="$(python scripts/release_eligibility.py --tested-sha "$TESTED_SHA" --repository "$GITHUB_REPOSITORY" --pull-requests-json "$repository")"; then
Expand Down
46 changes: 46 additions & 0 deletions scripts/release_eligibility.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
query($owner: String!, $repo: String!, $sha: String!) {
repository(owner: $owner, name: $repo) {
object(expression: $sha) {
... on Commit {
associatedPullRequests(first: 100) {
pageInfo {
hasNextPage
}
nodes {
number
mergeCommit {
oid
}
labels(first: 20) {
pageInfo {
hasNextPage
}
nodes {
name
}
}
closingIssuesReferences(first: 20) {
pageInfo {
hasNextPage
}
nodes {
number
repository {
nameWithOwner
}
labels(first: 30) {
pageInfo {
hasNextPage
}
nodes {
name
}
}
}
}
}
}
}
}
}
}
43 changes: 43 additions & 0 deletions tests/test_release_eligibility_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from pathlib import Path


QUERY = Path(__file__).parents[1] / "scripts" / "release_eligibility.graphql"
WORKFLOW = Path(__file__).parents[1] / ".github" / "workflows" / "release-on-resolved-issue.yml"


def _balanced_graphql_delimiters(source: str) -> bool:
"""Check the structural delimiters that GitHub's GraphQL parser requires.

This query contains no GraphQL string literals or comments, so a small
delimiter check catches malformed edits without adding a runtime-only
GraphQL parser dependency to the CLI test environment.
"""
pairs = {"}": "{", ")": "("}
stack: list[str] = []
for character in source:
if character in "{(":
stack.append(character)
elif character in pairs:
if not stack or stack.pop() != pairs[character]:
return False
return not stack


def test_release_eligibility_query_is_structurally_valid_and_wired_to_workflow():
query = QUERY.read_text()

assert _balanced_graphql_delimiters(query)
assert "query($owner: String!, $repo: String!, $sha: String!)" in query
assert "... on Commit" in query
assert "associatedPullRequests(first: 100)" in query
assert "closingIssuesReferences(first: 20)" in query
assert "query=\"$(< scripts/release_eligibility.graphql)\"" in WORKFLOW.read_text()


def test_release_eligibility_query_requests_every_fail_closed_page_boundary():
query = QUERY.read_text()

# The classifier rejects a truncated pull-request, label, or closing-issue
# connection. Keep every corresponding pageInfo request in the query.
assert query.count("pageInfo {") == 4
assert query.count("hasNextPage") == 4
Loading