Skip to content

Commit fff820b

Browse files
committed
CI: Add Blossom secure flow
Add GitHub Actions workflow, dispatcher job, and leaf jobs to enable internal Jenkins CI on openucx/ucx PRs triggered via /build comment. Signed-off-by: Alexey Rivkin <arivkin@nvidia.com>
1 parent 4c80964 commit fff820b

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

.ci/jenkins/Jenkinsfile.github

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/groovy
2+
3+
@Library('blossom-github-lib@master')
4+
@Library('github.com/Mellanox/ci-demo@master')
5+
def matrix = new com.mellanox.cicd.Matrix()
6+
7+
import ipp.blossom.*
8+
9+
def githubHelper = null
10+
def blueOceanUrl = ""
11+
12+
if (params.githubData) {
13+
withCredentials([usernamePassword(credentialsId: 'github-token', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
14+
githubHelper = GithubHelper.getInstance("${GIT_PASSWORD}", params.githubData)
15+
}
16+
17+
def blueOceanJobPath = env.JOB_NAME.replace('/', '%2F')
18+
blueOceanUrl = "${JENKINS_URL}blue/organizations/jenkins/${blueOceanJobPath}/detail/${env.JOB_BASE_NAME}/${env.BUILD_NUMBER}/pipeline/"
19+
20+
githubHelper.updateCommitStatus(blueOceanUrl, "CI started", GitHubCommitState.PENDING, env.JOB_BASE_NAME)
21+
currentBuild.description = githubHelper.getBuildDescription()
22+
}
23+
24+
try {
25+
matrix.main()
26+
} catch (Exception ex) {
27+
println ex
28+
throw ex
29+
} finally {
30+
if (params.githubData) {
31+
githubHelper.updateCommitStatus(
32+
blueOceanUrl,
33+
"CI completed",
34+
currentBuild.resultIsBetterOrEqualTo('SUCCESS') ? GitHubCommitState.SUCCESS : GitHubCommitState.FAILURE,
35+
env.JOB_BASE_NAME
36+
)
37+
githubHelper.uploadLogs(this, env.JOB_NAME, env.BUILD_NUMBER, null, null)
38+
}
39+
}

.ci/jenkins/proj_jjb_github.yaml

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Jenkins Job Builder (JJB) configuration for UCX GitHub (Blossom) jobs
2+
#
3+
# Entry point: ucx-dispatcher-github (generic-webhook-trigger token must match job name)
4+
# Leaf jobs: ucx-*-github (triggered by dispatcher, not directly from GitHub)
5+
#
6+
# NOTE: This file is applied by DevOps to Jenkins.
7+
8+
- job-template:
9+
name: "{jjb_proj}-dispatcher-github"
10+
folder: "UCX-GitHub"
11+
project-type: pipeline
12+
properties:
13+
- github:
14+
url: "https://github.com/openucx/ucx"
15+
- build-discarder:
16+
days-to-keep: 14
17+
num-to-keep: 1000
18+
- inject:
19+
keep-system-variables: true
20+
properties-content: |
21+
jjb_proj={jjb_proj}-dispatcher-github
22+
triggers:
23+
- generic-webhook-trigger:
24+
token: "{jjb_proj}-dispatcher-github"
25+
print-contributors: true
26+
print-posted-content: true
27+
silent-response: false
28+
cause: "GitHub Blossom trigger"
29+
post-content-params:
30+
- type: JSONPath
31+
key: githubData
32+
value: $
33+
- type: JSONPath
34+
key: VARIABLE_FROM_POST
35+
value: $
36+
description: "UCX GitHub dispatcher (Blossom). Do NOT edit via Web GUI!"
37+
concurrent: true
38+
sandbox: true
39+
parameters:
40+
- string:
41+
name: "VARIABLE_FROM_POST"
42+
default: ""
43+
description: "Raw GitHub webhook payload (Blossom)"
44+
dsl: |
45+
@Library('blossom-github-lib@master')
46+
import ipp.blossom.*
47+
48+
def githubHelper = null
49+
withCredentials([usernamePassword(credentialsId: 'github-token', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {{
50+
githubHelper = GithubHelper.getInstance("${{GIT_PASSWORD}}", VARIABLE_FROM_POST)
51+
}}
52+
53+
def sha = githubHelper.getMergedSHA()
54+
55+
currentBuild.description = githubHelper.getBuildDescription()
56+
57+
def jobs = [
58+
'ucx-codestyle-github',
59+
'ucx-static-checks-github',
60+
'ucx-coverity-github',
61+
'ucx-build-github',
62+
'ucx-build-static-github',
63+
]
64+
65+
def fanout = [:]
66+
for (def j in jobs) {{
67+
def jobName = "UCX-GitHub/${{j}}"
68+
fanout[jobName] = {{
69+
build job: jobName, parameters: [
70+
string(name: 'sha1', value: sha),
71+
string(name: 'githubData', value: VARIABLE_FROM_POST),
72+
], propagate: false, wait: true
73+
}}
74+
}}
75+
parallel fanout
76+
77+
- job-template:
78+
name: "{jjb_proj}"
79+
folder: "UCX-GitHub"
80+
project-type: pipeline
81+
disabled: false
82+
properties:
83+
- github:
84+
url: "https://github.com/openucx/ucx"
85+
- build-discarder:
86+
days-to-keep: 14
87+
num-to-keep: 1000
88+
- inject:
89+
keep-system-variables: true
90+
properties-content: |
91+
jjb_proj={jjb_proj}
92+
description: "{jjb_description}"
93+
concurrent: true
94+
sandbox: true
95+
parameters:
96+
- string:
97+
name: "sha1"
98+
default: "master"
99+
description: "Git ref/commit to build, set by dispatcher"
100+
- string:
101+
name: "githubData"
102+
default: ""
103+
description: "Webhook payload from Blossom"
104+
- string:
105+
name: "conf_file"
106+
default: "{jjb_conf_file}"
107+
description: "Matrix config file"
108+
- bool:
109+
name: "build_dockers"
110+
default: false
111+
description: "Force rebuild docker containers (if supported)"
112+
- string:
113+
name: "DEBUG"
114+
default: 0
115+
description: "Enable debug prints and traces, valid values are 0-9"
116+
pipeline-scm:
117+
scm:
118+
- git:
119+
url: "https://github.com/openucx/ucx.git"
120+
branches: [ '$sha1' ]
121+
shallow-clone: false
122+
do-not-fetch-tags: false
123+
refspec: "+refs/heads/*:refs/remotes/origin/* +refs/pull/*:refs/remotes/origin/pr/* +refs/tags/*:refs/remotes/origin/tags/*"
124+
browser: githubweb
125+
browser-url: "https://github.com/openucx/ucx"
126+
script-path: ".ci/jenkins/Jenkinsfile.github"
127+
128+
- project:
129+
name: ucx-dispatcher-github
130+
jjb_proj: "ucx"
131+
jobs:
132+
- "{jjb_proj}-dispatcher-github"
133+
134+
- project:
135+
name: ucx-codestyle-github
136+
jjb_proj: "ucx-codestyle-github"
137+
jjb_conf_file: ".ci/pipeline/codestyle_matrix.yaml"
138+
jjb_description: "UCX Codestyle checks (GitHub Blossom). Do NOT edit via Web GUI!"
139+
jobs:
140+
- "{jjb_proj}"
141+
142+
- project:
143+
name: ucx-static-checks-github
144+
jjb_proj: "ucx-static-checks-github"
145+
jjb_conf_file: ".ci/pipeline/static_checks_matrix.yaml"
146+
jjb_description: "UCX Static checks (GitHub Blossom). Do NOT edit via Web GUI!"
147+
jobs:
148+
- "{jjb_proj}"
149+
150+
- project:
151+
name: ucx-coverity-github
152+
jjb_proj: "ucx-coverity-github"
153+
jjb_conf_file: ".ci/pipeline/coverity_matrix.yaml"
154+
jjb_description: "UCX Coverity (GitHub Blossom). Do NOT edit via Web GUI!"
155+
jobs:
156+
- "{jjb_proj}"
157+
158+
- project:
159+
name: ucx-build-github
160+
jjb_proj: "ucx-build-github"
161+
jjb_conf_file: ".ci/pipeline/build_matrix.yaml"
162+
jjb_description: "UCX Build job (GitHub Blossom). Do NOT edit via Web GUI!"
163+
jobs:
164+
- "{jjb_proj}"
165+
166+
- project:
167+
name: ucx-build-static-github
168+
jjb_proj: "ucx-build-static-github"
169+
jjb_conf_file: ".ci/pipeline/build_static_matrix.yaml"
170+
jjb_description: "UCX Static build (GitHub Blossom). Do NOT edit via Web GUI!"
171+
jobs:
172+
- "{jjb_proj}"

.github/workflows/blossom-ci.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2026. ALL RIGHTS RESERVED.
2+
# See file LICENSE for terms.
3+
4+
# A workflow to trigger ci on hybrid infra (github + self hosted runner)
5+
6+
name: Blossom-CI
7+
run-name: >
8+
${{ github.event_name == 'workflow_dispatch' &&
9+
format(
10+
'Blossom CI: {0}{1} PR #{2}',
11+
fromJson(github.event.inputs.args).job,
12+
fromJson(github.event.inputs.args).build && format(' #{0}', fromJson(github.event.inputs.args).build) || '',
13+
fromJson(github.event.inputs.args).pr
14+
)
15+
|| '' }}
16+
on:
17+
issue_comment:
18+
types: [created]
19+
workflow_dispatch:
20+
inputs:
21+
platform:
22+
description: 'runs-on argument'
23+
required: false
24+
args:
25+
description: 'argument'
26+
required: false
27+
jobs:
28+
Authorization:
29+
name: Authorization
30+
runs-on: blossom
31+
outputs:
32+
args: ${{ env.args }}
33+
34+
# This job only runs for pull request comments
35+
if: github.event.comment.body == '/build'
36+
steps:
37+
- name: Check if comment is issued by authorized person
38+
run: blossom-ci
39+
env:
40+
OPERATION: 'AUTH'
41+
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
REPO_KEY_DATA: ${{ secrets.BLOSSOM_KEY }}
43+
44+
Vulnerability-scan:
45+
name: Vulnerability scan
46+
needs: [Authorization]
47+
runs-on: ubuntu-latest
48+
steps:
49+
- name: Checkout code
50+
uses: actions/checkout@v2
51+
with:
52+
repository: ${{ fromJson(needs.Authorization.outputs.args).repo }}
53+
ref: ${{ fromJson(needs.Authorization.outputs.args).ref }}
54+
lfs: 'true'
55+
56+
- name: Run blossom action
57+
uses: NVIDIA/blossom-action@main
58+
env:
59+
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
REPO_KEY_DATA: ${{ secrets.BLOSSOM_KEY }}
61+
with:
62+
args1: ${{ fromJson(needs.Authorization.outputs.args).args1 }}
63+
args2: ${{ fromJson(needs.Authorization.outputs.args).args2 }}
64+
args3: ${{ fromJson(needs.Authorization.outputs.args).args3 }}
65+
66+
Job-trigger:
67+
name: Start ci job
68+
needs: [Vulnerability-scan]
69+
runs-on: blossom
70+
steps:
71+
- name: Start ci job
72+
run: blossom-ci
73+
env:
74+
OPERATION: 'START-CI-JOB'
75+
CI_SERVER: ${{ secrets.CI_SERVER }}
76+
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77+
78+
Upload-Log:
79+
name: Upload log
80+
runs-on: blossom
81+
if: github.event_name == 'workflow_dispatch'
82+
steps:
83+
- name: Jenkins log for pull request ${{ fromJson(github.event.inputs.args).pr }} (click here)
84+
run: blossom-ci
85+
env:
86+
OPERATION: 'POST-PROCESSING'
87+
CI_SERVER: ${{ secrets.CI_SERVER }}
88+
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)