11name : Build Plugin
2+ run-name : Build Plugin ${{ inputs.plugin_directory }}
23
34on :
45 workflow_call :
1213 required : true
1314 FOSSA_API_KEY :
1415 required : true
16+ SONARQUBE_TOKEN :
17+ required : true
18+ SONARQUBE_HOST_URL :
19+ required : true
1520 workflow_dispatch :
1621 inputs :
1722 plugin_directory :
1823 description : " Directory of the plugin"
1924 required : true
2025 type : choice
2126 options :
27+ - sam-bedrock-agent
28+ - sam-event-mesh-agent
2229 - sam-event-mesh-gateway
23- - sam-mongodb
24- - sam-sql-database
30+ - sam-event-mesh-tool
2531 - sam-geo-information
26- - sam-rest-gateway
27- - sam-webhook-gateway
28- - sam-bedrock-agent
2932 - sam-mermaid
33+ - sam-mongodb
34+ - sam-nuclia-tool
35+ - sam-rag
36+ - sam-rest-gateway
37+ - sam-ruleset-lookup-tool
3038 - sam-slack
39+ - sam-slack-gateway-adapter
40+ - sam-sql-database
41+ - sam-sql-database-tool
42+ - sam-webhook-gateway
3143
3244permissions :
3345 contents : write
@@ -47,44 +59,97 @@ jobs:
4759 fetch-depth : 0
4860 sparse-checkout : ${{ inputs.plugin_directory }}
4961
50- - name : Set up Python
51- uses : actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
52- with :
53- python-version : " 3.12"
54- - name : Cache pip
55- uses : actions/cache@6f8efc29b200d32929f49075959781ed54ec270c # v3.5.0
56- with :
57- path : ~/.cache/pip
58- key : ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
59- restore-keys : |
60- ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
62+ - name : Install uv
63+ id : setup-uv
64+ uses : astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
6165 - name : Install Hatch
62- shell : bash
63- run : |
64- python -m pip install --upgrade pip -q
65- pip install hatch -q
66- pip install virtualenv pipdeptree -q
66+ run : uv tool install hatch
67+ - name : Create Hatch Environment
68+ working-directory : ${{ inputs.plugin_directory }}
69+ run : hatch -v env create hatch-test.py3.13
6770
68- - name : Test Plugin
71+ - name : Test Plugin ${{ inputs.plugin_directory }} with Python 3.13
72+ id : test
73+ continue-on-error : true
74+ working-directory : ${{ inputs.plugin_directory }}
6975 shell : bash
7076 run : |
71- cd ${{ inputs.plugin_directory }}/
72- ls -la
73- dir=$(pwd)
74- echo "Directory: $dir"
75- hatch run pip install solace-agent-mesh twine -q
76- hatch run solace-agent-mesh plugin add test-${{ inputs.plugin_directory }} --plugin $dir
77- hatch test
77+ # Check if tests directory exists
78+ if [ ! -d "tests" ]; then
79+ echo "No tests directory found, skipping tests"
80+ echo "junit_exists=false" >> $GITHUB_OUTPUT
81+ echo "coverage_exists=false" >> $GITHUB_OUTPUT
82+ exit 0
83+ fi
7884
79- - name : Install dependencies
85+ # Run tests with coverage if pytest-cov is available, otherwise without
86+ if hatch -v run hatch-test.py3.13:pip show pytest-cov > /dev/null 2>&1; then
87+ echo "Running tests with coverage..."
88+ hatch -v run hatch-test.py3.13:pytest tests/ --cov --cov-report=xml:coverage.xml --cov-report=term --junitxml=junit.xml
89+ else
90+ echo "Running tests without coverage (pytest-cov not available)..."
91+ hatch -v run hatch-test.py3.13:pytest tests/ --junitxml=junit.xml
92+ fi
93+
94+ # Check if result files exist
95+ if [ -f coverage.xml ]; then
96+ echo "coverage_exists=true" >> $GITHUB_OUTPUT
97+ else
98+ echo "coverage_exists=false" >> $GITHUB_OUTPUT
99+ fi
100+ if [ -f junit.xml ]; then
101+ echo "junit_exists=true" >> $GITHUB_OUTPUT
102+ else
103+ echo "junit_exists=false" >> $GITHUB_OUTPUT
104+ fi
105+
106+ - name : Status Check - Unit Tests
107+ uses : mikepenz/action-junit-report@3585e9575db828022551b4231f165eb59a0e74e3 # v5.6.2
108+ if : always() && steps.test.outputs.junit_exists == 'true'
109+ with :
110+ check_name : Unit Tests - ${{ inputs.plugin_directory }}
111+ report_paths : ${{ inputs.plugin_directory }}/junit.xml
112+ include_passed : true
113+
114+ - name : SonarQube Scan
115+ uses : sonarsource/sonarqube-scan-action@540792c588b5c2740ad2bb4667db5cd46ae678f2 # v2.2.0
116+ env :
117+ SONAR_TOKEN : ${{ secrets.SONARQUBE_TOKEN }}
118+ SONAR_HOST_URL : ${{ secrets.SONARQUBE_HOST_URL }}
119+ with :
120+ projectBaseDir : ${{ inputs.plugin_directory }}
121+ args : >
122+ -Dsonar.projectKey=${{ github.repository_owner }}_${{ inputs.plugin_directory }}
123+
124+ - name : SonarQube Quality Gate check
125+ if : github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
126+ id : sonarqube-quality-gate-check
127+ uses : sonarsource/sonarqube-quality-gate-action@master
128+ continue-on-error : true
129+ env :
130+ SONAR_TOKEN : ${{ secrets.SONARQUBE_TOKEN }}
131+ SONAR_HOST_URL : ${{ secrets.SONARQUBE_HOST_URL }}
132+
133+ - name : Build and Verify Package
80134 shell : bash
81135 run : |
82136 cd ${{ inputs.plugin_directory }}
83137 hatch build
84- ls dist/*.tar.gz | xargs -n1 hatch run python -m twine check
85- ls dist/*.whl | xargs -n1 hatch run python -m twine check
138+ # Use uv to run twine for package verification
139+ uv tool run twine check dist/*.tar.gz
140+ uv tool run twine check dist/*.whl
141+
142+ - name : Upload Build Artifacts
143+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
144+ with :
145+ name : ${{ inputs.plugin_directory }}-dist
146+ path : ${{ inputs.plugin_directory }}/dist/
147+ retention-days : 7
86148
87- - name : sca-scan
149+ # FOSSA Scan - uploads plugin data to FOSSA as unique project
150+ # Guard checks run at repo level in ci.yaml on main branch
151+ - name : FOSSA Scan
152+ continue-on-error : true
88153 uses : SolaceDev/solace-public-workflows/.github/actions/sca/sca-scan@main
89154 with :
90155 scanners : " fossa"
@@ -93,30 +158,3 @@ jobs:
93158 fossa.revision=${{ github.event.pull_request.number && github.head_ref || github.sha }}
94159 fossa.config=${{ inputs.plugin_directory }}/.fossa.yml
95160 fossa_api_key : ${{ secrets.FOSSA_API_KEY }}
96-
97-
98- - name : FOSSA Licensing
99- id : fossa_licensing
100- if : ${{ always() }}
101- uses : SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
102- with :
103- fossa_api_key : ${{ secrets.FOSSA_API_KEY }}
104- fossa_project_id : " ${{ github.repository_owner }}_${{ inputs.plugin_directory }}"
105- fossa_branch : ${{ github.event.pull_request.number && 'PR' || github.event.repository.default_branch }}
106- fossa_revision : ${{ github.event.pull_request.number && github.head_ref || github.sha }}
107- fossa_category : licensing
108- fossa_mode : BLOCK
109- block_on : policy_conflict
110-
111- - name : FOSSA Security Vulnerabilities
112- id : fossa_vulnerabilities
113- if : ${{ always() }}
114- uses : SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
115- with :
116- fossa_api_key : ${{ secrets.FOSSA_API_KEY }}
117- fossa_project_id : " ${{ github.repository_owner }}_${{ inputs.plugin_directory }}"
118- fossa_branch : ${{ github.event.pull_request.number && 'PR' || github.event.repository.default_branch }}
119- fossa_revision : ${{ github.event.pull_request.number && github.head_ref || github.sha }}
120- fossa_category : vulnerability
121- fossa_mode : BLOCK
122- block_on : critical,high
0 commit comments