test: TA testing pipeline to build add-ons with custom UCC #1989
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: TAs Regression Test | |
on: | |
push: | |
branches: | |
- develop | |
- main | |
pull_request: | |
branches: | |
- "**" | |
workflow_dispatch: | |
inputs: | |
target_repo: | |
description: "TA repository (leave empty to test all TAs)" | |
required: false | |
default: "" | |
target_branch: | |
description: "TA repository branch" | |
required: false | |
default: "main" | |
splunktaucclib_branch: | |
description: "Branch of splunk/addonfactory-ucc-library to use (leave empty to use latest from PyPI)" | |
required: false | |
default: "" | |
run_pipelines: | |
description: "Trigger TA pipelines (true/false)" | |
required: false | |
default: "false" | |
jobs: | |
build-ucc: | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Checkout UCC Framework Repository | |
uses: actions/checkout@v4 | |
with: | |
path: UCC | |
- name: Set up Python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.7" | |
- name: Install Poetry 1.5.1 | |
run: curl -sSL https://install.python-poetry.org | python3 - --version 1.5.1 | |
- name: Install Poetry Dependencies | |
working-directory: UCC | |
run: poetry install | |
- name: Build UCC Framework Package | |
working-directory: UCC | |
run: poetry build | |
- name: Upload UCC Artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ucc-package-whl | |
path: UCC/dist/*.whl | |
determine-repos: | |
# This job determines the repositories to run tests on based on the event type and inputs | |
runs-on: ubuntu-22.04 | |
outputs: | |
repos: ${{ steps.set-repos.outputs.repos }} | |
steps: | |
- id: set-repos | |
run: | | |
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ github.event.inputs.target_repo }}" ]]; then | |
echo "repos=[\"${{ github.event.inputs.target_repo }}\"]" >> $GITHUB_OUTPUT | |
else | |
echo "repos<<EOF" >> $GITHUB_OUTPUT | |
echo '[ | |
"splunk/splunk-add-on-for-amazon-web-services", | |
"splunk/splunk-add-on-for-google-cloud-platform", | |
"splunk/splunk-add-on-for-google-workspace", | |
"splunk/splunk-add-on-for-microsoft-cloud-services", | |
"splunk/splunk-add-on-for-microsoft-office-365", | |
"splunk/splunk-add-on-for-salesforce", | |
"splunk/splunk-add-on-for-servicenow", | |
"splunk/splunk-add-on-for-mysql", | |
"splunk/splunk-add-on-for-cisco-asa", | |
"splunk/splunk-add-on-for-unix-and-linux" | |
]' >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
fi | |
test-addons: | |
needs: [ build-ucc, determine-repos ] | |
strategy: | |
matrix: | |
target_repo: ${{ fromJSON(needs.determine-repos.outputs.repos) }} | |
continue-on-error: true | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Checkout Target Add-on Repository | |
uses: actions/checkout@v4 | |
with: | |
repository: ${{ matrix.target_repo }} | |
path: TA | |
token: ${{ secrets.GH_TOKEN_ADMIN }} | |
ref: ${{ github.event.inputs.target_branch }} | |
- name: Set up Python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.9" | |
- name: Install Poetry 2.1.4 | |
run: | | |
curl -sSL https://install.python-poetry.org | python3 - --version 2.1.4 | |
python3 -m pip install poetry-plugin-export==1.9.0 | |
- name: Download UCC Artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: ucc-package-whl | |
path: UCC | |
- name: Importing GPG key | |
if: success() && github.event.inputs.run_pipelines == 'true' | |
uses: crazy-max/ghaction-import-gpg@v6 | |
with: | |
git_committer_name: ${{ secrets.SA_GH_USER_NAME }} | |
git_committer_email: ${{ secrets.SA_GH_USER_EMAIL }} | |
gpg_private_key: ${{ secrets.SA_GPG_PRIVATE_KEY }} | |
passphrase: ${{ secrets.SA_GPG_PASSPHRASE }} | |
git_user_signingkey: true | |
git_commit_gpgsign: true | |
workdir: TA | |
- name: Prepare the Target Add-on | |
id: prepare | |
working-directory: TA | |
run: | | |
set -x | |
# https://github.com/python-poetry/poetry/issues/7491#issuecomment-1423763839 | |
git config --global --add url."https://${{ secrets.GH_TOKEN_ADMIN }}@github.com".insteadOf https://github.com | |
git config --global --add url."https://${{ secrets.GH_TOKEN_ADMIN }}@github.com".insteadOf ssh://[email protected] | |
# Use the special branch | |
if [[ "${{ github.event.inputs.run_pipelines }}" == "true" ]]; then | |
GIT_BRANCH="ucc/ci_tests_trigger_pipeline" | |
git fetch origin | |
if git ls-remote --exit-code --heads origin "$GIT_BRANCH"; then | |
echo "Branch $GIT_BRANCH already exists, checking it out" | |
git checkout "$GIT_BRANCH" | |
git reset --hard "origin/${{ github.event.inputs.target_branch }}" # Reset to main branch | |
git rebase ${{ github.event.inputs.target_branch }} $GIT_BRANCH # Rebase the branch onto main | |
echo "branch-created=false" >> "$GITHUB_OUTPUT" | |
else | |
echo "Branch $GIT_BRANCH does not exist, creating it" | |
git checkout -b "$GIT_BRANCH" "origin/${{ github.event.inputs.target_branch }}" | |
echo "branch-created=true" >> "$GITHUB_OUTPUT" | |
fi | |
echo "GIT_BRANCH=$GIT_BRANCH" >> "$GITHUB_ENV" | |
fi | |
rm splunk_add_on_ucc_framework-*.whl || true | |
cp ../UCC/*.whl ./ | |
UCC_WHL=$(ls *.whl) | |
echo "UCC_WHL=$UCC_WHL" >> "$GITHUB_ENV" | |
echo "Adding UCC package $UCC_WHL" | |
poetry remove splunk_add_on_ucc_framework | |
echo "./$UCC_WHL" > requirements_ucc.txt | |
# Adding "package-mode = false" to pyproject.toml if not present | |
if ! grep -q "package-mode = false" pyproject.toml; then | |
echo "Adding 'package-mode = false' to pyproject.toml" | |
sed -i '/name = .*/ s:$:\npackage-mode = false:' pyproject.toml | |
fi | |
# Install splunktaucclib with retries | |
MAX_RETRIES=3 | |
RETRY_COUNT=0 | |
until [ $RETRY_COUNT -ge $MAX_RETRIES ] | |
do | |
if [[ -n "${{ github.event.inputs.splunktaucclib_branch }}" ]]; then | |
echo "Installing splunktaucclib from branch ${{ github.event.inputs.splunktaucclib_branch }}" | |
poetry add git+https://github.com/splunk/addonfactory-ucc-library.git@${{ github.event.inputs.splunktaucclib_branch }} && break | |
else | |
echo "Installing latest splunktaucclib from PyPI" | |
poetry add splunktaucclib@latest && break | |
fi | |
RETRY_COUNT=$((RETRY_COUNT+1)) | |
if [[ $RETRY_COUNT -eq $MAX_RETRIES ]]; then | |
echo "splunktaucclib install failed after $MAX_RETRIES attempts, exiting" | |
exit 1 | |
fi | |
echo "splunktaucclib install failed, retry attempt $RETRY_COUNT of $MAX_RETRIES" | |
sleep 5 | |
done | |
mkdir -p package/lib | |
poetry export --without-hashes -o package/lib/requirements.txt | |
# Add to commit | |
if [[ "${{ github.event.inputs.run_pipelines }}" == "true" ]]; then | |
echo "Adding UCC, requirements_ucc.txt, pyproject.toml and poetry.lock to commit" | |
git add pyproject.toml requirements_ucc.txt poetry.lock *.whl | |
fi | |
- name: Run ucc-gen build in Target Add-on | |
working-directory: TA | |
run: | | |
set -x | |
python3 -m venv .ucc_venv | |
./.ucc_venv/bin/python3 -m pip install ./$UCC_WHL | |
./.ucc_venv/bin/ucc-gen build 2>&1 | tee build_output.log | |
if tail -n 1 build_output.log | grep -q "^INFO: File creation summary: created: "; then | |
echo "✓ Build completed successfully with expected output" | |
cat build_output.log | |
else | |
echo "✗ Build did not complete with expected output" | |
echo "Last line of output should start with 'INFO: File creation summary: created: '" | |
echo "Full output:" | |
cat build_output.log | |
exit 1 | |
fi | |
- name: Upgrade the release pipeline in Github Actions | |
if: success() && github.event.inputs.run_pipelines == 'true' | |
working-directory: TA | |
run: | | |
set -x | |
VERSION="$(cat .github/workflows/build-test-release.yml | grep reusable-build-test-release.yml | cut -d '@' -f 2)" | |
# Version is in format e.g. "v1.2.3". We need at least "v5.1.0" | |
MAJOR_VERSION="$(echo $VERSION | cut -d '.' -f 1 | sed 's/^v//')" | |
MINOR_VERSION="$(echo $VERSION | cut -d '.' -f 2)" | |
# If major and minor are not integers, exit | |
if ! [[ "$MAJOR_VERSION" =~ ^[0-9]+$ ]] || ! [[ "$MINOR_VERSION" =~ ^[0-9]+$ ]]; then | |
echo "✗ The reusable workflow version $VERSION is not in the expected format. No update performed." | |
exit 0 | |
fi | |
if (( MAJOR_VERSION < 5 )) || { (( MAJOR_VERSION == 5 )) && (( MINOR_VERSION < 1 )); }; then | |
echo "✗ The reusable workflow version $VERSION is too old. Upgrading to v5.1.0" | |
sed -i 's/reusable-build-test-release.yml@.*/[email protected]/' .github/workflows/build-test-release.yml | |
git add .github/workflows/build-test-release.yml | |
echo "Upgraded the reusable workflow version to v5.1.0" | |
else | |
echo "✓ The reusable workflow version $VERSION is up to date" | |
fi | |
- name: Push changes to a temporary branch in order to trigger the pipeline | |
if: success() && github.event.inputs.run_pipelines == 'true' | |
working-directory: TA | |
run: | | |
git config --global user.name "${{ secrets.SA_GH_USER_NAME }}" | |
git config --global user.email "${{ secrets.SA_GH_USER_EMAIL }}" | |
git commit -S -m "CI: UCC build for ${{ github.event_name }} event" | |
git push --force origin $GIT_BRANCH | |
- name: Obtain the workflow run ID | |
if: success() && github.event.inputs.run_pipelines == 'true' | |
id: get-workflow-run-id | |
env: | |
GH_TOKEN: ${{ secrets.GH_TOKEN_ADMIN }} | |
run: | | |
for i in {1..30}; do | |
echo "Attempt $i to get workflow run ID" | |
WORKFLOW_RUN_ID=$(gh run -R ${{ matrix.target_repo }} list -b ucc/ci_tests_trigger_pipeline \ | |
--json databaseId --limit 1 --status in_progress --workflow build-test-release \ | |
-q '.[0].databaseId | select( . != null )') | |
if [[ -n "$WORKFLOW_RUN_ID" ]]; then | |
echo "Found workflow run ID: $WORKFLOW_RUN_ID" | |
break | |
fi | |
echo "Workflow run ID not found, retrying in 2 seconds..." | |
sleep 2 | |
done | |
echo "WORKFLOW_RUN_ID=$WORKFLOW_RUN_ID" >> $GITHUB_ENV | |
echo "workflow_run_id=$WORKFLOW_RUN_ID" >> $GITHUB_OUTPUT | |
- name: Wait for the workflow run to complete | |
if: success() && github.event.inputs.run_pipelines == 'true' | |
id: wait-for-workflow | |
env: | |
GH_TOKEN: ${{ secrets.GH_TOKEN_ADMIN }} | |
run: | | |
if [[ -z "$WORKFLOW_RUN_ID" ]]; then | |
echo "No workflow run ID found, skipping wait" | |
exit 0 | |
fi | |
echo "Waiting for workflow run $WORKFLOW_RUN_ID to complete..." | |
gh run watch -R ${{ matrix.target_repo }} "$WORKFLOW_RUN_ID" -i 60 | |
echo "Results JSON:" | |
RESULTS_JSON="$(gh run view -R ${{ matrix.target_repo }} "$WORKFLOW_RUN_ID" --json jobs)" | |
echo $RESULTS_JSON | |
echo "Results:" | |
RESULTS="$(echo $RESULTS_JSON | jq -r '.jobs[] | select(.conclusion != "skipped") | |
| select(.name | test("build|spl2")) | |
| "\(.name): \(.conclusion)"')" | |
printf '%s\n' "$RESULTS" | |
[[ $(printf '%s\n' "$RESULTS" | cut -d ':' -f 2 | cut -d ' ' -f 2 | sort | uniq) == "success" ]] || exit 1 |