@@ -5,7 +5,7 @@ name: Build Ubuntu
55
66on :
77 push :
8- branches : [ main, 'release/*.*.x' ]
8+ branches : [ main, 'release/*.*.x', 'aaristarkhov/kitmaker' ]
99 tags : [ 'v*' ]
1010 pull_request :
1111
2424
2525 strategy :
2626 matrix :
27- build_type : ["Debug", " Release"]
27+ build_type : ["Release"]
2828 python_version : ['3.10', '3.11', '3.12']
2929 arch : ['x64', 'arm64']
3030
@@ -103,6 +103,7 @@ jobs:
103103 with :
104104 name : isaacteleop-wheels-${{ matrix.arch }}-py${{ matrix.python_version }}
105105 path : install/wheels/*.whl
106+ if-no-files-found : error
106107 retention-days : 1
107108
108109 test-cloudxr :
@@ -216,12 +217,17 @@ jobs:
216217 -p "${ARTIFACTORY_API_KEY}" \
217218 "${wheels[@]}"
218219
219- kitmaker :
220- runs-on : [self-hosted, linux]
220+ publish-github-release-assets :
221+ runs-on : ubuntu-latest
221222 needs :
222- - publish-wheel
223- environment : release
224- if : ${{ needs.publish-wheel.result == 'success' }}
223+ - build-ubuntu
224+ # - test-cloudxr
225+ outputs :
226+ wheel_urls : ${{ steps.upload-release-assets.outputs.wheel_urls }}
227+ permissions :
228+ contents : write
229+ # Publish only after build and CloudXR tests succeed.
230+ if : ${{ github.event_name == 'push' && needs.build-ubuntu.result == 'success' }} # && needs.test-cloudxr.result == 'success'
225231
226232 steps :
227233 - name : Download wheel artifacts
@@ -231,82 +237,110 @@ jobs:
231237 merge-multiple : true
232238 path : wheels
233239
234- - name : Submit wheel release to Kitmaker
240+ - name : Upload wheel(s) as GitHub release assets
241+ id : upload-release-assets
235242 env :
236- KITMAKER_PROJECT_ID : ${{ secrets.KITMAKER_PROJECT_ID }}
237- KITMAKER_TOKEN : ${{ secrets.KITMAKER_TOKEN }}
238- KITMAKER_PIC_EMAIL : ${{ secrets.KITMAKER_PIC_EMAIL }}
239- ARTIFACTORY_DOMAIN : ${{ secrets.ARTIFACTORY_DOMAIN }}
240- ARTIFACTORY_REPO : ${{ secrets.ARTIFACTORY_REPO }}
241- ARTIFACTORY_TOKEN : ${{ secrets.ARTIFACTORY_TOKEN }}
242- ARTIFACTORY_USER : ${{ secrets.ARTIFACTORY_USER }}
243+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
244+ GH_REPO : ${{ github.repository }}
243245 run : |
244246 set -euo pipefail
245247
246- if [[ -z "${KITMAKER_TOKEN}" || -z "${KITMAKER_PIC_EMAIL}" ]]; then
247- echo "Missing one or more required secrets: KITMAKER_TOKEN, KITMAKER_PIC_EMAIL"
248+ shopt -s nullglob
249+ wheels=(wheels/*.whl)
250+ if (( ${#wheels[@]} == 0 )); then
251+ echo "No wheels found under wheels/*.whl"
252+ ls -la wheels || true
248253 exit 1
249254 fi
250255
251- if [[ -z "${ARTIFACTORY_DOMAIN}" || -z "${ARTIFACTORY_REPO}" || -z "${ARTIFACTORY_TOKEN}" ]]; then
252- echo "Missing one or more required secrets: ARTIFACTORY_DOMAIN, ARTIFACTORY_REPO, ARTIFACTORY_TOKEN"
253- exit 1
254- fi
256+ tag="ci-wheels-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
257+ title="CI Wheels ${GITHUB_RUN_ID}.${GITHUB_RUN_ATTEMPT}"
258+
259+ gh release create "${tag}" \
260+ --repo "${GH_REPO}" \
261+ --target "${GITHUB_SHA}" \
262+ --title "${title}" \
263+ --notes "Automated wheel artifacts for ${GITHUB_SHA}" \
264+ --draft
255265
256- if [[ "${ARTIFACTORY_DOMAIN}" == http://* || "${ARTIFACTORY_DOMAIN}" == https://* ]]; then
257- echo "ARTIFACTORY_DOMAIN must be hostname only (no scheme), e.g. artifactory.example.com"
266+ echo "Uploading ${#wheels[@]} wheel(s) to release ${tag}"
267+ gh release upload "${tag}" "${wheels[@]}" --repo "${GH_REPO}"
268+
269+ echo "Finalizing release ${tag} as pre-release"
270+ gh release edit "${tag}" --repo "${GH_REPO}" --draft=false --prerelease
271+
272+ echo "Uploaded assets on ${tag}:"
273+ release_assets_json="$(gh release view "${tag}" --repo "${GH_REPO}" --json assets)"
274+ echo "${release_assets_json}"
275+
276+ wheel_urls="$(jq -r '.assets[] | select(.name | endswith(".whl")) | .url' <<< "${release_assets_json}")"
277+ if [[ -z "${wheel_urls}" ]]; then
278+ echo "Unable to find wheel asset URLs in uploaded release assets"
258279 exit 1
259280 fi
260281
261- if [[ "${ARTIFACTORY_DOMAIN}" == */* ]]; then
262- echo "ARTIFACTORY_DOMAIN must not contain '/'"
282+ {
283+ echo "wheel_urls<<EOF"
284+ echo "${wheel_urls}"
285+ echo "EOF"
286+ } >> "$GITHUB_OUTPUT"
287+
288+ kitmaker :
289+ runs-on : [self-hosted, linux]
290+ needs :
291+ - publish-github-release-assets
292+ environment : release
293+ permissions :
294+ contents : read
295+ if : ${{ needs.publish-github-release-assets.result == 'success' }}
296+
297+ steps :
298+ - name : Submit wheel release to Kitmaker
299+ env :
300+ KITMAKER_PROJECT_ID : ${{ secrets.KITMAKER_PROJECT_ID }}
301+ KITMAKER_TOKEN : ${{ secrets.KITMAKER_TOKEN }}
302+ KITMAKER_PIC_EMAIL : ${{ secrets.KITMAKER_PIC_EMAIL }}
303+ WHEEL_URLS : ${{ needs.publish-github-release-assets.outputs.wheel_urls }}
304+ run : |
305+ set -euo pipefail
306+
307+ if [[ -z "${KITMAKER_TOKEN}" || -z "${KITMAKER_PIC_EMAIL}" ]]; then
308+ echo "Missing one or more required secrets: KITMAKER_TOKEN, KITMAKER_PIC_EMAIL"
263309 exit 1
264310 fi
265311
266- shopt -s nullglob
267- wheels=(wheels/*.whl)
268- if (( ${#wheels[@]} == 0 )); then
269- echo "No wheels found under wheels/*.whl"
270- ls -la wheels || true
312+ if [[ -z "${WHEEL_URLS}" ]]; then
313+ echo "No wheel URLs were produced by publish-github-release-assets job"
271314 exit 1
272315 fi
273316
274317 api_url="https://kitmaker-portal.nvidia.com/api/v0/projects/${KITMAKER_PROJECT_ID}/releases"
275- wheel_url_base="https://${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}@${ARTIFACTORY_DOMAIN}/artifactory/${ARTIFACTORY_REPO}/isaacteleop"
276-
277- for wheel_path in "${wheels[@]}"; do
278- wheel_name="$(basename "${wheel_path}")"
279- if [[ "${wheel_name}" =~ ^isaacteleop-([^-]+)- ]]; then
280- wheel_version="${BASH_REMATCH[1]}"
281- else
282- echo "Unable to parse version from wheel filename: ${wheel_name}"
283- exit 1
284- fi
285-
286- wheel_url="${wheel_url_base}/${wheel_version}/${wheel_name}"
318+ payload_items=()
319+ while IFS= read -r wheel_url; do
320+ [[ -z "${wheel_url}" ]] && continue
321+ wheel_name="$(basename "${wheel_url}")"
322+ echo "Queueing wheel for Kitmaker payload: ${wheel_name}"
323+
324+ payload_items+=("$(jq -cn \
325+ --arg pic "${KITMAKER_PIC_EMAIL}" \
326+ --arg url "${wheel_url}" \
327+ '{pic: $pic, job_type: "wheel-release-job", publish_to: "both_devzone_pypi", url: $url, size: "small", upload: false}')")
328+ done <<< "${WHEEL_URLS}"
329+
330+ if (( ${#payload_items[@]} == 0 )); then
331+ echo "No valid wheel URLs found to submit to Kitmaker"
332+ exit 1
333+ fi
287334
288- payload=$(cat <<EOF
289- {
290- "project_name": "isaacteleop",
291- "payload": [
292- {
293- "pic": "${KITMAKER_PIC_EMAIL}",
294- "job_type": "wheel-release-job",
295- "publish_to": "both_devzone_pypi",
296- "url": "${wheel_url}",
297- "size": "small",
298- "upload": false
299- }
300- ]
301- }
302- EOF
303- )
304-
305- echo "Posting wheel to Kitmaker: ${wheel_name}"
306- curl --fail-with-body --show-error --silent --location --include \
307- -X POST "${api_url}" \
308- -H "Authorization: Bearer ${KITMAKER_TOKEN}" \
309- -H "Content-Type: application/json" \
310- -d "${payload}"
311- echo
312- done
335+ payload_array="$(printf '%s\n' "${payload_items[@]}" | jq -s '.')"
336+ payload="$(jq -cn --arg project_name "isaacteleop" --argjson payload "${payload_array}" '{project_name: $project_name, payload: $payload}')"
337+
338+ echo "Posting ${#payload_items[@]} wheel(s) to Kitmaker in a single request"
339+ curl --fail-with-body --show-error --silent --location --include \
340+ -X POST "${api_url}" \
341+ -H "Authorization: Bearer ${KITMAKER_TOKEN}" \
342+ -H "Content-Type: application/json" \
343+ -d "${payload}"
344+ echo
345+ echo "Waiting 60 seconds to allow Kitmaker to start downloading wheel payload"
346+ sleep 60
0 commit comments