mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
* feat: add CloudSinkEnvResolver interface with default implementation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add GitHub Actions environment resolver for cloud sink Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: populate invocation context with CI environment on cloud events Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address lint errors in cloud sink tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: use getter-based CloudSinkCIResolver with nil-when-no-CI Rename to CloudSinkCIResolver with focused CI concern. Factory returns nil when no CI is detected, removing the need for IsCI() and a default resolver. Leaves room for a separate agent resolver in the future. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add CI metadata support using updated API SDK Update SDK to include SetMetadata on EndpointCIContext. Add Metadata() to CloudSinkCIResolver interface and GitHub Actions implementation (workflow, job, run_attempt, server_url). Wire metadata into buildInvocationContext. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: address review comments on CI resolver - Inject CloudSinkCIResolver as dependency into newCloudSink for testability - Check both GITHUB_ACTIONS and GITHUB_RUN_ID for GHA environment detection - Make factory and constructor package-private (newCloudSinkCIResolver, newGithubActionsCIResolver) - Attach invocation context only to session complete events, not every event Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: fail fast on os.Getwd error instead of swallowing it Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
package audit
|
|
|
|
import (
|
|
"os"
|
|
"regexp"
|
|
|
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/controltower/v1"
|
|
)
|
|
|
|
var prRefPattern = regexp.MustCompile(`^refs/pull/(\d+)/merge$`)
|
|
|
|
type githubActionsEnvResolver struct{}
|
|
|
|
func newGithubActionsCIResolver() CloudSinkCIResolver {
|
|
return &githubActionsEnvResolver{}
|
|
}
|
|
|
|
func (r *githubActionsEnvResolver) Provider() controltowerv1.EndpointCIProvider {
|
|
return controltowerv1.EndpointCIProvider_ENDPOINT_CI_PROVIDER_GITHUB_ACTIONS
|
|
}
|
|
|
|
func (r *githubActionsEnvResolver) RunId() string { return os.Getenv("GITHUB_RUN_ID") }
|
|
func (r *githubActionsEnvResolver) Repository() string { return os.Getenv("GITHUB_REPOSITORY") }
|
|
func (r *githubActionsEnvResolver) CommitSha() string { return os.Getenv("GITHUB_SHA") }
|
|
func (r *githubActionsEnvResolver) Actor() string { return os.Getenv("GITHUB_ACTOR") }
|
|
|
|
func (r *githubActionsEnvResolver) Branch() string {
|
|
if headRef := os.Getenv("GITHUB_HEAD_REF"); headRef != "" {
|
|
return headRef
|
|
}
|
|
return os.Getenv("GITHUB_REF_NAME")
|
|
}
|
|
|
|
func (r *githubActionsEnvResolver) PrNumber() string {
|
|
matches := prRefPattern.FindStringSubmatch(os.Getenv("GITHUB_REF"))
|
|
if len(matches) == 2 {
|
|
return matches[1]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (r *githubActionsEnvResolver) Metadata() map[string]string {
|
|
entries := []struct {
|
|
key string
|
|
envVar string
|
|
}{
|
|
{"workflow", "GITHUB_WORKFLOW"},
|
|
{"job", "GITHUB_JOB"},
|
|
{"run_attempt", "GITHUB_RUN_ATTEMPT"},
|
|
{"server_url", "GITHUB_SERVER_URL"},
|
|
}
|
|
|
|
metadata := make(map[string]string)
|
|
for _, e := range entries {
|
|
if val := os.Getenv(e.envVar); val != "" {
|
|
metadata[e.key] = val
|
|
}
|
|
}
|
|
|
|
if len(metadata) == 0 {
|
|
return nil
|
|
}
|
|
return metadata
|
|
}
|