-
Notifications
You must be signed in to change notification settings - Fork 5
234 lines (214 loc) · 8.61 KB
/
publish.yml
File metadata and controls
234 lines (214 loc) · 8.61 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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
name: Publish to JSR
on:
push:
branches:
- main
paths:
- "packages/*/deno.json"
- "packages/*/mod.ts"
- "packages/*/src/**"
- ".github/workflows/publish.yml"
pull_request:
branches:
- main
paths:
- "packages/*/deno.json"
- "packages/*/mod.ts"
- "packages/*/src/**"
- ".github/workflows/publish.yml"
env:
DENO_VERSION: v2.x
BUILD_ORDER: '["schema", "runtime-core", "lib", "runtime-browser", "runtime-deno", "ai", "python-runtime-agent", "pyodide-runtime-agent", "tui"]'
jobs:
generate-build-order:
runs-on: ubuntu-latest
outputs:
build_list: ${{ steps.set_outputs.outputs.build_list }}
dry_run: ${{ steps.set_outputs.outputs.dry_run }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Filter changed packages
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
schema:
- 'packages/schema/**'
runtime-core:
- 'packages/runtime-core/**'
lib:
- 'packages/lib/**'
runtime-browser:
- 'packages/runtime-browser/**'
runtime-deno:
- 'packages/runtime-deno/**'
ai:
- 'packages/ai/**'
python-runtime-agent:
- 'packages/python-runtime-agent/**'
pyodide-runtime-agent:
- 'packages/pyodide-runtime-agent/**'
tui:
- 'packages/tui/**'
publish:
- '.github/workflows/publish.yml'
- name: Generate changed_packages
id: changed_pkgs
run: |
# Convert BUILD_ORDER to a bash array
PKGS=$(echo "$BUILD_ORDER" | jq -r '.[]')
# Build a jq filter to extract only those keys from the dorny output using .["key"] syntax
JQ_FILTER=$(echo "$BUILD_ORDER" | jq -r 'map("\"" + . + "\": .[\"" + . + "\"]") | join(", ")')
# Compose the final object
CHANGED_PACKAGES=$(jq -n --argjson obj '${{ toJson(steps.filter.outputs) }}' '$obj' | jq -c "{ $JQ_FILTER }")
# Dorny has values of true/false, but they're strings not booleans. Fix that here
CHANGED_PACKAGES=$(echo "$CHANGED_PACKAGES" | jq -c 'with_entries(
.value |= (
if type == "string" then
(if (ascii_downcase == "true") then true
elif (ascii_downcase == "false") then false
else . end)
else
.
end
)
)')
MISSING_KEYS=$(echo "$CHANGED_PACKAGES" | jq -r 'to_entries | map(select(.value == null) | .key) | join(",")')
if [ -n "$MISSING_KEYS" ]; then
echo "Error: The following keys are missing from the dorny filter step: $MISSING_KEYS"
exit 1
fi
echo "CHANGED_PACKAGES: $CHANGED_PACKAGES"
echo "changed_packages=$CHANGED_PACKAGES" >> $GITHUB_OUTPUT
- name: Ensure build-order is up to date
run: |
set -e
# CHANGED_PACKAGES is a JSON object with package keys and boolean values
CHANGED_PACKAGES=$(echo '${{ steps.changed_pkgs.outputs.changed_packages }}' | jq -r 'keys | .[]' | jq -R . | jq -c -s .)
# PKG_NAMES represents all the packages in the repo
PKG_NAMES=$(ls packages/*/deno.json | xargs -n1 jq -r .name | sed 's/^@runt\///' | jq -R . | jq -c -s .)
BUILD_ORDER_SORTED=$(echo "$BUILD_ORDER" | jq -c 'sort')
PKG_NAMES_SORTED=$(echo "$PKG_NAMES" | jq -c 'sort')
CHANGED_PACKAGES_SORTED=$(echo "$CHANGED_PACKAGES" | jq -c 'sort')
echo "BUILD_ORDER: $BUILD_ORDER"
echo "BUILD_ORDER_SORTED: $BUILD_ORDER_SORTED"
echo "CHANGED_PACKAGES: $CHANGED_PACKAGES"
echo "CHANGED_PACKAGES_SORTED: $CHANGED_PACKAGES_SORTED"
echo "PKG_NAMES: $PKG_NAMES"
echo "PKG_NAMES_SORTED: $PKG_NAMES_SORTED"
# Detect any mismatches between these three values, and report an error
if [ "$BUILD_ORDER_SORTED" != "$PKG_NAMES_SORTED" ]; then
echo "Mismatch: BUILD_ORDER and PKG_NAMES do not match" && exit 1
fi
if [ "$BUILD_ORDER_SORTED" != "$CHANGED_PACKAGES_SORTED" ]; then
echo "Mismatch: BUILD_ORDER and CHANGED_PACKAGES do not match" && exit 1
fi
- name: Generate build_list
id: build_list
run: |
CHANGED_PACKAGES=$(echo '${{ steps.changed_pkgs.outputs.changed_packages }}')
values=$(echo "$BUILD_ORDER" | jq --argjson changed "$CHANGED_PACKAGES" '[.[] | $changed[.]]')
idx_first_packgage_to_build=$(echo "$values" | jq 'index(true)')
if [ "$idx_first_packgage_to_build" = "null" ]; then
BUILD_LIST="[]"
else
BUILD_LIST=$(echo "$BUILD_ORDER" | jq -c ".[ $idx_first_packgage_to_build : ]")
fi
echo "BUILD_LIST: $BUILD_LIST"
echo "build_list=$BUILD_LIST" >> $GITHUB_OUTPUT
- name: Set outputs
id: set_outputs
run: |
BUILD_LIST='${{ steps.build_list.outputs.build_list }}'
GITHUB_ACTION_CHANGED='${{ steps.filter.outputs.publish }}'
GITHUB_EVENT_NAME='${{ github.event_name }}'
GITHUB_REF_NAME='${{ github.ref_name }}'
DRY_RUN=false
if [ "$BUILD_LIST" = "[]" ] && [ "$GITHUB_ACTION_CHANGED" = "true" ]; then
echo "Only changing the github action, setting dry_run to true, and building everything"
BUILD_LIST="$BUILD_ORDER"
DRY_RUN=true
fi
if [ "$GITHUB_EVENT_NAME" != "push" ] || [ "$GITHUB_REF_NAME" != "main" ]; then
echo "Running a $GITHUB_EVENT_NAME event on a $GITHUB_REF_NAME branch, setting dry_run to true"
DRY_RUN=true
fi
echo "BUILD_LIST: $BUILD_LIST"
echo "DRY_RUN: $DRY_RUN"
echo "build_list=$BUILD_LIST" >> $GITHUB_OUTPUT
echo "dry_run=$DRY_RUN" >> $GITHUB_OUTPUT
publish:
name: Publish Packages Sequentially
runs-on: ubuntu-latest
needs: generate-build-order
if: ${{ needs.generate-build-order.outputs.build_list != '[]' }}
concurrency:
group: publish-${{ github.run_id }}
cancel-in-progress: false
permissions:
contents: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: ${{ env.DENO_VERSION }}
cache: true
- name: Publish packages in order
id: publish
env:
BUILD_LIST: ${{ needs.generate-build-order.outputs.build_list }}
DRY_RUN: ${{ needs.generate-build-order.outputs.dry_run }}
run: |
set -e
PACKAGES=$(echo "$BUILD_LIST" | jq -r '.[]')
TAGS_CREATED=()
for PKG in $PACKAGES; do
PKG_DIR="packages/$PKG"
DENO_JSON="$PKG_DIR/deno.json"
if [ ! -f "$DENO_JSON" ]; then
echo "No deno.json for $PKG, skipping."
continue
fi
VERSION=$(jq -r .version "$DENO_JSON")
echo "Publishing @$PKG@$VERSION"
cd "$PKG_DIR"
if [ "$DRY_RUN" = "true" ]; then
echo "Dry run: Would publish @$PKG@$VERSION"
deno publish --dry-run --allow-slow-types
else
deno publish --allow-slow-types
fi
cd -
if [ "$DRY_RUN" != "true" ]; then
echo "Waiting for @$PKG@$VERSION to be available on JSR..."
TIMEOUT=30
ELAPSED=0
while true; do
deno info jsr:@runt/$PKG@$VERSION && break
sleep 2
ELAPSED=$((ELAPSED+2))
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "Timeout waiting for @$PKG@$VERSION to be available on JSR"
exit 1
fi
done
TAG="v${VERSION}-${PKG}"
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git tag "$TAG" -m "Release @$PKG@$VERSION"
TAGS_CREATED+=("$TAG")
fi
done
if [ "$DRY_RUN" != "true" ] && [ ${#TAGS_CREATED[@]} -gt 0 ]; then
git push origin --tags
fi
echo "Published packages: $PACKAGES"
if [ "$DRY_RUN" = "true" ]; then
echo "**Dry run completed - no packages were published**"
else
echo "✅ **Packages successfully published to JSR**"
fi