Cuemon CI/CD Pipeline #27
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: Cuemon CI/CD Pipeline | |
| on: | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| configuration: | |
| type: choice | |
| description: The build configuration to use in the deploy stage. | |
| required: true | |
| default: Release | |
| options: | |
| - Debug | |
| - Release | |
| permissions: | |
| contents: read | |
| jobs: | |
| prepare_test: | |
| name: 📜 Prepare Test | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| outputs: | |
| json: ${{ steps.test-projects.outputs.result }} | |
| steps: | |
| - name: Checkout | |
| uses: codebeltnet/git-checkout@v1 | |
| - id: test-projects | |
| name: Generate matrix for test projects | |
| uses: codebeltnet/shell-globbing@v2 | |
| with: | |
| pattern: | | |
| test/**/*.csproj | |
| !test/**/Cuemon.Data.SqlClient.Tests.csproj | |
| - name: JSON output | |
| run: echo "${{ steps.test-projects.outputs.result }}" | |
| build: | |
| name: call-build | |
| strategy: | |
| matrix: | |
| configuration: [Debug, Release] | |
| uses: codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3 | |
| with: | |
| configuration: ${{ matrix.configuration }} | |
| strong-name-key-filename: cuemon.snk | |
| secrets: | |
| GCP_TOKEN: ${{ secrets.GCP_TOKEN }} | |
| GCP_BUCKETNAME: ${{ secrets.GCP_BUCKETNAME }} | |
| pack: | |
| name: call-pack | |
| needs: [build] | |
| strategy: | |
| matrix: | |
| configuration: [Debug, Release] | |
| uses: codebeltnet/jobs-dotnet-pack/.github/workflows/default.yml@v3 | |
| with: | |
| configuration: ${{ matrix.configuration }} | |
| version: ${{ needs.build.outputs.version }} | |
| test_linux: | |
| name: call-test-linux | |
| needs: [build, prepare_test] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-24.04, ubuntu-24.04-arm] | |
| configuration: [Debug, Release] | |
| project: ${{ fromJson(needs.prepare_test.outputs.json) }} | |
| uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v3 | |
| with: | |
| runs-on: ${{ matrix.os }} | |
| configuration: ${{ matrix.configuration }} | |
| projects: ${{ matrix.project }} | |
| build: true # we need to build due to xUnitv3 | |
| restore: true # we need to restore since we disabled caching | |
| verbosity-level: diagnostic | |
| test_windows: | |
| name: call-test-windows | |
| needs: [build, prepare_test] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [windows-2025, windows-11-arm] | |
| configuration: [Debug, Release] | |
| project: ${{ fromJson(needs.prepare_test.outputs.json) }} | |
| uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v3 | |
| with: | |
| runs-on: ${{ matrix.os }} | |
| configuration: ${{ matrix.configuration }} | |
| projects: ${{ matrix.project }} | |
| test-arguments: -- RunConfiguration.DisableAppDomain=true | |
| build: true # we need to build for .net48 | |
| restore: true # apparently we need to restore for .net48 | |
| verbosity-level: diagnostic | |
| integration_test: | |
| name: ⚗️ Integration Test | |
| needs: [build] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| configuration: [Debug, Release] | |
| project: [ test/**/Cuemon.Data.SqlClient.Tests.csproj ] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: codebeltnet/git-checkout@v1 | |
| - name: Install .NET | |
| uses: codebeltnet/install-dotnet@v3 | |
| - name: Install .NET Tool - Report Generator | |
| uses: codebeltnet/dotnet-tool-install-reportgenerator@v1 | |
| - name: Spin up SQL Server test dependency for ${{ matrix.configuration }} build | |
| uses: codebeltnet/docker-compose@v1 | |
| with: | |
| command: up | |
| options: --wait | |
| env: | |
| SA_PASSWORD: ${{ secrets.SA_PASSWORD }} | |
| - name: Download Build Artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: '*-${{ matrix.configuration }}' | |
| merge-multiple: true | |
| - name: Fix Linux test apphost permissions | |
| run: | | |
| set -euo pipefail | |
| echo "=== Context ===" | |
| echo "Runner: $RUNNER_OS / $RUNNER_ARCH" | |
| echo "Configuration: ${{ inputs.configuration }}" | |
| echo "Workspace: $GITHUB_WORKSPACE" | |
| echo "PWD: $(pwd)" | |
| echo "Event: $GITHUB_EVENT_NAME" | |
| echo "Ref: $GITHUB_REF" | |
| echo "SHA: $GITHUB_SHA" | |
| echo | |
| echo "=== .NET info ===" | |
| dotnet --info || true | |
| echo | |
| echo "=== Git state ===" | |
| git rev-parse HEAD || true | |
| git status --porcelain || true | |
| git rev-parse --is-shallow-repository || true | |
| echo | |
| # Paths we care about | |
| BIN_GLOB="*/bin/${{ inputs.configuration }}/net*/*" | |
| OBJ_GLOB="*/obj/${{ inputs.configuration }}/net*/*" | |
| echo "=== Brute-force chmod (bin + obj) ===" | |
| find . -type f \( -path "$BIN_GLOB" -o -path "$OBJ_GLOB" \) -exec chmod a+x {} + 2>/dev/null || true | |
| echo "chmod completed (errors ignored)." | |
| echo | |
| echo "=== Mount options (look for noexec) ===" | |
| # If binaries live on a noexec mount, chmod won't help. | |
| mount | sed -n '1,200p' || true | |
| echo | |
| echo "=== Candidate executables (top 200) ===" | |
| # Show what we might execute; exclude obvious managed files | |
| find . -type f -path "$BIN_GLOB" \ | |
| ! -name "*.dll" ! -name "*.pdb" ! -name "*.json" ! -name "*.xml" \ | |
| -printf "%m %u:%g %s %p\n" | head -n 200 || true | |
| echo | |
| echo "=== Likely xUnit / test hosts (if present) ===" | |
| # These names vary; do not rely on just *Tests* | |
| find . -type f -path "$BIN_GLOB" \( \ | |
| -name "testhost*" -o \ | |
| -name "*xunit*" -o \ | |
| -name "*Tests*" -o \ | |
| -name "*.runsettings" \ | |
| \) -printf "%m %u:%g %s %p\n" | head -n 200 || true | |
| echo | |
| echo "=== Deep diagnostics for any 'testhost' or apphost candidates ===" | |
| # For each likely executable, show the facts that explain 'permission denied' vs 'exec format error' | |
| while IFS= read -r f; do | |
| echo "--- $f ---" | |
| ls -la "$f" || true | |
| # Identify file type and architecture | |
| file -L "$f" || true | |
| # If it's an ELF binary, show its dynamic interpreter and linked libs (exec format errors often show up here) | |
| if file -L "$f" | grep -q "ELF"; then | |
| echo "readelf -l (interpreter):" | |
| readelf -l "$f" 2>/dev/null | sed -n '1,80p' || true | |
| echo "ldd (dependencies):" | |
| ldd "$f" 2>/dev/null || true | |
| fi | |
| # If it's a script, CRLF in the shebang can cause 'Exec format error' | |
| if head -c 2 "$f" 2>/dev/null | grep -q "#!"; then | |
| echo "shebang:" | |
| head -n 1 "$f" | cat -A || true | |
| fi | |
| echo | |
| done < <( | |
| find . -type f -path "$BIN_GLOB" \( \ | |
| -name "testhost*" -o \ | |
| -name "*xunit*" -o \ | |
| -name "*Tests*" \ | |
| \) | head -n 50 | |
| ) || true | |
| echo "=== Done diagnostics step ===" | |
| shell: bash | |
| - name: Test with ${{ matrix.configuration }} build | |
| uses: codebeltnet/dotnet-test@v4 | |
| with: | |
| projects: ${{ matrix.project }} | |
| configuration: ${{ matrix.configuration }} | |
| build: true # apparently we need to due to xUnitv3 | |
| restore: true # we need to restore since we disabled caching | |
| env: | |
| CONNECTIONSTRINGS__ADVENTUREWORKS: ${{ secrets.DB_ADVENTUREWORKS }} | |
| - name: Take down SQL Server test dependency for ${{ matrix.configuration }} build | |
| uses: codebeltnet/docker-compose@v1 | |
| with: | |
| command: down | |
| sonarcloud: | |
| name: call-sonarcloud | |
| needs: [build, test_linux, test_windows, integration_test] | |
| uses: codebeltnet/jobs-sonarcloud/.github/workflows/default.yml@v3 | |
| with: | |
| organization: geekle | |
| projectKey: Cuemon | |
| version: ${{ needs.build.outputs.version }} | |
| secrets: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| codecov: | |
| name: call-codecov | |
| needs: [build, test_linux, test_windows, integration_test] | |
| uses: codebeltnet/jobs-codecov/.github/workflows/default.yml@v1 | |
| with: | |
| repository: codebeltnet/cuemon | |
| secrets: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| codeql: | |
| name: call-codeql | |
| needs: [build, test_linux, test_windows, integration_test] | |
| uses: codebeltnet/jobs-codeql/.github/workflows/default.yml@v3 | |
| with: | |
| timeout-minutes: 30 | |
| permissions: | |
| security-events: write | |
| deploy: | |
| if: github.event_name != 'pull_request' | |
| name: call-nuget | |
| needs: [build, pack, test_linux, test_windows, integration_test, sonarcloud, codecov, codeql] | |
| uses: codebeltnet/jobs-nuget-push/.github/workflows/default.yml@v2 | |
| with: | |
| version: ${{ needs.build.outputs.version }} | |
| environment: Production | |
| configuration: ${{ inputs.configuration == '' && 'Release' || inputs.configuration }} | |
| permissions: | |
| contents: write | |
| packages: write | |
| secrets: | |
| NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} |