CI by Jo5ta #49
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: CI Pipeline | |
| run-name: CI by ${{ github.actor }} | |
| on: | |
| push: | |
| branches: ['main'] | |
| pull_request: | |
| branches: ['main'] | |
| env: | |
| CI: true | |
| CONTAINER_TARGET: ci | |
| CONTAINER_CMD: docker | |
| CONTAINER_NON_INTERACTIVE: true | |
| # Required for pushing to ghcr.io and creating releases | |
| permissions: | |
| contents: write | |
| packages: write | |
| jobs: | |
| # ============================================ | |
| # Detect what changed (fast, no container) | |
| # ============================================ | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| tests: ${{ steps.filter.outputs.tests }} | |
| docs: ${{ steps.filter.outputs.docs }} | |
| ci: ${{ steps.filter.outputs.ci }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed paths | |
| id: filter | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| BASE="${{ github.event.pull_request.base.sha }}" | |
| HEAD="${{ github.event.pull_request.head.sha }}" | |
| else | |
| # Push event: compare with parent commit | |
| BASE="${{ github.event.before }}" | |
| HEAD="${{ github.sha }}" | |
| # Handle first push or force push (before is all zeros) | |
| if [ "$BASE" = "0000000000000000000000000000000000000000" ]; then | |
| # Compare against parent of HEAD | |
| BASE="${HEAD}^" | |
| fi | |
| fi | |
| CHANGED=$(git diff --name-only "$BASE" "$HEAD" 2>/dev/null || echo "") | |
| # Default all to false | |
| CODE=false | |
| TESTS=false | |
| DOCS=false | |
| CI_FILES=false | |
| # Check each pattern (only if CHANGED is non-empty) | |
| if [ -n "$CHANGED" ]; then | |
| if echo "$CHANGED" | grep -qE '^(tracing_library/|decoder_tool/|command_line_tool/|snapshot_library/|kernel_tracing_library/|cmake/|CMakeLists\.txt|CMakePresets\.json)'; then | |
| CODE=true | |
| fi | |
| if echo "$CHANGED" | grep -qE '^(tests/|examples/)'; then | |
| TESTS=true | |
| fi | |
| if echo "$CHANGED" | grep -qE '^docs/|\.md$'; then | |
| DOCS=true | |
| fi | |
| if echo "$CHANGED" | grep -qE '^(\.github/|scripts/)'; then | |
| CI_FILES=true | |
| fi | |
| fi | |
| echo "code=$CODE" >> $GITHUB_OUTPUT | |
| echo "tests=$TESTS" >> $GITHUB_OUTPUT | |
| echo "docs=$DOCS" >> $GITHUB_OUTPUT | |
| echo "ci=$CI_FILES" >> $GITHUB_OUTPUT | |
| echo "Changed files:" | |
| echo "$CHANGED" | |
| echo "" | |
| echo "Detected: code=$CODE tests=$TESTS docs=$DOCS ci=$CI_FILES" | |
| # ============================================ | |
| # Quick checks (format, version) - fail fast | |
| # Skip only for docs-only changes | |
| # ============================================ | |
| checks: | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: | | |
| github.event_name == 'push' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.tests == 'true' || | |
| needs.changes.outputs.ci == 'true' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Load CI-Container | |
| uses: ./.github/actions/load-container | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Format Check | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_format.sh | |
| - name: Fetch main branch for version check | |
| if: github.event_name == 'pull_request' | |
| run: git fetch origin main:main | |
| - name: Version Check | |
| if: github.event_name == 'pull_request' | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_version.sh | |
| # ============================================ | |
| # Build and Test | |
| # Skip only for docs-only changes | |
| # ============================================ | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| needs: [changes, checks] | |
| if: | | |
| !failure() && !cancelled() && | |
| (github.event_name == 'push' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.tests == 'true' || | |
| needs.changes.outputs.ci == 'true') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup ccache | |
| run: mkdir -p ~/.ccache | |
| - name: Restore ccache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.ccache | |
| key: ccache-${{ runner.os }}-build-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}-${{ github.sha }} | |
| restore-keys: | | |
| ccache-${{ runner.os }}-build-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}- | |
| ccache-${{ runner.os }}-build- | |
| - name: Load CI-Container | |
| uses: ./.github/actions/load-container | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_build.sh | |
| - name: Show ccache stats | |
| run: ./scripts/container.sh ccache --show-stats || true | |
| - name: Test | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_test.sh | |
| - name: Memory Check | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_memcheck.sh | |
| # ============================================ | |
| # Packaging (only for code/ci changes, or push to main) | |
| # ============================================ | |
| package: | |
| runs-on: ubuntu-latest | |
| needs: [changes, build-and-test] | |
| if: | | |
| !failure() && !cancelled() && | |
| (github.event_name == 'push' || | |
| needs.changes.outputs.code == 'true' || | |
| needs.changes.outputs.ci == 'true') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup ccache | |
| run: mkdir -p ~/.ccache | |
| - name: Restore ccache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.ccache | |
| key: ccache-${{ runner.os }}-package-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}-${{ github.sha }} | |
| restore-keys: | | |
| ccache-${{ runner.os }}-package-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}- | |
| ccache-${{ runner.os }}-package- | |
| ccache-${{ runner.os }}-build- | |
| - name: Load CI-Container | |
| uses: ./.github/actions/load-container | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Package | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_package.sh | |
| - name: Show ccache stats | |
| run: ./scripts/container.sh ccache --show-stats || true | |
| - name: Package Validate | |
| run: ./scripts/container.sh ./scripts/ci-cd/step_package_validate.sh --skip-srpm-rebuild | |
| # ========================================== | |
| # Create GitHub Release (only on push to main) | |
| # ========================================== | |
| - name: Get version and generate release info | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| id: release_info | |
| env: | |
| COMMIT_SHA: ${{ github.sha }} | |
| run: | | |
| set -e | |
| VERSION=$(head -n1 VERSION.md) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| # Create a unique tag using version + short commit hash | |
| SHORT_SHA=$(echo "$COMMIT_SHA" | cut -c1-7) | |
| echo "tag=v${VERSION}-${SHORT_SHA}" >> $GITHUB_OUTPUT | |
| # Find packages directory (container.sh puts it under build/in_container/*/build/packages) | |
| PACKAGES_DIR=$(find build -type d -name packages | head -1) | |
| if [ -z "$PACKAGES_DIR" ]; then | |
| echo "ERROR: No packages directory found" | |
| exit 1 | |
| fi | |
| # Check that SRPM exists | |
| if ! ls "$PACKAGES_DIR"/*.src.rpm 1>/dev/null 2>&1; then | |
| echo "ERROR: No SRPM found in $PACKAGES_DIR" | |
| exit 1 | |
| fi | |
| # Copy SRPM to current directory and generate checksums there | |
| # (packages dir may be owned by root from container) | |
| cp "$PACKAGES_DIR"/*.src.rpm . | |
| sha256sum *.src.rpm > SHA256SUMS | |
| # Build release body with checksums embedded | |
| { | |
| echo "Release of Common Low Level Tracing Kit" | |
| echo "" | |
| echo "**Commit:** ${COMMIT_SHA}" | |
| echo "" | |
| echo "## Install from SRPM" | |
| echo "\`\`\`bash" | |
| echo "rpmbuild --rebuild clltk-${VERSION}-*.src.rpm" | |
| echo "sudo dnf install ~/rpmbuild/RPMS/x86_64/clltk-*.rpm" | |
| echo "\`\`\`" | |
| echo "" | |
| echo "## Checksums (SHA256)" | |
| echo "\`\`\`" | |
| cat SHA256SUMS | |
| echo "\`\`\`" | |
| } > release_body.md | |
| - name: Create Release | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.release_info.outputs.tag }} | |
| name: ${{ steps.release_info.outputs.version }} | |
| body_path: release_body.md | |
| files: | | |
| *.src.rpm | |
| SHA256SUMS |