Skip to content

test: TA testing pipeline to build add-ons with custom UCC #1989

test: TA testing pipeline to build add-ons with custom UCC

test: TA testing pipeline to build add-ons with custom UCC #1989

Workflow file for this run

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