name: Continuous Integration # CI pipeline for the Skelly Godot project # # Code quality checks (formatting, linting, testing) run as independent jobs # in parallel. Uses tools/run_development.py for consistency with local development. # # Features: # - Independent job execution (no dependencies between format/lint/test) # - Automatic code formatting with commit back to branch # - Error reporting and PR comments # - Manual execution with selective step skipping on: # Trigger on push to any branch - only when relevant files change push: branches: ['*'] paths: - '**/*.gd' # Any GDScript file - '.gdlintrc' # Linting configuration - '.gdformatrc' # Formatting configuration - 'tools/run_development.py' # Development workflow script - '.gitea/workflows/ci.yml' # This workflow file # Trigger on pull requests - same file filters as push pull_request: branches: ['*'] paths: - '**/*.gd' - '.gdlintrc' - '.gdformatrc' - 'tools/run_development.py' - '.gitea/workflows/ci.yml' # Allow manual triggering with optional step skipping workflow_dispatch: inputs: skip_format: description: 'Skip code formatting' required: false default: 'false' type: boolean skip_lint: description: 'Skip code linting' required: false default: 'false' type: boolean skip_tests: description: 'Skip test execution' required: false default: 'false' type: boolean jobs: format: name: Code Formatting runs-on: ubuntu-latest permissions: contents: write pull-requests: write if: ${{ always() && github.event.inputs.skip_format != 'true' }} steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.ref || github.ref }} token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install --upgrade "setuptools<81" pip install gdtoolkit==4 - name: Run code formatting id: format run: | echo "๐ŸŽจ Running GDScript formatting..." python tools/run_development.py --format - name: Check for formatting changes id: check-changes run: | if git diff --quiet; then echo "๐Ÿ“ No formatting changes detected" echo "has_changes=false" >> $GITHUB_OUTPUT else echo "๐Ÿ“ Formatting changes detected" echo "has_changes=true" >> $GITHUB_OUTPUT echo "๐Ÿ” Changed files:" git diff --name-only echo "" echo "๐Ÿ“Š Diff summary:" git diff --stat fi - name: Commit and push formatting changes if: steps.check-changes.outputs.has_changes == 'true' run: | echo "๐Ÿ’พ Committing formatting changes..." git config user.name "Gitea Actions" git config user.email "actions@gitea.local" git add -A commit_message="๐ŸŽจ Auto-format GDScript code Automated formatting applied by tools/run_development.py ๐Ÿค– Generated by Gitea Actions Workflow: ${{ github.workflow }} Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" git commit -m "$commit_message" target_branch="${{ github.event.pull_request.head.ref || github.ref_name }}" echo "๐Ÿ“ค Pushing changes to branch: $target_branch" git push origin HEAD:"$target_branch" echo "โœ… Formatting changes pushed successfully!" lint: name: Code Quality Check runs-on: ubuntu-latest if: ${{ github.event.inputs.skip_lint != 'true' }} steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.ref || github.ref }} fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install --upgrade "setuptools<81" pip install gdtoolkit==4 - name: Run linting id: lint run: | echo "๐Ÿ” Running GDScript linting..." python tools/run_development.py --lint - name: Upload linting results if: failure() uses: actions/upload-artifact@v3 with: name: lint-results path: | **/*.gd retention-days: 7 test: name: Test Execution runs-on: ubuntu-latest if: ${{ github.event.inputs.skip_tests != 'true' }} steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.ref || github.ref }} fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' cache: 'pip' - name: Install Python dependencies run: | python -m pip install --upgrade pip pip install --upgrade "setuptools<81" pip install gdtoolkit==4 - name: Set up Godot uses: chickensoft-games/setup-godot@v1 with: version: 4.3.0 use-dotnet: false - name: Run tests id: test run: | echo "๐Ÿงช Running GDScript tests..." python tools/run_development.py --test - name: Upload test results if: failure() uses: actions/upload-artifact@v3 with: name: test-results path: | tests/**/*.gd retention-days: 7 summary: name: CI Summary runs-on: ubuntu-latest needs: [format, lint, test] if: always() steps: - name: Set workflow status id: status run: | format_status="${{ needs.format.result }}" lint_status="${{ needs.lint.result }}" test_status="${{ needs.test.result }}" echo "๐Ÿ“Š Workflow Results:" echo "๐ŸŽจ Format: $format_status" echo "๐Ÿ” Lint: $lint_status" echo "๐Ÿงช Test: $test_status" if [[ "$format_status" == "success" && "$lint_status" == "success" && ("$test_status" == "success" || "$test_status" == "skipped") ]]; then echo "overall_status=success" >> $GITHUB_OUTPUT echo "โœ… All CI checks passed!" else echo "overall_status=failure" >> $GITHUB_OUTPUT echo "โŒ Some CI checks failed" fi - name: Comment on PR (if applicable) if: github.event_name == 'pull_request' uses: actions/github-script@v6 with: script: | const formatStatus = '${{ needs.format.result }}'; const lintStatus = '${{ needs.lint.result }}'; const testStatus = '${{ needs.test.result }}'; const overallStatus = '${{ steps.status.outputs.overall_status }}'; const getStatusEmoji = (status) => { switch(status) { case 'success': return 'โœ…'; case 'failure': return 'โŒ'; case 'skipped': return 'โญ๏ธ'; default: return 'โš ๏ธ'; } }; const message = `## ๐Ÿค– CI Pipeline Results | Step | Status | Result | |------|--------|--------| | ๐ŸŽจ Formatting | ${getStatusEmoji(formatStatus)} | ${formatStatus} | | ๐Ÿ” Linting | ${getStatusEmoji(lintStatus)} | ${lintStatus} | | ๐Ÿงช Testing | ${getStatusEmoji(testStatus)} | ${testStatus} | **Overall Status:** ${getStatusEmoji(overallStatus)} ${overallStatus.toUpperCase()} ${overallStatus === 'success' ? '๐ŸŽ‰ All checks passed! This PR is ready for review.' : 'โš ๏ธ Some checks failed. Please review the workflow logs and fix any issues.'} [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})`; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: message }); - name: Set final exit code run: | if [[ "${{ steps.status.outputs.overall_status }}" == "success" ]]; then echo "๐ŸŽ‰ CI Pipeline completed successfully!" exit 0 else echo "โŒ CI Pipeline failed" exit 1 fi