Support github deploy task (#3512)

Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
This commit is contained in:
Fernando Barbosa 2024-05-02 13:56:19 -03:00 committed by GitHub
parent 225ddb586d
commit e6bda2c2b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 44 additions and 16 deletions

View file

@ -204,6 +204,10 @@ var flags = []cli.Flag{
EnvVars: []string{"CI_PIPELINE_TARGET"},
Name: "pipeline-target",
},
&cli.StringFlag{
EnvVars: []string{"CI_PIPELINE_TASK"},
Name: "pipeline-task",
},
&cli.StringFlag{
EnvVars: []string{"CI_COMMIT_SHA"},
Name: "commit-sha",

View file

@ -61,6 +61,7 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) metadata.Metadata {
Event: c.String("pipeline-event"),
ForgeURL: c.String("pipeline-url"),
Target: c.String("pipeline-target"),
Task: c.String("pipeline-task"),
Commit: metadata.Commit{
Sha: c.String("commit-sha"),
Ref: c.String("commit-ref"),

View file

@ -4023,6 +4023,9 @@ const docTemplate = `{
"created_at": {
"type": "integer"
},
"deploy_task": {
"type": "string"
},
"deploy_to": {
"type": "string"
},

View file

@ -85,6 +85,7 @@ This is the reference list of all environment variables available to your pipeli
| `CI_PIPELINE_URL` | link to the web UI for the pipeline |
| `CI_PIPELINE_FORGE_URL` | link to the forge's web UI for the commit(s) or tag that triggered the pipeline |
| `CI_PIPELINE_DEPLOY_TARGET` | pipeline deploy target for `deployment` events (i.e. production) |
| `CI_PIPELINE_DEPLOY_TASK` | pipeline deploy task for `deployment` events (i.e. migration) |
| `CI_PIPELINE_STATUS` | pipeline status (success, failure) |
| `CI_PIPELINE_CREATED` | pipeline created UNIX timestamp |
| `CI_PIPELINE_STARTED` | pipeline started UNIX timestamp |
@ -118,6 +119,7 @@ This is the reference list of all environment variables available to your pipeli
| `CI_PREV_PIPELINE_URL` | previous pipeline link in CI |
| `CI_PREV_PIPELINE_FORGE_URL` | previous pipeline link to event in forge |
| `CI_PREV_PIPELINE_DEPLOY_TARGET` | previous pipeline deploy target for `deployment` events (ie production) |
| `CI_PREV_PIPELINE_DEPLOY_TASK` | previous pipeline deploy task for `deployment` events (ie migration) |
| `CI_PREV_PIPELINE_STATUS` | previous pipeline status (success, failure) |
| `CI_PREV_PIPELINE_CREATED` | previous pipeline created UNIX timestamp |
| `CI_PREV_PIPELINE_STARTED` | previous pipeline started UNIX timestamp |

View file

@ -77,6 +77,7 @@ func (m *Metadata) Environ() map[string]string {
"CI_PIPELINE_URL": m.getPipelineWebURL(m.Curr, 0),
"CI_PIPELINE_FORGE_URL": m.Curr.ForgeURL,
"CI_PIPELINE_DEPLOY_TARGET": m.Curr.Target,
"CI_PIPELINE_DEPLOY_TASK": m.Curr.Task,
"CI_PIPELINE_STATUS": m.Curr.Status,
"CI_PIPELINE_CREATED": strconv.FormatInt(m.Curr.Created, 10),
"CI_PIPELINE_STARTED": strconv.FormatInt(m.Curr.Started, 10),
@ -108,6 +109,7 @@ func (m *Metadata) Environ() map[string]string {
"CI_PREV_PIPELINE_URL": m.getPipelineWebURL(m.Prev, 0),
"CI_PREV_PIPELINE_FORGE_URL": m.Prev.ForgeURL,
"CI_PREV_PIPELINE_DEPLOY_TARGET": m.Prev.Target,
"CI_PREV_PIPELINE_DEPLOY_TASK": m.Prev.Task,
"CI_PREV_PIPELINE_STATUS": m.Prev.Status,
"CI_PREV_PIPELINE_CREATED": strconv.FormatInt(m.Prev.Created, 10),
"CI_PREV_PIPELINE_STARTED": strconv.FormatInt(m.Prev.Started, 10),

View file

@ -53,6 +53,7 @@ type (
Event string `json:"event,omitempty"`
ForgeURL string `json:"forge_url,omitempty"`
Target string `json:"target,omitempty"`
Task string `json:"task,omitempty"`
Trusted bool `json:"trusted,omitempty"`
Commit Commit `json:"commit,omitempty"`
Parent int64 `json:"parent,omitempty"`

View file

@ -547,6 +547,9 @@ func PostPipeline(c *gin.Context) {
// make Deploy overridable
// make Deploy task overridable
pl.DeployTask = c.DefaultQuery("deploy_task", pl.DeployTask)
// make Event overridable to deploy
// TODO refactor to use own proper API for deploy
if event, ok := c.GetQuery("event"); ok {

View file

@ -224,6 +224,7 @@ func Test_helper(t *testing.T) {
from := &github.DeploymentEvent{Deployment: &github.Deployment{}, Sender: &github.User{}}
from.Deployment.Description = github.String(":shipit:")
from.Deployment.Environment = github.String("production")
from.Deployment.Task = github.String("deploy")
from.Deployment.ID = github.Int64(42)
from.Deployment.Ref = github.String("main")
from.Deployment.SHA = github.String("f72fc19")

View file

@ -120,16 +120,17 @@ func parsePushHook(hook *github.PushEvent) (*model.Repo, *model.Pipeline) {
// If the commit type is unsupported nil values are returned.
func parseDeployHook(hook *github.DeploymentEvent) (*model.Repo, *model.Pipeline) {
pipeline := &model.Pipeline{
Event: model.EventDeploy,
Commit: hook.GetDeployment().GetSHA(),
ForgeURL: hook.GetDeployment().GetURL(),
Message: hook.GetDeployment().GetDescription(),
Ref: hook.GetDeployment().GetRef(),
Branch: hook.GetDeployment().GetRef(),
Deploy: hook.GetDeployment().GetEnvironment(),
Avatar: hook.GetSender().GetAvatarURL(),
Author: hook.GetSender().GetLogin(),
Sender: hook.GetSender().GetLogin(),
Event: model.EventDeploy,
Commit: hook.GetDeployment().GetSHA(),
ForgeURL: hook.GetDeployment().GetURL(),
Message: hook.GetDeployment().GetDescription(),
Ref: hook.GetDeployment().GetRef(),
Branch: hook.GetDeployment().GetRef(),
Deploy: hook.GetDeployment().GetEnvironment(),
Avatar: hook.GetSender().GetAvatarURL(),
Author: hook.GetSender().GetLogin(),
Sender: hook.GetSender().GetLogin(),
DeployTask: hook.GetDeployment().GetTask(),
}
// if the ref is a sha or short sha we need to manually construct the ref.
if strings.HasPrefix(pipeline.Commit, pipeline.Ref) || pipeline.Commit == pipeline.Ref {

View file

@ -119,6 +119,8 @@ func Test_parser(t *testing.T) {
g.Assert(b).IsNotNil()
g.Assert(p).IsNil()
g.Assert(b.Event).Equal(model.EventDeploy)
g.Assert(b.Deploy).Equal("production")
g.Assert(b.DeployTask).Equal("deploy")
})
})

View file

@ -33,6 +33,7 @@ type Pipeline struct {
Started int64 `json:"started_at" xorm:"pipeline_started"`
Finished int64 `json:"finished_at" xorm:"pipeline_finished"`
Deploy string `json:"deploy_to" xorm:"pipeline_deploy"`
DeployTask string `json:"deploy_task" xorm:"pipeline_deploy_task"`
Commit string `json:"commit" xorm:"pipeline_commit"`
Branch string `json:"branch" xorm:"pipeline_branch"`
Ref string `json:"ref" xorm:"pipeline_ref"`

View file

@ -47,11 +47,11 @@ func TestMetadataFromStruct(t *testing.T) {
"CI_COMMIT_AUTHOR": "", "CI_COMMIT_AUTHOR_AVATAR": "", "CI_COMMIT_AUTHOR_EMAIL": "", "CI_COMMIT_BRANCH": "",
"CI_COMMIT_MESSAGE": "", "CI_COMMIT_PULL_REQUEST": "", "CI_COMMIT_PULL_REQUEST_LABELS": "", "CI_COMMIT_REF": "", "CI_COMMIT_REFSPEC": "", "CI_COMMIT_SHA": "", "CI_COMMIT_SOURCE_BRANCH": "",
"CI_COMMIT_TAG": "", "CI_COMMIT_TARGET_BRANCH": "", "CI_COMMIT_URL": "", "CI_FORGE_TYPE": "", "CI_FORGE_URL": "",
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FINISHED": "0", "CI_PIPELINE_FILES": "[]", "CI_PIPELINE_NUMBER": "0",
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_DEPLOY_TASK": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FINISHED": "0", "CI_PIPELINE_FILES": "[]", "CI_PIPELINE_NUMBER": "0",
"CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_STATUS": "", "CI_PIPELINE_URL": "/repos/0/pipeline/0", "CI_PIPELINE_FORGE_URL": "",
"CI_PREV_COMMIT_AUTHOR": "", "CI_PREV_COMMIT_AUTHOR_AVATAR": "", "CI_PREV_COMMIT_AUTHOR_EMAIL": "", "CI_PREV_COMMIT_BRANCH": "",
"CI_PREV_COMMIT_MESSAGE": "", "CI_PREV_COMMIT_REF": "", "CI_PREV_COMMIT_REFSPEC": "", "CI_PREV_COMMIT_SHA": "", "CI_PREV_COMMIT_URL": "", "CI_PREV_PIPELINE_CREATED": "0",
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "0", "CI_PREV_PIPELINE_PARENT": "0",
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_DEPLOY_TASK": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "0", "CI_PREV_PIPELINE_PARENT": "0",
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_STATUS": "", "CI_PREV_PIPELINE_URL": "/repos/0/pipeline/0", "CI_PREV_PIPELINE_FORGE_URL": "", "CI_REPO": "", "CI_REPO_CLONE_URL": "", "CI_REPO_CLONE_SSH_URL": "", "CI_REPO_DEFAULT_BRANCH": "", "CI_REPO_REMOTE_ID": "",
"CI_REPO_NAME": "", "CI_REPO_OWNER": "", "CI_REPO_PRIVATE": "false", "CI_REPO_SCM": "git", "CI_REPO_TRUSTED": "false", "CI_REPO_URL": "", "CI_STEP_FINISHED": "",
"CI_STEP_NAME": "", "CI_STEP_NUMBER": "0", "CI_STEP_STARTED": "", "CI_STEP_STATUS": "", "CI_STEP_URL": "/repos/0/pipeline/0", "CI_SYSTEM_HOST": "", "CI_SYSTEM_NAME": "woodpecker",
@ -82,11 +82,11 @@ func TestMetadataFromStruct(t *testing.T) {
"CI_COMMIT_AUTHOR": "", "CI_COMMIT_AUTHOR_AVATAR": "", "CI_COMMIT_AUTHOR_EMAIL": "", "CI_COMMIT_BRANCH": "",
"CI_COMMIT_MESSAGE": "", "CI_COMMIT_PULL_REQUEST": "", "CI_COMMIT_PULL_REQUEST_LABELS": "", "CI_COMMIT_REF": "", "CI_COMMIT_REFSPEC": "", "CI_COMMIT_SHA": "", "CI_COMMIT_SOURCE_BRANCH": "",
"CI_COMMIT_TAG": "", "CI_COMMIT_TARGET_BRANCH": "", "CI_COMMIT_URL": "", "CI_FORGE_TYPE": "gitea", "CI_FORGE_URL": "https://gitea.com",
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FINISHED": "0", "CI_PIPELINE_FILES": `["test.go","markdown file.md"]`,
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_DEPLOY_TASK": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FINISHED": "0", "CI_PIPELINE_FILES": `["test.go","markdown file.md"]`,
"CI_PIPELINE_NUMBER": "3", "CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_STATUS": "", "CI_PIPELINE_URL": "https://example.com/repos/0/pipeline/3", "CI_PIPELINE_FORGE_URL": "",
"CI_PREV_COMMIT_AUTHOR": "", "CI_PREV_COMMIT_AUTHOR_AVATAR": "", "CI_PREV_COMMIT_AUTHOR_EMAIL": "", "CI_PREV_COMMIT_BRANCH": "",
"CI_PREV_COMMIT_MESSAGE": "", "CI_PREV_COMMIT_REF": "", "CI_PREV_COMMIT_REFSPEC": "", "CI_PREV_COMMIT_SHA": "", "CI_PREV_COMMIT_URL": "", "CI_PREV_PIPELINE_CREATED": "0",
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "2", "CI_PREV_PIPELINE_PARENT": "0",
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_DEPLOY_TASK": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "2", "CI_PREV_PIPELINE_PARENT": "0",
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_STATUS": "", "CI_PREV_PIPELINE_URL": "https://example.com/repos/0/pipeline/2", "CI_PREV_PIPELINE_FORGE_URL": "", "CI_REPO": "testUser/testRepo", "CI_REPO_CLONE_URL": "https://gitea.com/testUser/testRepo.git", "CI_REPO_CLONE_SSH_URL": "git@gitea.com:testUser/testRepo.git",
"CI_REPO_DEFAULT_BRANCH": "main", "CI_REPO_NAME": "testRepo", "CI_REPO_OWNER": "testUser", "CI_REPO_PRIVATE": "true", "CI_REPO_REMOTE_ID": "",
"CI_REPO_SCM": "git", "CI_REPO_TRUSTED": "false", "CI_REPO_URL": "https://gitea.com/testUser/testRepo", "CI_STEP_FINISHED": "",

View file

@ -48,6 +48,7 @@
"deploy_pipeline": {
"title": "Trigger deployment event for current pipeline #{pipelineId}",
"enter_target": "Target deployment environment",
"enter_task": "Deployment task",
"trigger": "Deploy",
"variables": {
"delete": "Delete variable",

View file

@ -8,6 +8,9 @@
<InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.enter_target')">
<TextField :id="id" v-model="payload.environment" required />
</InputField>
<InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.enter_task')">
<TextField :id="id" v-model="payload.task" />
</InputField>
<InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.variables.title')">
<span class="text-sm text-wp-text-alt-100 mb-2">{{ $t('repo.deploy_pipeline.variables.desc') }}</span>
<div class="flex flex-col gap-2">
@ -69,9 +72,10 @@ const repo = inject('repo');
const router = useRouter();
const payload = ref<{ id: string; environment: string; variables: { name: string; value: string }[] }>({
const payload = ref<{ id: string; environment: string; task: string; variables: { name: string; value: string }[] }>({
id: '',
environment: '',
task: '',
variables: [
{
name: '',

View file

@ -31,6 +31,7 @@ type PipelineOptions = {
type DeploymentOptions = {
id: string;
environment: string;
task: string;
variables: Record<string, string>;
};
@ -89,12 +90,13 @@ export default class WoodpeckerClient extends ApiClient {
}
// Deploy triggers a deployment for an existing pipeline using the
// specified target environment.
// specified target environment and task.
deployPipeline(repoId: number, pipelineNumber: string, options: DeploymentOptions): Promise<Pipeline> {
const vars = {
...options.variables,
event: 'deployment',
deploy_to: options.environment,
deploy_task: options.task,
};
const query = encodeQueryString(vars);
return this._post(`/api/repos/${repoId}/pipelines/${pipelineNumber}?${query}`) as Promise<Pipeline>;