Skip to content

Commit 79ae485

Browse files
authored
Autorun manual jobs before merge (#63)
1 parent e930a92 commit 79ae485

File tree

7 files changed

+50
-3
lines changed

7 files changed

+50
-3
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Reasons can be for example:
2121
### Advanced features
2222

2323
- Autogenerated commit message based on MR title (Suffixed with link to the original MR).
24+
- The blocking jobs are triggered automatically. Very useful for E2E testing etc.
2425
- Bot skips squashing when `bot:skip-squash` label is present on the MR.
2526
- Bot assigns MR to the beginning of the queue when `bot:hi-priority` is present. Useful for hotfixes etc.
2627

@@ -89,5 +90,6 @@ GITLAB_AUTH_TOKEN="<token>" yarn run start
8990
| `MR_CHECK_INTERVAL` | `20` | Time between merge-requests checks (in seconds) |
9091
| `REMOVE_BRANCH_AFTER_MERGE` | `true` | It'll remove branch after merge |
9192
| `SQUASH_MERGE_REQUEST` | `true` | It'll squash commits on merge |
93+
| `AUTORUN_MANUAL_BLOCKING_JOBS` | `true` | It'll autorun manual blocking jobs before merge |
9294
| `SKIP_SQUASHING_LABEL` | `bot:skip-squash` | It'll skip squash when MR contains this label |
9395
| `HI_PRIORITY_LABEL` | `bot:hi-priority` | It'll put MR with this label to the beginning of the queue |

charts/gitlab-merger-bot/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v1
22
appVersion: "1.0"
33
description: A Helm chart for Kubernetes
44
name: gitlab-merger-bot
5-
version: 1.2.1
5+
version: 1.2.2
66
home: https://github.com/pepakriz/gitlab-merger-bot
77
maintainers:
88
- name: pepakriz

charts/gitlab-merger-bot/templates/deployment.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ spec:
4545
value: "{{ .Values.settings.ciCheckInterval }}"
4646
- name: MR_CHECK_INTERVAL
4747
value: "{{ .Values.settings.mrCheckInterval }}"
48+
- name: AUTORUN_MANUAL_BLOCKING_JOBS
49+
value: "{{ .Values.settings.autorunManualBlockingJobs }}"
4850
- name: SENTRY_DSN
4951
value: "{{ .Values.settings.sentryDsn }}"
5052
- name: SKIP_SQUASHING_LABEL

charts/gitlab-merger-bot/values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ settings:
2626
sentryDsn: ""
2727
ciCheckInterval: 10
2828
mrCheckInterval: 20
29+
autorunManualBlockingJobs: true
2930
skipSquashingLabel: ""
3031
hiPriorityLabel: ""

src/GitlabApi.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ export interface MergeRequestPipeline {
7878
status: PipelineStatus;
7979
}
8080

81+
export enum PipelineJobStatus {
82+
Manual = 'manual',
83+
Failed = 'failed',
84+
Canceled = 'canceled',
85+
Pending = 'pending',
86+
Started = 'started',
87+
Running = 'running',
88+
}
89+
90+
export interface PipelineJob {
91+
id: number;
92+
allow_failure: boolean;
93+
status: PipelineJobStatus;
94+
}
95+
8196
export interface MergeRequestInfo extends MergeRequest {
8297
sha: string;
8398
diff_refs: {
@@ -137,6 +152,10 @@ export class GitlabApi {
137152
return this.sendRequestWithMultiResponse(`/api/v4/projects/${projectId}/merge_requests/${mergeRequestIid}/pipelines`, RequestMethod.Get);
138153
}
139154

155+
public async getPipelineJobs(projectId: number, pipelineId: number): Promise<PipelineJob[]> {
156+
return this.sendRequestWithMultiResponse(`/api/v4/projects/${projectId}/pipelines/${pipelineId}/jobs`, RequestMethod.Get);
157+
}
158+
140159
public async getMergeRequestApprovals(projectId: number, mergeRequestIid: number): Promise<MergeRequestApprovals> {
141160
return this.sendRequestWithSingleResponse(`/api/v4/projects/${projectId}/merge_requests/${mergeRequestIid}/approvals`, RequestMethod.Get);
142161
}
@@ -168,6 +187,11 @@ export class GitlabApi {
168187
this.validateResponseStatus(response);
169188
}
170189

190+
public async runJob(projectId: number, jobId: number): Promise<void> {
191+
const response = await this.sendRawRequest(`/api/v4/projects/${projectId}/jobs/${jobId}/play`, RequestMethod.Post);
192+
this.validateResponseStatus(response);
193+
}
194+
171195
private async sendRequestWithSingleResponse(url: string, method: RequestMethod, body?: ParsedUrlQueryInput): Promise<any> {
172196
const response = await this.sendRawRequest(url, method, body);
173197
this.validateResponseStatus(response);

src/MergeRequestAcceptor.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import {
22
GitlabApi,
3-
MergeRequest, MergeRequestApprovals,
4-
MergeRequestInfo, MergeRequestPipeline,
3+
MergeRequest,
4+
MergeRequestApprovals,
5+
MergeRequestInfo,
6+
MergeRequestPipeline,
57
MergeState,
68
MergeStatus,
9+
PipelineJobStatus,
710
PipelineStatus,
811
RequestMethod,
912
User,
@@ -106,6 +109,7 @@ interface AcceptMergeRequestOptions {
106109
removeBranchAfterMerge: boolean;
107110
squashMergeRequest: boolean;
108111
skipSquashingLabel: string;
112+
autorunManualBlockingJobs: boolean;
109113
}
110114

111115
export enum BotLabels {
@@ -318,6 +322,18 @@ export const acceptMergeRequest = async (gitlabApi: GitlabApi, mergeRequest: Mer
318322
};
319323
}
320324

325+
if (options.autorunManualBlockingJobs && currentPipeline.status === PipelineStatus.Manual) {
326+
const jobs = await gitlabApi.getPipelineJobs(mergeRequestInfo.project_id, currentPipeline.id);
327+
const jobsToRun = jobs.filter((job) => job.status === PipelineJobStatus.Manual && !job.allow_failure);
328+
329+
if (jobsToRun.length > 0) {
330+
console.log(`[MR][${mergeRequestInfo.iid}] there are some blocking manual jobs. triggering`);
331+
await Promise.all(jobsToRun.map((job) => gitlabApi.runJob(mergeRequestInfo.project_id, job.id)));
332+
await Promise.all(tasks);
333+
continue;
334+
}
335+
}
336+
321337
if (currentPipeline.status === PipelineStatus.Manual) {
322338
return {
323339
kind: AcceptMergeRequestResultKind.WaitingPipeline,

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const CI_CHECK_INTERVAL = env.get('CI_CHECK_INTERVAL').default('10').asIntPositi
2525
const MR_CHECK_INTERVAL = env.get('MR_CHECK_INTERVAL').default('20').asIntPositive() * 1000;
2626
const REMOVE_BRANCH_AFTER_MERGE = env.get('REMOVE_BRANCH_AFTER_MERGE').default('true').asBoolStrict();
2727
const SQUASH_MERGE_REQUEST = env.get('SQUASH_MERGE_REQUEST').default('true').asBoolStrict();
28+
const AUTORUN_MANUAL_BLOCKING_JOBS = env.get('AUTORUN_MANUAL_BLOCKING_JOBS').default('true').asBoolStrict();
2829
const SKIP_SQUASHING_LABEL = env.get('SKIP_SQUASHING_LABEL').default('bot:skip-squash').asString();
2930
const HI_PRIORITY_LABEL = env.get('HI_PRIORITY_LABEL').default('bot:hi-priority').asString();
3031

@@ -242,6 +243,7 @@ const runMergeRequestCheckerLoop = async (user: User) => {
242243
removeBranchAfterMerge: REMOVE_BRANCH_AFTER_MERGE,
243244
squashMergeRequest: SQUASH_MERGE_REQUEST,
244245
skipSquashingLabel: SKIP_SQUASHING_LABEL,
246+
autorunManualBlockingJobs: AUTORUN_MANUAL_BLOCKING_JOBS,
245247
}),
246248
).then(resolveMergeRequestResult);
247249

0 commit comments

Comments
 (0)