1
0
Fork 0
mirror of https://github.com/imjasonh/terraform-playground synced 2026-07-06 23:12:22 +00:00

Fix check_run events using subject instead of repo extension

The github-events trampoline sets event.SetSubject(repoFullName) which
becomes ce-subject attribute, but does NOT set a 'repo' extension.

- Change extension_key from 'repo' to 'subject' for check-run-workqueue
- Rename parseRepoURL to parseRepoKey to handle both URL and subject formats
- Add tests for subject format (owner/repo)

This allows check_run completion events to flow through the workqueue
and trigger CI fixer reconciliation.
This commit is contained in:
Jason Hall 2026-02-04 12:43:03 -05:00
parent 87ca77d9dd
commit 009f2ec186
3 changed files with 44 additions and 16 deletions

View file

@ -292,6 +292,9 @@ var prURLRegex = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)/pull/(
// repoURLRegex matches GitHub repo URLs like https://github.com/owner/repo
var repoURLRegex = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)$`)
// repoSubjectRegex matches repo subject format like owner/repo (from CloudEvents subject)
var repoSubjectRegex = regexp.MustCompile(`^([^/]+)/([^/]+)$`)
// ciState represents the evaluated state of CI checks
type ciState int
@ -357,12 +360,21 @@ func parsePRURL(url string) (owner, repo string, number int, err error) {
return matches[1], matches[2], number, nil
}
func parseRepoURL(url string) (owner, repo string, err error) {
matches := repoURLRegex.FindStringSubmatch(url)
if matches == nil {
return "", "", fmt.Errorf("invalid repo URL: %s", url)
// parseRepoKey parses a repo identifier which can be either:
// - Full URL: https://github.com/owner/repo
// - Subject format: owner/repo (from CloudEvents subject attribute)
func parseRepoKey(key string) (owner, repo string, err error) {
// Try full URL format first
matches := repoURLRegex.FindStringSubmatch(key)
if matches != nil {
return matches[1], matches[2], nil
}
return matches[1], matches[2], nil
// Try subject format (owner/repo)
matches = repoSubjectRegex.FindStringSubmatch(key)
if matches != nil {
return matches[1], matches[2], nil
}
return "", "", fmt.Errorf("invalid repo key: %s", key)
}
func (r *PRReconciler) Process(ctx context.Context, req *workqueue.ProcessRequest) (*workqueue.ProcessResponse, error) {
@ -372,7 +384,7 @@ func (r *PRReconciler) Process(ctx context.Context, req *workqueue.ProcessReques
if err != nil {
// Key is not a PR URL - might be a repo URL from check_run events.
// Try to parse as repo URL and handle check_run completion.
owner, repo, parseErr := parseRepoURL(req.Key)
owner, repo, parseErr := parseRepoKey(req.Key)
if parseErr != nil {
log.Warnf("skipping unknown key format: %v", err)
return &workqueue.ProcessResponse{}, nil

View file

@ -314,34 +314,48 @@ func TestParsePRURL(t *testing.T) {
}
}
func TestParseRepoURL(t *testing.T) {
func TestParseRepoKey(t *testing.T) {
for _, tt := range []struct {
desc string
url string
key string
wantOwner string
wantRepo string
wantErr bool
}{{
desc: "valid repo URL",
url: "https://github.com/owner/repo",
key: "https://github.com/owner/repo",
wantOwner: "owner",
wantRepo: "repo",
}, {
desc: "valid repo URL with dashes",
url: "https://github.com/my-org/my-repo",
key: "https://github.com/my-org/my-repo",
wantOwner: "my-org",
wantRepo: "my-repo",
}, {
desc: "PR URL is not a repo URL",
url: "https://github.com/owner/repo/pull/123",
desc: "subject format owner/repo",
key: "owner/repo",
wantOwner: "owner",
wantRepo: "repo",
}, {
desc: "subject format with dashes",
key: "my-org/my-repo",
wantOwner: "my-org",
wantRepo: "my-repo",
}, {
desc: "PR URL is not a repo key",
key: "https://github.com/owner/repo/pull/123",
wantErr: true,
}, {
desc: "empty string",
url: "",
key: "",
wantErr: true,
}, {
desc: "just owner no repo",
key: "owner",
wantErr: true,
}} {
t.Run(tt.desc, func(t *testing.T) {
owner, repo, err := parseRepoURL(tt.url)
owner, repo, err := parseRepoKey(tt.key)
if tt.wantErr {
if err == nil {
t.Errorf("expected error, got owner=%q repo=%q", owner, repo)

View file

@ -47,8 +47,10 @@ module "check-run-workqueue" {
"action" = "completed"
}]
# Use repository URL as the key since check_run events don't have pullrequesturl
extension_key = "repo"
# Use subject (repo full name like "owner/repo") as the key.
# The trampoline sets event.SetSubject(repoFullName) which becomes ce-subject attribute.
# Note: "repo" extension doesn't exist - the trampoline only sets subject, not a repo extension.
extension_key = "subject"
workqueue = {
name = module.pr-reconciler.receiver.name