-
Notifications
You must be signed in to change notification settings - Fork 362
174 lines (159 loc) · 6.3 KB
/
anchor.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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 }}
batch_count: ${{ steps.get-projects.outputs.batch_count }}
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
shell: bash
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"
# Debug output
echo "Final projects to process:"
printf '%s\n' "${FINAL_PROJECTS[@]}"
# Create batches of projects (max 5 per batch) to stay under job limit
BATCH_SIZE=5
BATCHES="["
BATCH_COUNT=0
for ((i=0; i<${#FINAL_PROJECTS[@]}; i+=BATCH_SIZE)); do
if [ $i -ne 0 ]; then
BATCHES="${BATCHES},"
fi
END=$((i + BATCH_SIZE))
if [ $END -gt ${#FINAL_PROJECTS[@]} ]; then
END=${#FINAL_PROJECTS[@]}
fi
BATCH=$(printf '%s\n' "${FINAL_PROJECTS[@]:i:BATCH_SIZE}" | jq -R . | jq -s .)
BATCHES="${BATCHES}${BATCH}"
BATCH_COUNT=$((BATCH_COUNT + 1))
done
BATCHES="${BATCHES}]"
# Debug output
echo "Total projects: ${#FINAL_PROJECTS[@]}"
echo "Total batches: $BATCH_COUNT"
echo "Batches created:"
echo "$BATCHES" | jq .
# Output project batches as JSON array and total count
echo "project_batches=$BATCHES" >> $GITHUB_OUTPUT
echo "total_projects=${#FINAL_PROJECTS[@]}" >> $GITHUB_OUTPUT
echo "batch_count=$BATCH_COUNT" >> $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: |
echo "Processing batch: ${{ toJson(matrix.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 - > /dev/null
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 - > /dev/null
done
summary:
needs: [changes, build-and-test]
runs-on: ubuntu-latest
if: always()
steps:
- name: Summary
run: |
echo "## Anchor Workflow Summary" >> $GITHUB_STEP_SUMMARY
echo "Total projects processed: ${{ needs.changes.outputs.total_projects }}" >> $GITHUB_STEP_SUMMARY
echo "Total batches: ${{ needs.changes.outputs.batch_count }}" >> $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