From a07d9cd86df470439d574e5f371a396c6dee7da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20So=C5=82tys?= <74361703+Sawthis@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:43:56 +0200 Subject: [PATCH] Add support for workflow_dispatch event (#11190) * Add support for workflow_dispatch event * Add BaseCommitRef and unit test * Adjust prepareADOTemplateParameters function * Add more unit tests --- cmd/image-builder/config.go | 17 ++- cmd/image-builder/config_test.go | 20 +++ cmd/image-builder/main.go | 6 + cmd/image-builder/main_test.go | 27 +++- .../test_fixture/workflow_dispatch.json | 131 ++++++++++++++++++ pkg/azuredevops/pipelines/templatesParams.go | 14 +- .../pipelines/templatesParams_test.go | 10 +- 7 files changed, 219 insertions(+), 6 deletions(-) create mode 100644 cmd/image-builder/test_fixture/workflow_dispatch.json diff --git a/cmd/image-builder/config.go b/cmd/image-builder/config.go index 0d097b1cf563..ee67c1ffb8f1 100644 --- a/cmd/image-builder/config.go +++ b/cmd/image-builder/config.go @@ -128,8 +128,10 @@ type GitStateConfig struct { JobType string // Number of the pull request for presubmit job PullRequestNumber int - // Commit SHA for base branch + // Commit SHA for base branch or tag BaseCommitSHA string + // Base branch or tag + BaseCommitRef string // Commit SHA for head of the pull request PullHeadCommitSHA string // isPullRequest contains information whether event which triggered the job was from pull request @@ -255,6 +257,19 @@ func loadGithubActionsGitState() (GitStateConfig, error) { JobType: "postsubmit", BaseCommitSHA: *payload.HeadCommit.ID, }, nil + case "workflow_dispatch": + var payload github.WorkflowDispatchEvent + err = json.Unmarshal(data, &payload) + if err != nil { + return GitStateConfig{}, fmt.Errorf("failed to parse event payload: %s", err) + } + return GitStateConfig{ + RepositoryName: *payload.Repo.Name, + RepositoryOwner: *payload.Repo.Owner.Login, + JobType: "on-demand", + BaseCommitSHA: os.Getenv("GITHUB_SHA"), + BaseCommitRef: os.Getenv("GITHUB_REF"), + }, nil default: return GitStateConfig{}, fmt.Errorf("GITHUB_EVENT_NAME environment variable is set to unsupported value \"%s\", please set it to supported value", eventName) } diff --git a/cmd/image-builder/config_test.go b/cmd/image-builder/config_test.go index 17814035014f..00e062d78538 100644 --- a/cmd/image-builder/config_test.go +++ b/cmd/image-builder/config_test.go @@ -246,6 +246,26 @@ func TestLoadGitStateConfig(t *testing.T) { isPullRequest: false, }, }, + { + name: "Load data from event payload for github workflow_dispatch event", + options: options{ + ciSystem: GithubActions, + }, + env: map[string]string{ + "GITHUB_EVENT_PATH": "./test_fixture/workflow_dispatch.json", + "GITHUB_EVENT_NAME": "workflow_dispatch", + "GITHUB_SHA": "d42f5051757b3e0699eb979d7581404e36fc0eee", + "GITHUB_REF": "refs/heads/main", + }, + gitState: GitStateConfig{ + RepositoryName: "test-infra", + RepositoryOwner: "KacperMalachowski", + JobType: "on-demand", + BaseCommitSHA: "d42f5051757b3e0699eb979d7581404e36fc0eee", + BaseCommitRef: "refs/heads/main", + isPullRequest: false, + }, + }, { name: "Unknown ci system, return err", options: options{ diff --git a/cmd/image-builder/main.go b/cmd/image-builder/main.go index 52749020dd35..a3f21133c9c6 100644 --- a/cmd/image-builder/main.go +++ b/cmd/image-builder/main.go @@ -201,6 +201,8 @@ func prepareADOTemplateParameters(options options) (adopipelines.OCIImageBuilder templateParameters.SetPresubmitJobType() } else if options.gitState.JobType == "postsubmit" { templateParameters.SetPostsubmitJobType() + } else if options.gitState.JobType == "on-demand" { + templateParameters.SetOnDemandJobType() } if options.gitState.IsPullRequest() { @@ -209,6 +211,10 @@ func prepareADOTemplateParameters(options options) (adopipelines.OCIImageBuilder templateParameters.SetBaseSHA(options.gitState.BaseCommitSHA) + if len(options.gitState.BaseCommitRef) > 0 { + templateParameters.SetBaseRef(options.gitState.BaseCommitRef) + } + if options.gitState.IsPullRequest() { templateParameters.SetPullSHA(options.gitState.PullHeadCommitSHA) } diff --git a/cmd/image-builder/main_test.go b/cmd/image-builder/main_test.go index 6a346a7979e3..02724c37e4dd 100644 --- a/cmd/image-builder/main_test.go +++ b/cmd/image-builder/main_test.go @@ -650,13 +650,38 @@ func Test_prepareADOTemplateParameters(t *testing.T) { "UseKanikoConfigFromPR": "false", }, }, + { + name: "On demand job type with base commit SHA and base commit ref", + options: options{ + gitState: GitStateConfig{ + JobType: "on-demand", + BaseCommitSHA: "abc123", + BaseCommitRef: "main", + }, + tags: sets.Tags{ + {Name: "{{ .Env \"GOLANG_VERSION\" }}-ShortSHA", Value: "{{ .Env \"GOLANG_VERSION\" }}-{{ .ShortSHA }}"}, + }, + }, + want: pipelines.OCIImageBuilderTemplateParams{ + "Context": "", + "Dockerfile": "", + "ExportTags": "false", + "JobType": "on-demand", + "Name": "", + "PullBaseSHA": "abc123", + "BaseRef": "main", + "RepoName": "", + "RepoOwner": "", + "Tags": "e3sgLkVudiAiR09MQU5HX1ZFUlNJT04iIH19LVNob3J0U0hBPXt7IC5FbnYgIkdPTEFOR19WRVJTSU9OIiB9fS17eyAuU2hvcnRTSEEgfX0=", + "UseKanikoConfigFromPR": "false", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := prepareADOTemplateParameters(tt.options) if (err != nil) != tt.wantErr { t.Errorf("prepareADOTemplateParameters() error = %v, wantErr %v", err, tt.wantErr) - return } if !reflect.DeepEqual(got, tt.want) { t.Errorf("prepareADOTemplateParameters() got = %v, want %v", got, tt.want) diff --git a/cmd/image-builder/test_fixture/workflow_dispatch.json b/cmd/image-builder/test_fixture/workflow_dispatch.json new file mode 100644 index 000000000000..3f8b3faf4799 --- /dev/null +++ b/cmd/image-builder/test_fixture/workflow_dispatch.json @@ -0,0 +1,131 @@ +{ + "inputs": null, + "ref": "refs/heads/main", + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/KacperMalachowski/test-infra/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/KacperMalachowski/test-infra/assignees{/user}", + "blobs_url": "https://api.github.com/repos/KacperMalachowski/test-infra/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/KacperMalachowski/test-infra/branches{/branch}", + "clone_url": "https://github.com/KacperMalachowski/test-infra.git", + "collaborators_url": "https://api.github.com/repos/KacperMalachowski/test-infra/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/KacperMalachowski/test-infra/comments{/number}", + "commits_url": "https://api.github.com/repos/KacperMalachowski/test-infra/commits{/sha}", + "compare_url": "https://api.github.com/repos/KacperMalachowski/test-infra/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/KacperMalachowski/test-infra/contents/{+path}", + "contributors_url": "https://api.github.com/repos/KacperMalachowski/test-infra/contributors", + "created_at": "2022-09-30T09:18:40Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/KacperMalachowski/test-infra/deployments", + "description": "Test infrastructure for the Kyma project.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/KacperMalachowski/test-infra/downloads", + "events_url": "https://api.github.com/repos/KacperMalachowski/test-infra/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/KacperMalachowski/test-infra/forks", + "full_name": "KacperMalachowski/test-infra", + "git_commits_url": "https://api.github.com/repos/KacperMalachowski/test-infra/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/KacperMalachowski/test-infra/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/KacperMalachowski/test-infra/git/tags{/sha}", + "git_url": "git://github.com/KacperMalachowski/test-infra.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://status.build.kyma-project.io/", + "hooks_url": "https://api.github.com/repos/KacperMalachowski/test-infra/hooks", + "html_url": "https://github.com/KacperMalachowski/test-infra", + "id": 543520825, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/KacperMalachowski/test-infra/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/KacperMalachowski/test-infra/issues/events{/number}", + "issues_url": "https://api.github.com/repos/KacperMalachowski/test-infra/issues{/number}", + "keys_url": "https://api.github.com/repos/KacperMalachowski/test-infra/keys{/key_id}", + "labels_url": "https://api.github.com/repos/KacperMalachowski/test-infra/labels{/name}", + "language": "Go", + "languages_url": "https://api.github.com/repos/KacperMalachowski/test-infra/languages", + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "node_id": "MDc6TGljZW5zZTI=", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0" + }, + "merges_url": "https://api.github.com/repos/KacperMalachowski/test-infra/merges", + "milestones_url": "https://api.github.com/repos/KacperMalachowski/test-infra/milestones{/number}", + "mirror_url": null, + "name": "test-infra", + "node_id": "R_kgDOIGV4OQ", + "notifications_url": "https://api.github.com/repos/KacperMalachowski/test-infra/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/38684517?v=4", + "events_url": "https://api.github.com/users/KacperMalachowski/events{/privacy}", + "followers_url": "https://api.github.com/users/KacperMalachowski/followers", + "following_url": "https://api.github.com/users/KacperMalachowski/following{/other_user}", + "gists_url": "https://api.github.com/users/KacperMalachowski/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/KacperMalachowski", + "id": 38684517, + "login": "KacperMalachowski", + "node_id": "MDQ6VXNlcjM4Njg0NTE3", + "organizations_url": "https://api.github.com/users/KacperMalachowski/orgs", + "received_events_url": "https://api.github.com/users/KacperMalachowski/received_events", + "repos_url": "https://api.github.com/users/KacperMalachowski/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/KacperMalachowski/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/KacperMalachowski/subscriptions", + "type": "User", + "url": "https://api.github.com/users/KacperMalachowski" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/KacperMalachowski/test-infra/pulls{/number}", + "pushed_at": "2024-07-01T11:57:56Z", + "releases_url": "https://api.github.com/repos/KacperMalachowski/test-infra/releases{/id}", + "size": 43126, + "ssh_url": "git@github.com:KacperMalachowski/test-infra.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/KacperMalachowski/test-infra/stargazers", + "statuses_url": "https://api.github.com/repos/KacperMalachowski/test-infra/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/KacperMalachowski/test-infra/subscribers", + "subscription_url": "https://api.github.com/repos/KacperMalachowski/test-infra/subscription", + "svn_url": "https://github.com/KacperMalachowski/test-infra", + "tags_url": "https://api.github.com/repos/KacperMalachowski/test-infra/tags", + "teams_url": "https://api.github.com/repos/KacperMalachowski/test-infra/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/KacperMalachowski/test-infra/git/trees{/sha}", + "updated_at": "2024-07-01T11:57:59Z", + "url": "https://api.github.com/repos/KacperMalachowski/test-infra", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/38684517?v=4", + "events_url": "https://api.github.com/users/KacperMalachowski/events{/privacy}", + "followers_url": "https://api.github.com/users/KacperMalachowski/followers", + "following_url": "https://api.github.com/users/KacperMalachowski/following{/other_user}", + "gists_url": "https://api.github.com/users/KacperMalachowski/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/KacperMalachowski", + "id": 38684517, + "login": "KacperMalachowski", + "node_id": "MDQ6VXNlcjM4Njg0NTE3", + "organizations_url": "https://api.github.com/users/KacperMalachowski/orgs", + "received_events_url": "https://api.github.com/users/KacperMalachowski/received_events", + "repos_url": "https://api.github.com/users/KacperMalachowski/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/KacperMalachowski/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/KacperMalachowski/subscriptions", + "type": "User", + "url": "https://api.github.com/users/KacperMalachowski" + }, + "workflow": ".github/workflows/test.yaml" +} \ No newline at end of file diff --git a/pkg/azuredevops/pipelines/templatesParams.go b/pkg/azuredevops/pipelines/templatesParams.go index aa1bb9269496..fdd2cd55a2a9 100644 --- a/pkg/azuredevops/pipelines/templatesParams.go +++ b/pkg/azuredevops/pipelines/templatesParams.go @@ -42,6 +42,11 @@ func (p OCIImageBuilderTemplateParams) SetPostsubmitJobType() { p["JobType"] = "postsubmit" } +// SetOnDemandJobType sets required parameter JobType to on-demand. +func (p OCIImageBuilderTemplateParams) SetOnDemandJobType() { + p["JobType"] = "on-demand" +} + // SetPullNumber sets optional parameter PullNumber. func (p OCIImageBuilderTemplateParams) SetPullNumber(number string) { p["PullNumber"] = number @@ -55,6 +60,11 @@ func (p OCIImageBuilderTemplateParams) SetBaseSHA(sha string) { p["PullBaseSHA"] = sha } +// SetBaseRef sets required parameter BaseRef. +func (p OCIImageBuilderTemplateParams) SetBaseRef(ref string) { + p["BaseRef"] = ref +} + // SetPullSHA sets optional parameter PullSHA. // This is the pull request head commit SHA with source code for building image for tests. func (p OCIImageBuilderTemplateParams) SetPullSHA(sha string) { @@ -139,8 +149,8 @@ func (p OCIImageBuilderTemplateParams) Validate() error { if jobType, ok = p["JobType"]; !ok { return ErrRequiredParamNotSet("JobType") } - if jobType != "presubmit" && jobType != "postsubmit" { - return fmt.Errorf("JobType must be either presubmit or postsubmit, got: %s", jobType) + if jobType != "presubmit" && jobType != "postsubmit" && jobType != "on-demand" { + return fmt.Errorf("JobType must be either presubmit, postsubmit or on-demand, got: %s", jobType) } if _, ok = p["PullBaseSHA"]; !ok { return ErrRequiredParamNotSet("BaseSHA") diff --git a/pkg/azuredevops/pipelines/templatesParams_test.go b/pkg/azuredevops/pipelines/templatesParams_test.go index c185c54f0a5f..8c8092da4dbc 100644 --- a/pkg/azuredevops/pipelines/templatesParams_test.go +++ b/pkg/azuredevops/pipelines/templatesParams_test.go @@ -36,6 +36,11 @@ var _ = Describe("Test OCIImageBuilderTemplateParams", func() { Expect(params["JobType"]).To(Equal("postsubmit")) }) + It("sets the correct JobType to on-demand", func() { + params.SetOnDemandJobType() + Expect(params["JobType"]).To(Equal("on-demand")) + }) + It("sets the correct PullNumber", func() { params.SetPullNumber("123") Expect(params["PullNumber"]).To(Equal("123")) @@ -97,7 +102,8 @@ var _ = Describe("Test OCIImageBuilderTemplateParams", func() { params.SetRepoName("testName") params.SetRepoOwner("testOwner") params.SetPresubmitJobType() - params.SetBaseSHA("abc") + params.SetBaseSHA("abc123") + params.SetBaseRef("main") params.SetImageName("my-image") params.SetDockerfilePath("/path/to/dockerfile") params.SetBuildContext("/path/to/context") @@ -111,7 +117,7 @@ var _ = Describe("Test OCIImageBuilderTemplateParams", func() { Expect(err).NotTo(BeNil()) }) - It("returns error if JobType is not presubmit or postsubmit", func() { + It("returns error if JobType is not presubmit or postsubmit or on-demand", func() { params["JobType"] = "otherType" err := params.Validate()