-
Notifications
You must be signed in to change notification settings - Fork 1
ci: edge-cluster-trigger workflow (GH→ADO smoke test) #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| # Trigger a SovereignSOC ADO edge-cluster lifecycle run. | ||
| # Smoke test for the GH→ADO trigger path. Once stable, this can be folded | ||
| # into component-tests.yaml as a pre-step that resets the target cluster | ||
| # before component tests run against it. | ||
| # | ||
| # Setup contract (k8sstormcenter/actions repo + SovereignSOC docs): | ||
| # secrets.ADO_PAT — PAT with Build:Read & Execute | ||
| # vars.ADO_ORG — AustrianDataLab | ||
| # vars.ADO_PROJECT — SovereignSOC | ||
| # vars.ADO_PIPELINE_EDGE — pipeline definition ID for edge-cluster.yml | ||
| name: edge-cluster-trigger | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| cluster: | ||
| description: 'Edge cluster slot' | ||
| required: true | ||
| default: 'edge4' | ||
| type: choice | ||
| options: | ||
| - edge4 | ||
| - k3s-1 | ||
| - k3s-2 | ||
| - rocky-1 | ||
| action: | ||
| description: 'Lifecycle action' | ||
| required: true | ||
| default: 'plan' | ||
| type: choice | ||
| options: | ||
| - plan | ||
| - create | ||
| - delete | ||
| - reset | ||
| os: | ||
| description: 'Base OS' | ||
| required: true | ||
| default: 'ubuntu' | ||
| type: choice | ||
| options: | ||
| - ubuntu | ||
| - rocky | ||
| wait: | ||
| description: 'Wait for ADO run to complete' | ||
| required: true | ||
| default: 'true' | ||
| type: boolean | ||
|
|
||
| jobs: | ||
| trigger: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Guard — config sanity | ||
| env: | ||
| ADO_PAT: ${{ secrets.ADO_PAT }} | ||
| ADO_ORG: ${{ vars.ADO_ORG }} | ||
| ADO_PROJECT: ${{ vars.ADO_PROJECT }} | ||
| ADO_PIPELINE_EDGE: ${{ vars.ADO_PIPELINE_EDGE }} | ||
| run: | | ||
| missing=() | ||
| [[ -n "$ADO_PAT" ]] || missing+=("secrets.ADO_PAT") | ||
| [[ -n "$ADO_ORG" ]] || missing+=("vars.ADO_ORG") | ||
| [[ -n "$ADO_PROJECT" ]] || missing+=("vars.ADO_PROJECT") | ||
| [[ -n "$ADO_PIPELINE_EDGE" ]] || missing+=("vars.ADO_PIPELINE_EDGE") | ||
| if [[ ${#missing[@]} -gt 0 ]]; then | ||
| echo "::error::Missing required config: ${missing[*]}" | ||
| echo "Set them per docs at k8sstormcenter/actions/trigger-ado-pipeline/README.md" | ||
| exit 1 | ||
| fi | ||
| echo "✔ All required config present" | ||
|
|
||
| - id: ado | ||
| uses: k8sstormcenter/actions/trigger-ado-pipeline@main | ||
| with: | ||
| org: ${{ vars.ADO_ORG }} | ||
| project: ${{ vars.ADO_PROJECT }} | ||
| pipeline_id: ${{ vars.ADO_PIPELINE_EDGE }} | ||
| pat: ${{ secrets.ADO_PAT }} | ||
| cluster: ${{ inputs.cluster }} | ||
| action: ${{ inputs.action }} | ||
| os: ${{ inputs.os }} | ||
| wait: ${{ inputs.wait }} | ||
| timeout: '1800' | ||
|
Comment on lines
+73
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get the latest commit hash for the action to pin to
gh api repos/k8sstormcenter/actions/commits/main \
--jq '.sha' \
| head -c 7Repository: k8sstormcenter/node-agent Length of output: 76 🏁 Script executed: #!/bin/bash
set -euo pipefail
# 1) Show the exact workflow lines around the ADO trigger step
echo "---- Workflow snippet ----"
nl -ba .github/workflows/edge-cluster-trigger.yml | sed -n '60,95p'
# 2) Get full SHA for k8sstormcenter/actions@main
echo "---- GitHub: full SHA for repos/k8sstormcenter/actions@main ----"
FULL_SHA="$(gh api repos/k8sstormcenter/actions/commits/main --jq '.sha')"
echo "$FULL_SHA"
# 3) Verify that trigger-ado-pipeline path exists in that repo at that ref
# (GitHub Actions expects an action.yml/metadata inside the directory for the path portion.)
echo "---- GitHub: check contents/trigger-ado-pipeline exists at ref ----"
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline?ref=$FULL_SHA" --jq '.[].path' || \
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline?ref=$FULL_SHA" --jq '.path'Repository: k8sstormcenter/node-agent Length of output: 157 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "---- Workflow snippet (lines 65-95) ----"
awk 'NR>=65 && NR<=95 {printf "%d:%s\n", NR, $0}' .github/workflows/edge-cluster-trigger.yml
echo "---- GitHub: full SHA for repos/k8sstormcenter/actions@main ----"
FULL_SHA="$(gh api repos/k8sstormcenter/actions/commits/main --jq '.sha')"
SHORT_SHA="$(echo "$FULL_SHA" | head -c 7)"
echo "FULL_SHA=$FULL_SHA"
echo "SHORT_SHA=$SHORT_SHA"
echo "---- GitHub: check trigger-ado-pipeline directory exists at that ref ----"
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline?ref=$FULL_SHA" --jq '{path, type, name}' || true
echo "---- GitHub: check action entry files exist at that ref ----"
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline/action.yml?ref=$FULL_SHA" --jq '.path' || true
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline/action.yaml?ref=$FULL_SHA" --jq '.path' || true
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline/metadata.json?ref=$FULL_SHA" --jq '.path' || trueRepository: k8sstormcenter/node-agent Length of output: 2318 🏁 Script executed: #!/bin/bash
set -euo pipefail
FULL_SHA="$(gh api repos/k8sstormcenter/actions/commits/main --jq '.sha')"
echo "FULL_SHA=$FULL_SHA"
echo "---- Find any paths containing 'trigger-ado' in that ref ----"
gh api "repos/k8sstormcenter/actions/git/trees/$FULL_SHA?recursive=1" --jq '
.tree[]
| select(.path | test("trigger-ado"; "i"))
| {path, type}
' | head -n 50
echo "---- Find exact 'trigger-ado-pipeline' matches ----"
gh api "repos/k8sstormcenter/actions/git/trees/$FULL_SHA?recursive=1" --jq '
.tree[]
| select(.path == "trigger-ado-pipeline" or .path | test("trigger-ado-pipeline"; "i"))
| {path, type}
' | head -n 50Repository: k8sstormcenter/node-agent Length of output: 180 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "---- contents: trigger-ado-pipeline at ref=main ----"
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline?ref=main" --jq '
if type=="array" then map({name, path, type}) else {path, type} end
' || true
echo "---- contents: trigger-ado-pipeline at ref=SHORT_SHA=27790fc (if needed) ----"
gh api "repos/k8sstormcenter/actions/contents/trigger-ado-pipeline?ref=27790fc" --jq '
if type=="array" then map({name, path, type}) else {path, type} end
' || trueRepository: k8sstormcenter/node-agent Length of output: 508 Pin
🧰 Tools🪛 zizmor (1.25.2)[error] 74-74: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI Agents |
||
|
|
||
| - name: Summary | ||
| if: always() | ||
| run: | | ||
| echo "### ADO run" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- cluster: \`${{ inputs.cluster }}\`" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- action: \`${{ inputs.action }}\`" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- run id: ${{ steps.ado.outputs.run_id }}" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- url: ${{ steps.ado.outputs.run_url }}" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- result: ${{ steps.ado.outputs.result }}" >> "$GITHUB_STEP_SUMMARY" | ||
|
Comment on lines
+86
to
+95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mitigate potential code injection via step outputs. Lines 93-95 expand step outputs directly in the shell script. While the outputs come from a trusted internal action, if they contain shell metacharacters (backticks, 🛡️ Proposed fix using environment variables - name: Summary
if: always()
+ env:
+ RUN_ID: ${{ steps.ado.outputs.run_id }}
+ RUN_URL: ${{ steps.ado.outputs.run_url }}
+ RESULT: ${{ steps.ado.outputs.result }}
run: |
echo "### ADO run" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "- cluster: \`${{ inputs.cluster }}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- action: \`${{ inputs.action }}\`" >> "$GITHUB_STEP_SUMMARY"
- echo "- run id: ${{ steps.ado.outputs.run_id }}" >> "$GITHUB_STEP_SUMMARY"
- echo "- url: ${{ steps.ado.outputs.run_url }}" >> "$GITHUB_STEP_SUMMARY"
- echo "- result: ${{ steps.ado.outputs.result }}" >> "$GITHUB_STEP_SUMMARY"
+ echo "- run id: $RUN_ID" >> "$GITHUB_STEP_SUMMARY"
+ echo "- url: $RUN_URL" >> "$GITHUB_STEP_SUMMARY"
+ echo "- result: $RESULT" >> "$GITHUB_STEP_SUMMARY"🧰 Tools🪛 zizmor (1.25.2)[warning] 91-91: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [warning] 92-92: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 93-93: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 94-94: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 95-95: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Consider adding concurrency control keyed on cluster input.
The workflow allows parallel manual triggers. If multiple users trigger lifecycle operations (especially
reset,create, ordelete) on the same cluster simultaneously, they could interfere with each other.♻️ Proposed addition of concurrency group
Add this block after the
on:section and beforejobs::wait: description: 'Wait for ADO run to complete' required: true default: 'true' type: boolean +concurrency: + group: edge-cluster-${{ inputs.cluster }} + cancel-in-progress: false + jobs: trigger:This allows parallel operations on different clusters while serializing operations on the same cluster. Set
cancel-in-progress: trueif you prefer newer runs to cancel pending ones.📝 Committable suggestion
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 13-48: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents