From 3d2cd78b077eb3cabd75d7bc1b4f00d0bd1e86d4 Mon Sep 17 00:00:00 2001 From: "Urko." Date: Fri, 24 May 2024 21:32:05 +0200 Subject: [PATCH] feat: allow projects with branches/envs --- internal/gitea.go | 184 +++++++++++++++++++++++++++++++++++++++++++ kit/config/config.go | 6 +- main.go | 17 +++- 3 files changed, 200 insertions(+), 7 deletions(-) create mode 100644 internal/gitea.go diff --git a/internal/gitea.go b/internal/gitea.go new file mode 100644 index 0000000..de0ece7 --- /dev/null +++ b/internal/gitea.go @@ -0,0 +1,184 @@ +package internal + +import "time" + +type WebhookPayload struct { + Ref string `json:"ref"` + Before string `json:"before"` + After string `json:"after"` + CompareURL string `json:"compare_url"` + Commits []struct { + ID string `json:"id"` + Message string `json:"message"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + Username string `json:"username"` + } `json:"author"` + Committer struct { + Name string `json:"name"` + Email string `json:"email"` + Username string `json:"username"` + } `json:"committer"` + Verification any `json:"verification"` + Timestamp string `json:"timestamp"` + Added []any `json:"added"` + Removed []any `json:"removed"` + Modified []string `json:"modified"` + } `json:"commits"` + TotalCommits int `json:"total_commits"` + HeadCommit struct { + ID string `json:"id"` + Message string `json:"message"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + Username string `json:"username"` + } `json:"author"` + Committer struct { + Name string `json:"name"` + Email string `json:"email"` + Username string `json:"username"` + } `json:"committer"` + Verification any `json:"verification"` + Timestamp string `json:"timestamp"` + Added []any `json:"added"` + Removed []any `json:"removed"` + Modified []string `json:"modified"` + } `json:"head_commit"` + Repository struct { + ID int `json:"id"` + Owner struct { + ID int `json:"id"` + Login string `json:"login"` + LoginName string `json:"login_name"` + FullName string `json:"full_name"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` + Language string `json:"language"` + IsAdmin bool `json:"is_admin"` + LastLogin time.Time `json:"last_login"` + Created time.Time `json:"created"` + Restricted bool `json:"restricted"` + Active bool `json:"active"` + ProhibitLogin bool `json:"prohibit_login"` + Location string `json:"location"` + Website string `json:"website"` + Description string `json:"description"` + Visibility string `json:"visibility"` + FollowersCount int `json:"followers_count"` + FollowingCount int `json:"following_count"` + StarredReposCount int `json:"starred_repos_count"` + Username string `json:"username"` + } `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` + Description string `json:"description"` + Empty bool `json:"empty"` + Private bool `json:"private"` + Fork bool `json:"fork"` + Template bool `json:"template"` + Parent any `json:"parent"` + Mirror bool `json:"mirror"` + Size int `json:"size"` + Language string `json:"language"` + LanguagesURL string `json:"languages_url"` + HTMLURL string `json:"html_url"` + URL string `json:"url"` + Link string `json:"link"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + OriginalURL string `json:"original_url"` + Website string `json:"website"` + StarsCount int `json:"stars_count"` + ForksCount int `json:"forks_count"` + WatchersCount int `json:"watchers_count"` + OpenIssuesCount int `json:"open_issues_count"` + OpenPrCounter int `json:"open_pr_counter"` + ReleaseCounter int `json:"release_counter"` + DefaultBranch string `json:"default_branch"` + Archived bool `json:"archived"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + ArchivedAt time.Time `json:"archived_at"` + Permissions struct { + Admin bool `json:"admin"` + Push bool `json:"push"` + Pull bool `json:"pull"` + } `json:"permissions"` + HasIssues bool `json:"has_issues"` + InternalTracker struct { + EnableTimeTracker bool `json:"enable_time_tracker"` + AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` + EnableIssueDependencies bool `json:"enable_issue_dependencies"` + } `json:"internal_tracker"` + HasWiki bool `json:"has_wiki"` + HasPullRequests bool `json:"has_pull_requests"` + HasProjects bool `json:"has_projects"` + HasReleases bool `json:"has_releases"` + HasPackages bool `json:"has_packages"` + HasActions bool `json:"has_actions"` + IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` + AllowMergeCommits bool `json:"allow_merge_commits"` + AllowRebase bool `json:"allow_rebase"` + AllowRebaseExplicit bool `json:"allow_rebase_explicit"` + AllowSquashMerge bool `json:"allow_squash_merge"` + AllowRebaseUpdate bool `json:"allow_rebase_update"` + DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"` + DefaultMergeStyle string `json:"default_merge_style"` + DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"` + AvatarURL string `json:"avatar_url"` + Internal bool `json:"internal"` + MirrorInterval string `json:"mirror_interval"` + MirrorUpdated time.Time `json:"mirror_updated"` + RepoTransfer any `json:"repo_transfer"` + } `json:"repository"` + Pusher struct { + ID int `json:"id"` + Login string `json:"login"` + LoginName string `json:"login_name"` + FullName string `json:"full_name"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` + Language string `json:"language"` + IsAdmin bool `json:"is_admin"` + LastLogin time.Time `json:"last_login"` + Created time.Time `json:"created"` + Restricted bool `json:"restricted"` + Active bool `json:"active"` + ProhibitLogin bool `json:"prohibit_login"` + Location string `json:"location"` + Website string `json:"website"` + Description string `json:"description"` + Visibility string `json:"visibility"` + FollowersCount int `json:"followers_count"` + FollowingCount int `json:"following_count"` + StarredReposCount int `json:"starred_repos_count"` + Username string `json:"username"` + } `json:"pusher"` + Sender struct { + ID int `json:"id"` + Login string `json:"login"` + LoginName string `json:"login_name"` + FullName string `json:"full_name"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` + Language string `json:"language"` + IsAdmin bool `json:"is_admin"` + LastLogin time.Time `json:"last_login"` + Created time.Time `json:"created"` + Restricted bool `json:"restricted"` + Active bool `json:"active"` + ProhibitLogin bool `json:"prohibit_login"` + Location string `json:"location"` + Website string `json:"website"` + Description string `json:"description"` + Visibility string `json:"visibility"` + FollowersCount int `json:"followers_count"` + FollowingCount int `json:"following_count"` + StarredReposCount int `json:"starred_repos_count"` + Username string `json:"username"` + } `json:"sender"` +} diff --git a/kit/config/config.go b/kit/config/config.go index 699a3a4..6d780e7 100755 --- a/kit/config/config.go +++ b/kit/config/config.go @@ -7,9 +7,9 @@ import ( ) type Config struct { - Secret string `yaml:"secret"` - Port int `yaml:"port"` - Scripts map[string]ConfigScript `yaml:"scripts"` + Secret string `yaml:"secret"` + Port int `yaml:"port"` + Projects map[string]map[string]ConfigScript `yaml:"projects"` } type ConfigScript struct { BinaryPath string `yaml:"binary"` diff --git a/main.go b/main.go index 9b07dce..6821b0a 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,9 @@ import ( "os/exec" "path" "runtime" + "strings" + "gitea.urkob.com/urko/gitea-webhook-listener/internal" "gitea.urkob.com/urko/gitea-webhook-listener/kit/config" ) @@ -25,11 +27,11 @@ func main() { if err != nil { log.Fatalf("Error loading config: %v", err) } - http.HandleFunc("/", handlePayload(cfg.Secret, cfg.Scripts)) + http.HandleFunc("/", handlePayload(cfg.Secret, cfg.Projects)) http.ListenAndServe(fmt.Sprintf(":%d", cfg.Port), nil) } -func handlePayload(secret string, scripts map[string]config.ConfigScript) func(w http.ResponseWriter, r *http.Request) { +func handlePayload(secret string, projects map[string]map[string]config.ConfigScript) func(w http.ResponseWriter, r *http.Request) { return (func(w http.ResponseWriter, r *http.Request) { // Read the request body body, err := io.ReadAll(r.Body) @@ -51,16 +53,23 @@ func handlePayload(secret string, scripts map[string]config.ConfigScript) func(w } project := r.URL.Query().Get("project") - scr, found := scripts[project] + proj, found := projects[project] if !found { http.Error(w, "not found", http.StatusNotFound) return } - var payload interface{} + var payload internal.WebhookPayload if err = json.Unmarshal(body, &payload); err != nil { http.Error(w, "Failed to parse JSON payload", http.StatusBadRequest) return } + branchName := strings.Split(payload.Ref, "/")[len(strings.Split(payload.Ref, "/"))-1] + + scr, found := proj[branchName] + if !found { + http.Error(w, "not found", http.StatusNotFound) + return + } go func() { if err := execute(scr.BinaryPath, scr.ScriptPath); err != nil {