refactor actions, included programs from .ghaignore #317
Workflow file for this run
This file contains 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: Anchor | |
on: | |
schedule: | |
- cron: "0 0 * * *" | |
push: | |
branches: | |
- main | |
pull_request: | |
types: [opened, synchronize, reopened] | |
branches: | |
- main | |
jobs: | |
changes: | |
runs-on: ubuntu-latest | |
outputs: | |
project_batches: ${{ steps.get-projects.outputs.project_batches }} | |
total_projects: ${{ steps.get-projects.outputs.total_projects }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dorny/paths-filter@v3 | |
id: filter | |
with: | |
list-files: json | |
filters: | | |
anchor: | |
- '**/anchor/**' | |
workflow: | |
- '.github/workflows/anchor.yml' | |
ghaignore: | |
- '.github/.ghaignore' | |
- id: get-projects | |
run: | | |
# Find all anchor project directories | |
get_all_projects() { | |
find . -type d -name "anchor" | sort -u | |
} | |
# Check if a project is in the ignore list | |
is_ignored() { | |
local project=$1 | |
grep -qE "^${project}$" .github/.ghaignore | |
} | |
# Get projects that were added to or removed from .ghaignore | |
get_changed_ignored_projects() { | |
git diff origin/main .github/.ghaignore | grep "^[+-]" | grep -v "^[+-][+-]" | sed 's/^[+-]//' | |
} | |
ALL_PROJECTS=$(get_all_projects) | |
WORKFLOW_CHANGED=${{ steps.filter.outputs.workflow }} | |
GHAIGNORE_CHANGED=${{ steps.filter.outputs.ghaignore }} | |
# Determine which projects to process based on the event type and changed files | |
if [[ "$WORKFLOW_CHANGED" == "true" ]]; then | |
echo "Workflow changed. Processing all projects." | |
PROJECTS=$ALL_PROJECTS | |
elif [[ "$GHAIGNORE_CHANGED" == "true" && "${{ github.event_name }}" == "pull_request" ]]; then | |
echo ".ghaignore changed in PR. Processing only changed ignored projects." | |
PROJECTS=$(get_changed_ignored_projects) | |
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
echo "Processing changed projects for PR." | |
CHANGED=$(echo '${{ steps.filter.outputs.anchor_files }}' | jq -r '.[] | split("/") | .[0:index("anchor")+1] | join("/")') | |
PROJECTS=$CHANGED | |
else | |
echo "Processing all projects for non-PR event." | |
PROJECTS=$ALL_PROJECTS | |
fi | |
# Filter out ignored projects (except when .ghaignore itself changed in a PR) | |
FINAL_PROJECTS=() | |
while IFS= read -r project; do | |
if [[ "$GHAIGNORE_CHANGED" == "true" && "${{ github.event_name }}" == "pull_request" ]] || ! is_ignored "$project"; then | |
FINAL_PROJECTS+=("$project") | |
fi | |
done <<< "$PROJECTS" | |
# Create batches of projects (max 50 per batch) to stay under job limit | |
# https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#using-a-matrix-strategy | |
BATCH_SIZE=5 | |
BATCHES=() | |
for ((i=0; i<${#FINAL_PROJECTS[@]}; i+=BATCH_SIZE)); do | |
BATCH="${FINAL_PROJECTS[@]:i:BATCH_SIZE}" | |
BATCHES+=("$(echo $BATCH | jq -R 'split(" ")')") | |
done | |
# Output project batches and total count | |
echo "project_batches=$(echo "${BATCHES[@]}" | jq -s -c .)" >> $GITHUB_OUTPUT | |
echo "total_projects=${#FINAL_PROJECTS[@]}" >> $GITHUB_OUTPUT | |
build-and-test: | |
needs: changes | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
batch: ${{ fromJson(needs.changes.outputs.project_batches) }} | |
include: | |
- solana-version: 1.18.17 | |
anchor-version: 0.30.1 | |
fail-fast: false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: heyAyushh/[email protected] | |
with: | |
anchor-version: ${{ matrix.anchor-version }} | |
solana-cli-version: ${{ matrix.solana-version }} | |
- uses: pnpm/action-setup@v2 | |
with: | |
version: 8 | |
- name: Build and Test Batch | |
run: | | |
# Process each project in the batch | |
for project in ${{ toJson(matrix.batch) }}; do | |
project=$(echo $project | jq -r '.') | |
echo "Processing $project" | |
cd $project | |
# Build the project | |
if ! anchor build; then | |
echo "::warning file=$project/Cargo.toml::Failed to build $project" | |
echo "$project - :x: Build Failed" >> $GITHUB_STEP_SUMMARY | |
cd - | |
continue | |
fi | |
# Run tests | |
if ! pnpm install --frozen-lockfile || ! anchor test; then | |
echo "::warning file=$project/Cargo.toml::Failed to test $project" | |
echo "$project - :x: Test Failed" >> $GITHUB_STEP_SUMMARY | |
else | |
echo "$project - :white_check_mark: Passed" >> $GITHUB_STEP_SUMMARY | |
fi | |
cd - | |
done | |
summary: | |
needs: [changes, build-and-test] | |
runs-on: ubuntu-latest | |
if: always() | |
steps: | |
- name: Summary | |
run: | | |
# Provide overall workflow summary | |
echo "## Anchor Workflow Summary" >> $GITHUB_STEP_SUMMARY | |
echo "Total projects processed: ${{ needs.changes.outputs.total_projects }}" >> $GITHUB_STEP_SUMMARY | |
echo "Check individual job logs for details on warnings and failures." >> $GITHUB_STEP_SUMMARY | |
if [[ "${{ needs.build-and-test.result }}" == "success" ]]; then | |
echo ":white_check_mark: All projects completed (with potential warnings)" >> $GITHUB_STEP_SUMMARY | |
else | |
echo ":x: Some projects encountered errors" >> $GITHUB_STEP_SUMMARY | |
fi |