|
|
@@ -1,334 +0,0 @@
|
|
|
-name: Steel
|
|
|
-
|
|
|
-on:
|
|
|
- schedule:
|
|
|
- - cron: "0 0 * * *"
|
|
|
- push:
|
|
|
- branches:
|
|
|
- - main
|
|
|
- pull_request:
|
|
|
- types: [opened, synchronize, reopened]
|
|
|
- branches:
|
|
|
- - main
|
|
|
-
|
|
|
-env:
|
|
|
- MAX_JOBS: 64
|
|
|
- MIN_PROJECTS_PER_JOB: 4
|
|
|
- MIN_PROJECTS_FOR_MATRIX: 4
|
|
|
-
|
|
|
-jobs:
|
|
|
- changes:
|
|
|
- runs-on: ubuntu-latest
|
|
|
- permissions:
|
|
|
- pull-requests: read
|
|
|
- outputs:
|
|
|
- changed_projects: ${{ steps.analyze.outputs.changed_projects }}
|
|
|
- total_projects: ${{ steps.analyze.outputs.total_projects }}
|
|
|
- matrix: ${{ steps.matrix.outputs.matrix }}
|
|
|
- steps:
|
|
|
- - uses: actions/checkout@v4
|
|
|
- - uses: dtolnay/rust-toolchain@stable
|
|
|
- with:
|
|
|
- components: rustfmt, clippy
|
|
|
- - uses: dorny/paths-filter@v3
|
|
|
- id: changes
|
|
|
- if: github.event_name == 'pull_request'
|
|
|
- with:
|
|
|
- list-files: shell
|
|
|
- filters: |
|
|
|
- steel:
|
|
|
- - added|modified: '**/steel/**'
|
|
|
- workflow:
|
|
|
- - added|modified: '.github/workflows/steel.yml'
|
|
|
-
|
|
|
- - name: Run fmt and clippy
|
|
|
- run: |
|
|
|
- readarray -t all_projects < <(echo '${{ needs.changes.outputs.changed_projects }}' | jq -r '.[]?')
|
|
|
- for project in "${all_projects[@]}"; do
|
|
|
- echo "::group::Checking ${project}"
|
|
|
- if [ ! -f "${project}/Cargo.toml" ]; then
|
|
|
- echo "::error::No Cargo.toml found in ${project}"
|
|
|
- exit 1
|
|
|
- fi
|
|
|
- cd "${project}"
|
|
|
- cargo fmt --check
|
|
|
- cargo clippy --all-features -- -D warnings
|
|
|
- cd - > /dev/null
|
|
|
- echo "::endgroup::"
|
|
|
- done
|
|
|
-
|
|
|
- - name: Analyze Changes
|
|
|
- id: analyze
|
|
|
- run: |
|
|
|
- # Generate ignore pattern, excluding comments
|
|
|
- ignore_pattern=$(grep -v '^#' .github/.ghaignore | grep -v '^$' | tr '\n' '|' | sed 's/|$//')
|
|
|
- echo "Ignore pattern: $ignore_pattern"
|
|
|
-
|
|
|
- function get_projects() {
|
|
|
- find . -type d -name "steel" | grep -vE "$ignore_pattern" | sort
|
|
|
- }
|
|
|
-
|
|
|
- # Determine which projects to build and test
|
|
|
- if [[ "${{ github.event_name }}" == "push" || "${{ github.event_name }}" == "schedule" || "${{ steps.changes.outputs.workflow }}" == "true" ]]; then
|
|
|
- projects=$(get_projects)
|
|
|
- elif [[ "${{ steps.changes.outputs.steel }}" == "true" ]]; then
|
|
|
- changed_files=(${{ steps.changes.outputs.steel_files }})
|
|
|
- projects=$(for file in "${changed_files[@]}"; do dirname "${file}" | grep steel | sed 's#/steel/.*#/steel#g'; done | grep -vE "$ignore_pattern" | sort -u)
|
|
|
- else
|
|
|
- projects=""
|
|
|
- fi
|
|
|
-
|
|
|
- # Output project information
|
|
|
- if [[ -n "$projects" ]]; then
|
|
|
- echo "Projects to build and test"
|
|
|
- echo "$projects"
|
|
|
- total_projects=$(echo "$projects" | wc -l)
|
|
|
- echo "Total projects: $total_projects"
|
|
|
- echo "total_projects=$total_projects" >> $GITHUB_OUTPUT
|
|
|
- echo "changed_projects=$(echo "$projects" | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT
|
|
|
- else
|
|
|
- echo "No projects to build and test."
|
|
|
- echo "total_projects=0" >> $GITHUB_OUTPUT
|
|
|
- echo "changed_projects=[]" >> $GITHUB_OUTPUT
|
|
|
- fi
|
|
|
- - name: Generate matrix
|
|
|
- id: matrix
|
|
|
- run: |
|
|
|
- total_projects=${{ steps.analyze.outputs.total_projects }}
|
|
|
- max_jobs=${{ env.MAX_JOBS }}
|
|
|
- min_projects_per_job=${{ env.MIN_PROJECTS_PER_JOB }}
|
|
|
- min_projects_for_matrix=${{ env.MIN_PROJECTS_FOR_MATRIX }}
|
|
|
-
|
|
|
- if [ "$total_projects" -lt "$min_projects_for_matrix" ]; then
|
|
|
- echo "matrix=[0]" >> $GITHUB_OUTPUT
|
|
|
- else
|
|
|
- projects_per_job=$(( (total_projects + max_jobs - 1) / max_jobs ))
|
|
|
- projects_per_job=$(( projects_per_job > min_projects_per_job ? projects_per_job : min_projects_per_job ))
|
|
|
- num_jobs=$(( (total_projects + projects_per_job - 1) / projects_per_job ))
|
|
|
-
|
|
|
- indices=$(seq 0 $(( num_jobs - 1 )))
|
|
|
- echo "matrix=[$(echo $indices | tr ' ' ',')]" >> $GITHUB_OUTPUT
|
|
|
- fi
|
|
|
-
|
|
|
- rust-checks:
|
|
|
- needs: changes
|
|
|
- if: ${{ github.event_name == 'pull_request' && needs.changes.outputs.total_projects != '0' }}
|
|
|
- name: Rust Checks
|
|
|
- runs-on: ubuntu-latest
|
|
|
- steps:
|
|
|
- - uses: actions/checkout@v4
|
|
|
- - name: Run fmt and clippy
|
|
|
- run: |
|
|
|
- readarray -t all_projects < <(echo '${{ needs.changes.outputs.changed_projects }}' | jq -r '.[]?')
|
|
|
- for project in "${all_projects[@]}"; do
|
|
|
- echo "::group::Checking ${project}"
|
|
|
- if [ ! -f "${project}/Cargo.toml" ]; then
|
|
|
- echo "::error::No Cargo.toml found in ${project}"
|
|
|
- exit 1
|
|
|
- fi
|
|
|
- cd "${project}"
|
|
|
- cargo fmt --check
|
|
|
- cargo clippy --all-features -- -D warnings
|
|
|
- cd - > /dev/null
|
|
|
- echo "::endgroup::"
|
|
|
- done
|
|
|
-
|
|
|
- build-and-test:
|
|
|
- needs: changes
|
|
|
- if: needs.changes.outputs.total_projects != '0'
|
|
|
- runs-on: ubuntu-latest
|
|
|
- strategy:
|
|
|
- fail-fast: false
|
|
|
- matrix:
|
|
|
- index: ${{ fromJson(needs.changes.outputs.matrix) }}
|
|
|
- name: build-and-test-group-${{ matrix.index }}
|
|
|
- outputs:
|
|
|
- failed_projects: ${{ steps.set-failed.outputs.failed_projects }}
|
|
|
- steps:
|
|
|
- - uses: actions/checkout@v4
|
|
|
- - uses: dorny/paths-filter@v3
|
|
|
- id: changes
|
|
|
- if: github.event_name == 'pull_request'
|
|
|
- with:
|
|
|
- list-files: shell
|
|
|
- filters: |
|
|
|
- native:
|
|
|
- - added|modified: '**/native/**'
|
|
|
- workflow:
|
|
|
- - added|modified: '.github/workflows/solana-native.yml'
|
|
|
- - name: Use Node.js
|
|
|
- uses: actions/setup-node@v4
|
|
|
- with:
|
|
|
- node-version: 'lts/*'
|
|
|
- check-latest: true
|
|
|
- - name: Setup build environment
|
|
|
- id: setup
|
|
|
- run: |
|
|
|
- npm install --global pnpm
|
|
|
-
|
|
|
- # Create the build and test function
|
|
|
- cat << 'EOF' > build_and_test.sh
|
|
|
- function build_and_test() {
|
|
|
- local project=$1
|
|
|
- local solana_version=$2
|
|
|
- echo "Building and Testing $project with Solana $solana_version"
|
|
|
- cd "$project" || return 1
|
|
|
-
|
|
|
- # Check if this is a pnpm project or Steel CLI project
|
|
|
- if [ -f "package.json" ]; then
|
|
|
- # Use pnpm for projects with package.json
|
|
|
- if ! pnpm install --frozen-lockfile; then
|
|
|
- echo "::error::pnpm install failed for $project"
|
|
|
- echo "$project: pnpm install failed with $solana_version" >> $GITHUB_WORKSPACE/failed_projects.txt
|
|
|
- cd - > /dev/null
|
|
|
- return 1
|
|
|
- fi
|
|
|
-
|
|
|
- # Build
|
|
|
- if ! pnpm build; then
|
|
|
- echo "::error::build failed for $project"
|
|
|
- echo "$project: build failed with $solana_version" >> $GITHUB_WORKSPACE/failed_projects.txt
|
|
|
- cd - > /dev/null
|
|
|
- return 1
|
|
|
- fi
|
|
|
-
|
|
|
- # Test
|
|
|
- if ! pnpm test; then
|
|
|
- echo "::error::tests failed for $project"
|
|
|
- echo "$project: tests failed with $solana_version" >> $GITHUB_WORKSPACE/failed_projects.txt
|
|
|
- cd - > /dev/null
|
|
|
- return 1
|
|
|
- fi
|
|
|
- else
|
|
|
- # Use Steel CLI for pure Steel projects
|
|
|
-
|
|
|
- # Build
|
|
|
- if ! steel build; then
|
|
|
- echo "::error::steel build failed for $project"
|
|
|
- echo "$project: steel build failed with $solana_version" >> $GITHUB_WORKSPACE/failed_projects.txt
|
|
|
- cd - > /dev/null
|
|
|
- return 1
|
|
|
- fi
|
|
|
-
|
|
|
- # Test
|
|
|
- if ! steel test; then
|
|
|
- echo "::error::steel test failed for $project"
|
|
|
- echo "$project: steel test failed with $solana_version" >> $GITHUB_WORKSPACE/failed_projects.txt
|
|
|
- cd - > /dev/null
|
|
|
- return 1
|
|
|
- fi
|
|
|
- fi
|
|
|
-
|
|
|
- echo "Build and tests succeeded for $project with $solana_version version."
|
|
|
- cd - > /dev/null
|
|
|
- return 0
|
|
|
- }
|
|
|
-
|
|
|
- function process_projects() {
|
|
|
- local solana_version=$1
|
|
|
-
|
|
|
- readarray -t all_projects < <(echo '${{ needs.changes.outputs.changed_projects }}' | jq -r '.[]?')
|
|
|
- start_index=$(( ${{ matrix.index }} * ${{ env.MIN_PROJECTS_PER_JOB }} ))
|
|
|
- end_index=$(( start_index + ${{ env.MIN_PROJECTS_PER_JOB }} ))
|
|
|
- end_index=$(( end_index > ${{ needs.changes.outputs.total_projects }} ? ${{ needs.changes.outputs.total_projects }} : end_index ))
|
|
|
-
|
|
|
- echo "Projects to build and test in this job"
|
|
|
- for i in $(seq $start_index $(( end_index - 1 ))); do
|
|
|
- echo "${all_projects[$i]}"
|
|
|
- done
|
|
|
-
|
|
|
- failed=false
|
|
|
- for i in $(seq $start_index $(( end_index - 1 ))); do
|
|
|
- echo "::group::Building and testing ${all_projects[$i]}"
|
|
|
- if ! build_and_test "${all_projects[$i]}" "$solana_version"; then
|
|
|
- failed=true
|
|
|
- fi
|
|
|
- echo "::endgroup::"
|
|
|
- done
|
|
|
-
|
|
|
- return $([ "$failed" = true ] && echo 1 || echo 0)
|
|
|
- }
|
|
|
- EOF
|
|
|
-
|
|
|
- # Make the script executable
|
|
|
- chmod +x build_and_test.sh
|
|
|
-
|
|
|
- - name: Setup Solana Stable
|
|
|
- uses: heyAyushh/setup-solana@v2.02
|
|
|
- with:
|
|
|
- solana-cli-version: stable
|
|
|
- - name: Build and Test with Stable
|
|
|
- run: |
|
|
|
- source build_and_test.sh
|
|
|
- solana -V
|
|
|
- rustc -V
|
|
|
- solana-keygen new --no-bip39-passphrase --force
|
|
|
- cargo install --quiet steel-cli
|
|
|
- process_projects "stable"
|
|
|
- - name: Setup Solana Beta
|
|
|
- uses: heyAyushh/setup-solana@v2.02
|
|
|
- with:
|
|
|
- solana-cli-version: beta
|
|
|
- - name: Build and Test with Beta
|
|
|
- run: |
|
|
|
- source build_and_test.sh
|
|
|
- solana -V
|
|
|
- rustc -V
|
|
|
- solana-keygen new --no-bip39-passphrase --force
|
|
|
- cargo install --quiet steel-cli
|
|
|
- process_projects "beta"
|
|
|
-
|
|
|
- - name: Set failed projects output
|
|
|
- id: set-failed
|
|
|
- if: failure()
|
|
|
- run: |
|
|
|
- if [ -f "$GITHUB_WORKSPACE/failed_projects.txt" ]; then
|
|
|
- failed_projects=$(cat $GITHUB_WORKSPACE/failed_projects.txt | jq -R -s -c 'split("\n")[:-1]')
|
|
|
- echo "failed_projects=$failed_projects" >> $GITHUB_OUTPUT
|
|
|
- else
|
|
|
- echo "failed_projects=[]" >> $GITHUB_OUTPUT
|
|
|
- fi
|
|
|
-
|
|
|
- summary:
|
|
|
- needs: [changes, build-and-test]
|
|
|
- if: always()
|
|
|
- runs-on: ubuntu-latest
|
|
|
- steps:
|
|
|
- - uses: actions/checkout@v4
|
|
|
- - name: Create job summary
|
|
|
- run: |
|
|
|
- echo "## Steel Workflow Summary" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "- Total projects: ${{ needs.changes.outputs.total_projects }}" >> $GITHUB_STEP_SUMMARY
|
|
|
-
|
|
|
- # List all processed projects
|
|
|
- echo "<details>" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "<summary>Projects processed (click to expand)</summary>" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo '${{ needs.changes.outputs.changed_projects }}' | jq -r '.[]' | while read project; do
|
|
|
- echo "- $project" >> $GITHUB_STEP_SUMMARY
|
|
|
- done
|
|
|
- echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "</details>" >> $GITHUB_STEP_SUMMARY
|
|
|
-
|
|
|
- # Report build and test results
|
|
|
- if [[ "${{ needs.build-and-test.result }}" == "failure" ]]; then
|
|
|
- echo "## :x: Build or tests failed" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "<details>" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "<summary>Failed projects (click to expand)</summary>" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
- failed_projects='${{ needs.build-and-test.outputs.failed_projects }}'
|
|
|
- if [[ -n "$failed_projects" ]]; then
|
|
|
- echo "$failed_projects" | jq -r '.[]' | while IFS=: read -r project failure_reason; do
|
|
|
- echo "- **$project**" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo " - Failure reason: $failure_reason" >> $GITHUB_STEP_SUMMARY
|
|
|
- done
|
|
|
- else
|
|
|
- echo "No failed projects reported. This might indicate an unexpected error in the workflow." >> $GITHUB_STEP_SUMMARY
|
|
|
- fi
|
|
|
- echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
- echo "</details>" >> $GITHUB_STEP_SUMMARY
|
|
|
- elif [[ "${{ needs.build-and-test.result }}" == "success" ]]; then
|
|
|
- echo "## :white_check_mark: All builds and tests passed" >> $GITHUB_STEP_SUMMARY
|
|
|
- else
|
|
|
- echo "## :warning: Build and test job was skipped or canceled" >> $GITHUB_STEP_SUMMARY
|
|
|
- fi
|