Repository navigation
164 lines (149 loc) · 7.06 KB
/
Copy pathdependency-updates.yml
File metadata and controls
164 lines (149 loc) · 7.06 KB
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
name: Weekly dependency updates
# Updates every external dependency that has a compatible release, one lane at a time
# (tooling/dependency-lanes.mjs): installs it or rebuilds the native helpers whose pins
# changed, lets Claude fix what broke and leaves out a lane that still fails. The
# remaining lanes get the checks on a Mac with a simulator, which Claude may fix too,
# and one pull request. CI then adds the Linux, Codex regression and visual jobs to it.
# A run that produces no pull request opens or updates an issue.
on:
schedule:
# Off the hour, when GitHub drops fewer scheduled runs. Tuesday runs only if no
# run succeeded since Monday, in case Monday's never started or crashed.
- cron: '23 4 * * 1'
- cron: '23 4 * * 2'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: dependency-updates
cancel-in-progress: false
env:
HUSKY: '0'
BRANCH: deps/weekly
jobs:
due:
runs-on: ubuntu-latest
permissions:
actions: read
outputs:
run: ${{ steps.due.outputs.run }}
steps:
- id: due
env:
GH_TOKEN: ${{ github.token }}
RETRY: ${{ github.event.schedule == '23 4 * * 2' }}
run: |
run=true
if [ "$RETRY" = true ]; then
since=$(date -u -d yesterday +%F)
done=$(gh run list -R "$GITHUB_REPOSITORY" --workflow dependency-updates.yml --status success --created ">=$since" --json databaseId -q length)
if [ "$done" != 0 ]; then run=false; fi
fi
echo "run=$run" >> "$GITHUB_OUTPUT"
update:
needs: due
if: needs.due.outputs.run == 'true'
runs-on: xcode-27
timeout-minutes: 300
permissions:
contents: write
pull-requests: write
actions: write
issues: write
env:
DEVELOPER_DIR: /Applications/Xcode_27.app/Contents/Developer
# Optional. A token with workflow permission also updates pinned actions, and
# its pull requests start CI on their own; without it CI is dispatched.
UPDATE_TOKEN: ${{ secrets.DEPENDENCY_UPDATES_TOKEN }}
GH_TOKEN: ${{ github.token }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: main
fetch-depth: 0
token: ${{ secrets.DEPENDENCY_UPDATES_TOKEN || github.token }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: '22.23.2'
cache: npm
cache-dependency-path: |
package-lock.json
packages/runtimes/agent-device/package-lock.json
packages/runtimes/serve-emu/package-lock.json
# Same toolchain as the release build, so rebuilt helpers match what ships.
- name: Prepare native build tools
run: |
test "$(uname -m)" = arm64
brew install cmake ninja pkgconf openssl@3 autoconf automake libtool
rustup toolchain install 1.98.1 --profile minimal
rustup default 1.98.1
android_sdk_manager="${ANDROID_HOME:?}/cmdline-tools/latest/bin/sdkmanager"
"$android_sdk_manager" --sdk_root="$ANDROID_HOME" --install 'ndk;27.2.12479018'
echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/27.2.12479018" >> "$GITHUB_ENV"
- name: Install dependencies
run: |
npm ci --no-audit --no-fund
npm run vendor:agent-device
npm run vendor:serve-emu
# Applies, prepares and commits each lane on the update branch, then runs the
# checks. Needs the native release tools above to rebuild changed helpers.
- name: Update dependencies
id: update
env:
# Optional. Without it, a lane that fails to install or build is left out,
# and failed checks are reported for a person to fix. Only Claude gets it.
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git switch -C "$BRANCH"
# Later steps read it too; the runner context is not available in job env.
export WORK="$RUNNER_TEMP/dependency-update"
echo "WORK=$WORK" >> "$GITHUB_ENV"
node tooling/weekly-dependency-update.mjs "$WORK"
- name: Open or update the pull request
if: steps.update.outputs.changed == 'true'
env:
GH_TOKEN: ${{ secrets.DEPENDENCY_UPDATES_TOKEN || github.token }}
run: |
git push -q --force origin "$BRANCH"
number=$(gh pr list --head "$BRANCH" --state open --json number -q '.[0].number')
if [ -n "$number" ]; then gh pr edit "$number" --body-file "$WORK/body.md"
else gh pr create --base main --head "$BRANCH" --title 'chore(deps): weekly dependency updates' --body-file "$WORK/body.md"; fi
# Pull requests opened with the workflow token do not start other workflows.
- name: Start CI on the pull request
if: steps.update.outputs.changed == 'true' && env.UPDATE_TOKEN == ''
run: gh workflow run ci.yml --ref "$BRANCH"
# No pull request means nobody would notice: every lane was left out, or the run
# crashed. The next run that opens one, or finds nothing to update, closes it.
- name: Report a failed update
if: failure() || (steps.update.outputs.changed == 'false' && steps.update.outputs.left_out != '')
env:
LEFT_OUT: ${{ steps.update.outputs.left_out }}
run: |
title='Weekly dependency update failed'
if [ -n "$LEFT_OUT" ] && [ -f "$WORK/body.md" ]; then
body=$(printf 'Every lane with updates was left out ([run](%s)):\n\n%s' "$RUN_URL" "$(cat "$WORK/body.md")")
else
body="The [weekly dependency update]($RUN_URL) failed before it could open a pull request. Its logs are in the run and its dependency-update-logs artifact."
fi
number=$(gh issue list --state open --search "in:title \"$title\"" --json number,title -q ".[] | select(.title == \"$title\") | .number" | head -1)
if [ -n "$number" ]; then gh issue comment "$number" --body "$body"
else gh issue create --title "$title" --body "$body"; fi
- name: Close the failure report
if: success() && !(steps.update.outputs.changed == 'false' && steps.update.outputs.left_out != '')
run: |
title='Weekly dependency update failed'
for number in $(gh issue list --state open --search "in:title \"$title\"" --json number,title -q ".[] | select(.title == \"$title\") | .number"); do
gh issue close "$number" --comment "Fixed by [this run]($RUN_URL)."
done
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: dependency-update-logs
path: |
${{ runner.temp }}/dependency-update
!${{ runner.temp }}/dependency-update/native-artifacts
if-no-files-found: ignore
retention-days: 14