diff --git a/web/components.d.ts b/web/components.d.ts
index 982dbccbe..8a2d022af 100644
--- a/web/components.d.ts
+++ b/web/components.d.ts
@@ -15,6 +15,7 @@ declare module '@vue/runtime-core' {
Checkbox: typeof import('./src/components/form/Checkbox.vue')['default']
CheckboxesField: typeof import('./src/components/form/CheckboxesField.vue')['default']
CronTab: typeof import('./src/components/repo/settings/CronTab.vue')['default']
+ DeployPipelinePopup: typeof import('./src/components/layout/popups/DeployPipelinePopup.vue')['default']
DocsLink: typeof import('./src/components/atomic/DocsLink.vue')['default']
FluidContainer: typeof import('./src/components/layout/FluidContainer.vue')['default']
GeneralTab: typeof import('./src/components/repo/settings/GeneralTab.vue')['default']
diff --git a/web/src/assets/locales/en.json b/web/src/assets/locales/en.json
index 82874a454..4ee285ede 100644
--- a/web/src/assets/locales/en.json
+++ b/web/src/assets/locales/en.json
@@ -41,6 +41,18 @@
"value": "Variable value"
}
},
+ "deploy_pipeline": {
+ "title": "Trigger deployment event for current pipeline #{pipelineId}",
+ "enter_target": "Target deployment environment",
+ "trigger": "Deploy",
+ "variables": {
+ "add": "Add variable",
+ "title": "Additional pipeline variables",
+ "desc": "Specify additional variables to use in your pipeline. Variables with the same name will be overwritten.",
+ "name": "Variable name",
+ "value": "Variable value"
+ }
+ },
"activity": "Activity",
"branches": "Branches",
"add": "Add repository",
@@ -218,6 +230,7 @@
"restart": "Restart",
"canceled": "This step has been canceled.",
"cancel_success": "Pipeline canceled",
+ "deploy": "Deploy",
"restart_success": "Pipeline restarted",
"log_download": "Download",
"log_auto_scroll": "Automatically scroll down",
diff --git a/web/src/components/layout/popups/DeployPipelinePopup.vue b/web/src/components/layout/popups/DeployPipelinePopup.vue
new file mode 100644
index 000000000..04198596d
--- /dev/null
+++ b/web/src/components/layout/popups/DeployPipelinePopup.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
diff --git a/web/src/lib/api/index.ts b/web/src/lib/api/index.ts
index 5ace212f1..b030a89b3 100644
--- a/web/src/lib/api/index.ts
+++ b/web/src/lib/api/index.ts
@@ -23,6 +23,13 @@ type PipelineOptions = {
branch: string;
variables: Record;
};
+
+type DeploymentOptions = {
+ id: string;
+ environment: string;
+ variables: Record;
+};
+
export default class WoodpeckerClient extends ApiClient {
getRepoList(opts?: RepoListOptions): Promise {
const query = encodeQueryString(opts);
@@ -62,6 +69,18 @@ export default class WoodpeckerClient extends ApiClient {
return this._post(`/api/repos/${owner}/${repo}/pipelines`, options) as Promise;
}
+ // Deploy triggers a deployment for an existing pipeline using the
+ // specified target environment.
+ deployPipeline(owner: string, repo: string, number: number, options: DeploymentOptions): Promise {
+ const vars = {
+ ...options.variables,
+ event: 'deployment',
+ deploy_to: options.environment,
+ };
+ const query = encodeQueryString(vars);
+ return this._post(`/api/repos/${owner}/${repo}/pipelines/${number}?${query}`) as Promise;
+ }
+
getPipelineList(owner: string, repo: string, opts?: Record): Promise {
const query = encodeQueryString(opts);
return this._get(`/api/repos/${owner}/${repo}/pipelines?${query}`) as Promise;
diff --git a/web/src/views/repo/pipeline/PipelineWrapper.vue b/web/src/views/repo/pipeline/PipelineWrapper.vue
index 96c4aa050..3b0836f75 100644
--- a/web/src/views/repo/pipeline/PipelineWrapper.vue
+++ b/web/src/views/repo/pipeline/PipelineWrapper.vue
@@ -31,6 +31,17 @@
:is-loading="isRestartingPipeline"
@click="restartPipeline"
/>
+
+
@@ -66,7 +77,7 @@