v / .github / workflows / bootstrapping_ci.yml
135 lines · 132 sloc · 5.09 KB · 93162641ddda0809e8e8c2da69af8b13982567ee
Raw
1name: Bootstrapping CI
2
3on:
4 workflow_dispatch:
5 push:
6 branches:
7 - master
8 paths-ignore:
9 - '**.yml'
10 - '**.md'
11 - '**.vv'
12 - '**.out'
13 - 'cmd/tools/**'
14 - '!cmd/tools/builders/**.v'
15 - '!cmd/tools/vup.v'
16 - '!**/bootstrapping_ci.yml'
17 pull_request:
18 paths-ignore:
19 - '**.yml'
20 - '**.md'
21 - '**.vv'
22 - '**.out'
23 - 'cmd/tools/**'
24 - '!cmd/tools/builders/**.v'
25 - '!cmd/tools/vup.v'
26 - '!**/bootstrapping_ci.yml'
27
28concurrency:
29 group: bootstrapping-${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.sha || github.ref }}
30 cancel-in-progress: true
31
32jobs:
33 bootstrap-v:
34 strategy:
35 matrix:
36 os: [ubuntu-latest, macos-14]
37 fail-fast: false
38 runs-on: ${{ matrix.os }}
39 timeout-minutes: 20
40 env:
41 VFLAGS: -no-parallel
42 B_LFLAGS: -lm -lpthread
43 steps:
44 - uses: actions/checkout@v6
45 with:
46 fetch-depth: 0
47 - name: Build V
48 run: make -j4
49 - name: Test bootstrapping (v.c can be compiled and run with -os cross)
50 run: |
51 ls -la v vc/v.c
52 ./v -os cross -o vc/v.c cmd/v
53 # shellcheck disable=SC2086
54 cc -o v_from_vc vc/v.c $B_LFLAGS
55 ls -lart v_from_vc
56 ./v_from_vc version
57 ./v_from_vc run examples/hello_world.v
58 ./v_from_vc -o v_from_vc_produced_native_v cmd/v
59 ./v_from_vc_produced_native_v run examples/hello_world.v
60 ### the next make invocation will simulate building V from scratch
61 make local=1
62 ls -la v vc/v.c v_from_vc v_from_vc_produced_native_v
63 ./v_from_vc_produced_native_v -os cross -o vc/v.c cmd/v
64 ### do it a second time, just in case:
65 # shellcheck disable=SC2086
66 clang -o v_from_vc2 vc/v.c $B_LFLAGS
67 ls -lart v_from_vc2
68 ./v_from_vc2 version
69 ./v_from_vc2 run examples/hello_world.v
70 ./v_from_vc2 -o v_from_vc_produced_native_v2 cmd/v
71 ./v_from_vc_produced_native_v2 run examples/hello_world.v
72 make local=1
73 ls -la v vc/v.c
74 ls -la v_from_vc v_from_vc_produced_native_v
75 ls -la v_from_vc2 v_from_vc_produced_native_v2
76 - name: Ensure V master is available
77 if: github.ref_name != 'master'
78 run: git branch master remotes/origin/master
79 - name: Test `v up`
80 run: |
81 # Derive a commit sha from an older successful fast workflow on master that was able to build V.
82 # The workflow used below is `Path Testing CI` (18477644).
83 # Fetch several successful runs and pick the first commit that is actually reachable on master.
84 # Some runs may reference commits from force-pushed branches that are no longer on master.
85 fetch_page() {
86 local page="$1"
87 local body=""
88 for attempt in 1 2 3; do
89 body=$(curl -sL --max-time 30 \
90 -H "Accept: application/vnd.github+json" \
91 -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
92 -H "X-GitHub-Api-Version: 2022-11-28" \
93 "https://api.github.com/repos/vlang/v/actions/workflows/18477644/runs?branch=master&status=success&event=push&per_page=10&page=$page")
94 if [ -n "$body" ] && echo "$body" | jq -e '.workflow_runs' >/dev/null 2>&1; then
95 echo "$body" | jq -r '.workflow_runs[].head_sha'
96 return 0
97 fi
98 echo "::warning::page $page attempt $attempt failed, retrying..." >&2
99 sleep 5
100 done
101 return 1
102 }
103 recent_good_commit=""
104 valid_count=0
105 for page in 1 2 3; do
106 commits=$(fetch_page "$page" || true)
107 commit_count=$(printf '%s\n' "$commits" | grep -c . || true)
108 echo "page $page: fetched $commit_count commits"
109 for sha in $commits; do
110 if git merge-base --is-ancestor "$sha" master 2>/dev/null; then
111 valid_count=$((valid_count + 1))
112 echo " valid #$valid_count: $sha"
113 # Skip the first few valid commits to get an older one for testing upgrades.
114 if [ "$valid_count" -ge 5 ]; then
115 recent_good_commit="$sha"
116 break 2
117 fi
118 fi
119 done
120 done
121 if [ -z "$recent_good_commit" ]; then
122 echo "Path Testing CI lookup yielded only $valid_count valid commits; falling back to git log."
123 recent_good_commit=$(git log master --first-parent --format=%H --before='14 days ago' -n 1)
124 fi
125 if [ -z "$recent_good_commit" ]; then
126 echo "Could not find a valid recent good commit on master"
127 exit 1
128 fi
129 echo "recent_good_commit=$recent_good_commit"
130 # Build oldv at recent_good_commit.
131 ./v run cmd/tools/oldv.v -v "$recent_good_commit"
132 cd "$HOME/.cache/oldv/v_at_$recent_good_commit"
133 # Test updating
134 ./v version && ./v -v up && ./v version
135 ./v -o v2 cmd/v && ./v2 -o v3 cmd/v
136