Skip to content

Commit e8d1aec

Browse files
committed
Add composite actions to eliminate workflow duplication
Created 5 reusable composite actions in .github/actions/: 1. preflight-checks: Validates environment variables and system resources - Configurable checks for PULL_SECRET, system resources, libvirt - Eliminates ~50 lines duplicated across 4 workflows 2. setup-cluster-name: Generates unique cluster names - Supports hash-based (e2e/infra) and date-based (nightly) naming - Eliminates duplicate naming logic across 4 workflows 3. notify-slack: Sends workflow status notifications - Templated success/failure messages - Eliminates ~100 lines duplicated in 2 nightly workflows 4. setup-infrastructure: Creates and configures infrastructure - Runs make environment → provision-landing-zone → install-enclave - Configurable step skipping - Eliminates repeated infrastructure setup patterns 5. collect-artifacts: Collects CI artifacts for troubleshooting - Runs collection script and appends summary - Eliminates duplicate artifact collection logic These actions will be used in the next commit to refactor all workflows.
1 parent 9910f45 commit e8d1aec

5 files changed

Lines changed: 318 additions & 0 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Collect Artifacts
2+
description: Collects CI artifacts (logs, configs, diagnostics) for troubleshooting
3+
4+
inputs:
5+
artifact-type:
6+
description: 'Type of artifacts to collect (deployment, infrastructure, etc.)'
7+
required: false
8+
default: 'deployment'
9+
output-directory:
10+
description: 'Directory to store collected artifacts'
11+
required: false
12+
default: 'artifacts'
13+
14+
runs:
15+
using: composite
16+
steps:
17+
- name: Collect artifacts
18+
shell: bash
19+
run: |
20+
echo "## Collecting Artifacts" >> $GITHUB_STEP_SUMMARY
21+
echo "" >> $GITHUB_STEP_SUMMARY
22+
23+
# Run artifact collection script
24+
./scripts/collect_ci_artifacts.sh ${{ inputs.artifact-type }} ${{ inputs.output-directory }} 2>&1 | tee artifact-collection.log
25+
26+
# Add summary if available
27+
if [ -f ${{ inputs.output-directory }}/collection-summary.txt ]; then
28+
echo "" >> $GITHUB_STEP_SUMMARY
29+
cat ${{ inputs.output-directory }}/collection-summary.txt >> $GITHUB_STEP_SUMMARY
30+
fi
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Notify Slack
2+
description: Sends workflow status notifications to Slack
3+
4+
inputs:
5+
status:
6+
description: 'Workflow status: success or failure'
7+
required: true
8+
workflow-name:
9+
description: 'Workflow display name (e.g., "Nightly E2E - Connected")'
10+
required: true
11+
cluster-name:
12+
description: 'Cluster name'
13+
required: true
14+
slack-webhook-urls:
15+
description: 'Space-separated list of Slack webhook URLs'
16+
required: true
17+
workflow-url:
18+
description: 'GitHub workflow run URL'
19+
required: true
20+
branch-name:
21+
description: 'Git branch name'
22+
required: true
23+
24+
runs:
25+
using: composite
26+
steps:
27+
- name: Send Slack notification
28+
shell: bash
29+
run: |
30+
if [ "${{ inputs.status }}" = "success" ]; then
31+
ICON=":green_jenkins_circle:"
32+
STATUS_TEXT="PASSED"
33+
COLOR="#36a64f"
34+
else
35+
ICON=":red_jenkins_circle:"
36+
STATUS_TEXT="FAILED"
37+
COLOR="#ff0000"
38+
fi
39+
40+
PAYLOAD=$(cat <<EOF
41+
{
42+
"text": "${ICON} ${{ inputs.workflow-name }} ${STATUS_TEXT}",
43+
"attachments": [
44+
{
45+
"color": "${COLOR}",
46+
"blocks": [
47+
{
48+
"type": "header",
49+
"text": {
50+
"type": "plain_text",
51+
"text": "${ICON} ${{ inputs.workflow-name }} - ${STATUS_TEXT}",
52+
"emoji": true
53+
}
54+
},
55+
{
56+
"type": "section",
57+
"fields": [
58+
{
59+
"type": "mrkdwn",
60+
"text": "*Cluster:*\n${{ inputs.cluster-name }}"
61+
},
62+
{
63+
"type": "mrkdwn",
64+
"text": "*Branch:*\n${{ inputs.branch-name }}"
65+
},
66+
{
67+
"type": "mrkdwn",
68+
"text": "*Workflow:*\n<${{ inputs.workflow-url }}|View Run>"
69+
},
70+
{
71+
"type": "mrkdwn",
72+
"text": "*Status:*\n${STATUS_TEXT}"
73+
}
74+
]
75+
}
76+
]
77+
}
78+
]
79+
}
80+
EOF
81+
)
82+
83+
# Send to all webhook URLs
84+
for WEBHOOK_URL in ${{ inputs.slack-webhook-urls }}; do
85+
echo "Sending notification to Slack..."
86+
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$WEBHOOK_URL"
87+
done
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Preflight Checks
2+
description: Validates environment variables and system resources before workflow execution
3+
4+
inputs:
5+
title:
6+
description: 'Title for the preflight checks section'
7+
required: false
8+
default: 'Pre-flight Checks'
9+
check-pull-secret:
10+
description: 'Whether to check PULL_SECRET variable'
11+
required: false
12+
default: 'false'
13+
check-system-resources:
14+
description: 'Whether to check system resources (RAM, disk)'
15+
required: false
16+
default: 'false'
17+
check-libvirt:
18+
description: 'Whether to check libvirt access'
19+
required: false
20+
default: 'false'
21+
deployment-mode:
22+
description: 'Deployment mode to display (optional)'
23+
required: false
24+
default: ''
25+
26+
runs:
27+
using: composite
28+
steps:
29+
- name: Run preflight checks
30+
shell: bash {0}
31+
run: |
32+
set +e # Don't exit on first error, collect all failures
33+
FAILED=0
34+
35+
echo "## ${{ inputs.title }}" | tee -a $GITHUB_STEP_SUMMARY
36+
echo "" | tee -a $GITHUB_STEP_SUMMARY
37+
38+
# Check required environment variables
39+
echo "### Environment Variables" | tee -a $GITHUB_STEP_SUMMARY
40+
41+
if [ -z "$DEV_SCRIPTS_PATH" ]; then
42+
echo "❌ DEV_SCRIPTS_PATH not set" | tee -a $GITHUB_STEP_SUMMARY
43+
FAILED=1
44+
else
45+
echo "✅ DEV_SCRIPTS_PATH: $DEV_SCRIPTS_PATH" | tee -a $GITHUB_STEP_SUMMARY
46+
fi
47+
48+
if [ -z "$WORKING_DIR" ]; then
49+
echo "❌ WORKING_DIR not set" | tee -a $GITHUB_STEP_SUMMARY
50+
FAILED=1
51+
else
52+
echo "✅ WORKING_DIR: $WORKING_DIR" | tee -a $GITHUB_STEP_SUMMARY
53+
fi
54+
55+
if [ "${{ inputs.check-pull-secret }}" = "true" ]; then
56+
if [ -z "$PULL_SECRET" ]; then
57+
echo "❌ PULL_SECRET not set" | tee -a $GITHUB_STEP_SUMMARY
58+
FAILED=1
59+
else
60+
echo "✅ PULL_SECRET: configured" | tee -a $GITHUB_STEP_SUMMARY
61+
fi
62+
fi
63+
64+
if [ -n "${{ inputs.deployment-mode }}" ]; then
65+
echo "✅ Deployment mode: ${{ inputs.deployment-mode }}" | tee -a $GITHUB_STEP_SUMMARY
66+
fi
67+
68+
# Check system resources if requested
69+
if [ "${{ inputs.check-system-resources }}" = "true" ]; then
70+
echo "" | tee -a $GITHUB_STEP_SUMMARY
71+
echo "### System Resources" | tee -a $GITHUB_STEP_SUMMARY
72+
TOTAL_RAM=$(free -g | awk '/^Mem:/{print $2}')
73+
echo "✅ Total RAM: ${TOTAL_RAM}GB" | tee -a $GITHUB_STEP_SUMMARY
74+
75+
if [ -n "$WORKING_DIR" ]; then
76+
AVAILABLE_DISK=$(df -h $WORKING_DIR 2>/dev/null | awk 'NR==2{print $4}')
77+
if [ -n "$AVAILABLE_DISK" ]; then
78+
echo "✅ Available disk space: $AVAILABLE_DISK" | tee -a $GITHUB_STEP_SUMMARY
79+
fi
80+
fi
81+
fi
82+
83+
# Check libvirt access if requested
84+
if [ "${{ inputs.check-libvirt }}" = "true" ]; then
85+
echo "" | tee -a $GITHUB_STEP_SUMMARY
86+
echo "### Libvirt Access" | tee -a $GITHUB_STEP_SUMMARY
87+
if sudo virsh list --all > /dev/null 2>&1; then
88+
echo "✅ Libvirt access verified" | tee -a $GITHUB_STEP_SUMMARY
89+
else
90+
echo "❌ Cannot access libvirt" | tee -a $GITHUB_STEP_SUMMARY
91+
FAILED=1
92+
fi
93+
fi
94+
95+
# Final status
96+
if [ $FAILED -eq 0 ]; then
97+
echo "" | tee -a $GITHUB_STEP_SUMMARY
98+
echo "✅ All pre-flight checks passed" | tee -a $GITHUB_STEP_SUMMARY
99+
else
100+
echo "" | tee -a $GITHUB_STEP_SUMMARY
101+
echo "❌ Pre-flight checks failed" | tee -a $GITHUB_STEP_SUMMARY
102+
echo "" | tee -a $GITHUB_STEP_SUMMARY
103+
echo "**Action Required**: Configure repository variables and secrets in Settings → Secrets and variables → Actions" | tee -a $GITHUB_STEP_SUMMARY
104+
exit 1
105+
fi
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Setup Cluster Name
2+
description: Generates a unique cluster name for the deployment
3+
4+
inputs:
5+
naming-strategy:
6+
description: 'Naming strategy: "hash" (e2e/infra) or "date" (nightly)'
7+
required: true
8+
prefix:
9+
description: 'Cluster name prefix (eci for e2e/infra, nc/nd for nightly)'
10+
required: true
11+
run-id:
12+
description: 'GitHub run ID for hash-based naming'
13+
required: false
14+
default: ''
15+
16+
outputs:
17+
cluster-name:
18+
description: 'Generated cluster name'
19+
value: ${{ steps.generate.outputs.cluster-name }}
20+
21+
runs:
22+
using: composite
23+
steps:
24+
- name: Generate cluster name
25+
id: generate
26+
shell: bash
27+
run: |
28+
if [ "${{ inputs.naming-strategy }}" = "hash" ]; then
29+
# Hash-based naming for e2e/infra runs
30+
# Cluster name: prefix-XXXXXXXX (e.g., eci-a1b2c3d4)
31+
SHORT_ID=$(echo "${{ inputs.run-id }}" | sha256sum | cut -c1-8)
32+
CLUSTER_NAME="${{ inputs.prefix }}-${SHORT_ID}"
33+
echo "Generated cluster name: ${CLUSTER_NAME}"
34+
elif [ "${{ inputs.naming-strategy }}" = "date" ]; then
35+
# Date-based naming for nightly runs
36+
# Cluster name: prefix-YYYYMMDD (e.g., nc-20260303)
37+
DATE_STAMP=$(date +%Y%m%d)
38+
CLUSTER_NAME="${{ inputs.prefix }}-${DATE_STAMP}"
39+
echo "Generated cluster name: ${CLUSTER_NAME} (nightly)"
40+
else
41+
echo "ERROR: Invalid naming-strategy: ${{ inputs.naming-strategy }}"
42+
exit 1
43+
fi
44+
45+
# Set as output and environment variable
46+
echo "cluster-name=${CLUSTER_NAME}" >> $GITHUB_OUTPUT
47+
echo "ENCLAVE_CLUSTER_NAME=${CLUSTER_NAME}" >> $GITHUB_ENV
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Setup Infrastructure
2+
description: Creates and configures infrastructure (VMs, networks, Landing Zone, Enclave)
3+
4+
inputs:
5+
skip-environment:
6+
description: 'Skip make environment step'
7+
required: false
8+
default: 'false'
9+
skip-provision-lz:
10+
description: 'Skip make provision-landing-zone step'
11+
required: false
12+
default: 'false'
13+
skip-install-enclave:
14+
description: 'Skip make install-enclave step'
15+
required: false
16+
default: 'false'
17+
18+
runs:
19+
using: composite
20+
steps:
21+
- name: Create infrastructure
22+
if: inputs.skip-environment != 'true'
23+
shell: bash
24+
run: |
25+
echo "## Creating Infrastructure" >> $GITHUB_STEP_SUMMARY
26+
echo "" >> $GITHUB_STEP_SUMMARY
27+
echo "Creating VMs, networks, and BMC emulation..." >> $GITHUB_STEP_SUMMARY
28+
make environment
29+
echo "✅ Infrastructure created" >> $GITHUB_STEP_SUMMARY
30+
31+
- name: Provision Landing Zone
32+
if: inputs.skip-provision-lz != 'true'
33+
shell: bash
34+
run: |
35+
echo "## Provisioning Landing Zone" >> $GITHUB_STEP_SUMMARY
36+
echo "" >> $GITHUB_STEP_SUMMARY
37+
echo "Installing CentOS Stream and configuring Landing Zone VM..." >> $GITHUB_STEP_SUMMARY
38+
make provision-landing-zone
39+
echo "✅ Landing Zone provisioned" >> $GITHUB_STEP_SUMMARY
40+
41+
- name: Install Enclave Lab
42+
if: inputs.skip-install-enclave != 'true'
43+
shell: bash
44+
run: |
45+
echo "## Installing Enclave Lab" >> $GITHUB_STEP_SUMMARY
46+
echo "" >> $GITHUB_STEP_SUMMARY
47+
echo "Installing dev-scripts and required packages on Landing Zone..." >> $GITHUB_STEP_SUMMARY
48+
make install-enclave
49+
echo "✅ Enclave Lab installed" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)