Skip to content

Commit 9317905

Browse files
authored
Merge branch 'main' into feat/ADFA-6279-agent-capability-tags
2 parents e1e0d78 + f0e8510 commit 9317905

88 files changed

Lines changed: 2978 additions & 1075 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/build-addons.yml‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Build addon artifacts
2+
3+
# Builds every addon (or one) to prove the tree compiles and packages.
4+
# It publishes nothing and uploads no artifacts: to get a downloadable URL,
5+
# run "Publish addons" with staging: true.
6+
#
7+
# Two kinds of addon, two build scripts (ADFA-6252). A plugin is a Gradle project
8+
# that compiles to a .cgp against the CodeOnTheGo jars; a template is a plain-text
9+
# tree that zips to a .cgt and needs neither. Each script builds only its own kind
10+
# and ignores a name of the other, so both steps get the same input.
11+
12+
on:
13+
workflow_dispatch:
14+
inputs:
15+
codeonthego_ref:
16+
description: CodeOnTheGo branch or tag to build the libs against
17+
required: false
18+
default: stage
19+
addon:
20+
description: One addon directory name, e.g. Random-XKCD (blank builds all)
21+
required: false
22+
default: ''
23+
24+
permissions:
25+
contents: read
26+
27+
jobs:
28+
build:
29+
runs-on: ubuntu-latest
30+
timeout-minutes: 45
31+
steps:
32+
- name: Checkout plugin-examples
33+
uses: actions/checkout@v4
34+
35+
- name: Set up JDK 17
36+
uses: actions/setup-java@v4
37+
with:
38+
distribution: temurin
39+
java-version: '17'
40+
41+
- name: Install uv
42+
uses: astral-sh/setup-uv@v5
43+
44+
- name: Set up Gradle
45+
uses: gradle/actions/setup-gradle@v3
46+
with:
47+
cache-disabled: true
48+
add-job-summary: 'never'
49+
50+
- name: Refresh libs and build plugins
51+
env:
52+
CODEONTHEGO_REF: ${{ inputs.codeonthego_ref }}
53+
ONLY_ADDON: ${{ inputs.addon }}
54+
run: ./scripts/build-plugins.sh --ref "$CODEONTHEGO_REF" ${ONLY_ADDON:+"$ONLY_ADDON"}
55+
56+
- name: Build templates
57+
env:
58+
ONLY_ADDON: ${{ inputs.addon }}
59+
run: ./scripts/build-templates.sh ${ONLY_ADDON:+"$ONLY_ADDON"}

‎.github/workflows/build-plugins.yml‎

Lines changed: 0 additions & 87 deletions
This file was deleted.

‎.github/workflows/check-toolchain.yml‎

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ name: Check toolchain
55
# deliberately not restated here, so there is only one copy of the numbers.
66
#
77
# This is the only workflow here that runs automatically on pull requests.
8-
# "Build plugin artifacts" and "Update libs from CodeOnTheGo" are both
8+
# "Build addon artifacts" and "Update libs from CodeOnTheGo" are both
99
# workflow_dispatch-only, which is why toolchain drift previously reached
1010
# main with no CI signal at all.
1111
#
1212
# It is pure text inspection — no JDK, no Gradle, no network — so it costs a
1313
# few seconds and is safe to make a required check.
14+
#
15+
# It also lints the template bundle sources (ADFA-6252). Those checks are
16+
# borrowed from dev-assets' lint-templates.yml, which guards core.cgt the same
17+
# way. They are cheap, and since this is the only workflow that runs on a pull
18+
# request, it is the only place a broken bundle can be caught before merge.
1419

1520
on:
1621
pull_request:
@@ -53,3 +58,109 @@ jobs:
5358

5459
- name: Check addon names and metadata
5560
run: uv run --directory tools/addons addons --root "$GITHUB_WORKSPACE" check
61+
62+
# From here down: the template bundle sources. `addons check` already
63+
# asserts the structure (templates.json parses, every path it names
64+
# exists and carries a template.json, the addon.json block is present).
65+
# These add the syntax checks it does not do, on the file contents.
66+
- name: Install the template lint tools
67+
run: |
68+
sudo apt-get update -qq
69+
sudo apt-get install -y -qq libxml2-utils jq zip
70+
pip install --quiet json5
71+
72+
- name: Reject junk files committed under templates/
73+
run: |
74+
set -e
75+
BAD=$(git ls-files templates/ | grep -E '(^|/)(\.gradle|build|local\.properties)(/|$)|\.(swp|swo|bak)$|(^|/)\.DS_Store$' || true)
76+
if [ -n "$BAD" ]; then
77+
echo "::error::Junk files committed under templates/:"
78+
echo "$BAD"
79+
exit 1
80+
fi
81+
82+
- name: Reject a committed bundle or provenance record
83+
run: |
84+
set -e
85+
# Both are generated at publish time. A committed one goes stale
86+
# silently and would ship instead of a fresh build (ADFA-6252).
87+
BAD=$(git ls-files templates/ | grep -E '\.cgt$|(^|/)cgt-build\.properties$' || true)
88+
if [ -n "$BAD" ]; then
89+
echo "::error::A .cgt or cgt-build.properties is committed; both are generated:"
90+
echo "$BAD"
91+
exit 1
92+
fi
93+
94+
- name: Validate XML under templates/
95+
run: |
96+
set -e
97+
fail=0
98+
while IFS= read -r f; do
99+
if ! xmllint --noout "$f" 2>/dev/null; then
100+
echo "::error file=$f::Invalid XML"
101+
fail=1
102+
fi
103+
done < <(find templates -type f -name '*.xml')
104+
exit $fail
105+
106+
- name: Validate each templates.json (strict JSON)
107+
run: |
108+
set -e
109+
fail=0
110+
while IFS= read -r f; do
111+
if ! jq empty "$f" 2>/dev/null; then
112+
echo "::error file=$f::Invalid JSON"
113+
fail=1
114+
fi
115+
done < <(find templates -maxdepth 2 -type f -name 'templates.json')
116+
exit $fail
117+
118+
- name: Validate each template.json (JSON5)
119+
run: |
120+
set -e
121+
fail=0
122+
while IFS= read -r f; do
123+
if ! python3 -c "import json5,sys; json5.load(open(sys.argv[1]))" "$f" >/dev/null 2>&1; then
124+
echo "::error file=$f::Invalid JSON5"
125+
fail=1
126+
fi
127+
done < <(find templates -type f -path '*/template/template.json')
128+
exit $fail
129+
130+
- name: Pebble brace balance check
131+
run: |
132+
set -e
133+
# Counts delimiters only. It cannot tell whether an identifier is
134+
# declared, and the renderer runs with strictVariables(true), so an
135+
# undeclared one still fails on the device at project generation.
136+
fail=0
137+
while IFS= read -r f; do
138+
opens=$(grep -o '{{' "$f" | wc -l | tr -d ' ')
139+
closes=$(grep -o '}}' "$f" | wc -l | tr -d ' ')
140+
if [ "$opens" != "$closes" ]; then
141+
echo "::error file=$f::Pebble brace imbalance: $opens '{{' vs $closes '}}'"
142+
fail=1
143+
fi
144+
done < <(find templates -type f -name '*.peb')
145+
exit $fail
146+
147+
- name: Build every template bundle
148+
run: |
149+
set -euo pipefail
150+
# Proves the bundle packages and that templates.json names only paths
151+
# that exist: build-cgt.sh derives its file list from that manifest and
152+
# fails when one is missing.
153+
./scripts/build-templates.sh
154+
for cgt in dist/*.cgt; do
155+
[ -e "$cgt" ] || continue
156+
slug="$(basename "$cgt" .cgt)"
157+
# The IDE looks templates.json up by that exact bare name, so a
158+
# nested one means no template is ever found.
159+
unzip -l "$cgt" | grep -qE '[[:space:]]templates\.json$' \
160+
|| { echo "::error::${slug}.cgt has no bare templates.json entry"; exit 1; }
161+
# Repository metadata must not reach a user-facing download.
162+
if unzip -l "$cgt" | grep -qE '[[:space:]](addon\.json|.*\.html|icon_(day|night)\.png)$'; then
163+
echo "::error::${slug}.cgt contains gallery metadata that belongs only in the repository"
164+
exit 1
165+
fi
166+
done

‎.github/workflows/publish-addons.yml‎

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -86,42 +86,32 @@ jobs:
8686
PLUGIN_LIBS_REVISION: ${{ steps.libs.outputs.revision }}
8787
run: |
8888
set -euo pipefail
89-
mkdir -p dist
90-
all="$(uv run --directory tools/addons addons --root "$GITHUB_WORKSPACE" discover)"
89+
# Without a name, discover lists every addon not held back by skip.txt.
90+
# With one, it resolves the directory name or the slug, in any case, and
91+
# fails on an unknown one, so a hostile value never reaches the shell as
92+
# a path.
9193
if [ "$ADDON" = "all" ]; then
92-
names="$all"
94+
names="$(uv run --directory tools/addons addons --root "$GITHUB_WORKSPACE" discover)"
9395
else
94-
# resolve through discover so an unknown or hostile value cannot
95-
# reach the shell as a path
96-
# match the directory name or the lowercase slug the rest of the
97-
# system uses (dl/<slug>.cgp, the catalog's slug field)
98-
names="$(printf '%s\n' "$all" | awk -v want="$ADDON" '
99-
{ n = $0; sub(/.*\//, "", n); l = tolower(n)
100-
if (n == want || $0 == want || l == tolower(want)) print }')"
101-
if [ -z "$names" ]; then
102-
echo "Unknown addon: $ADDON" >&2; exit 1
103-
fi
96+
names="$(uv run --directory tools/addons addons --root "$GITHUB_WORKSPACE" discover "$ADDON")"
10497
fi
10598
printf 'only<<EOF\n%s\nEOF\n' "$names" >> "$GITHUB_OUTPUT"
106-
for dir in $names; do
107-
echo "==> $dir"
108-
( cd "$dir"
109-
gradlew="$GITHUB_WORKSPACE/gradlew"
110-
if [ -x ./gradlew ]; then gradlew=./gradlew; fi
111-
if grep -q downloadAssets build.gradle.kts; then
112-
"$gradlew" --console=plain downloadAssets
113-
fi
114-
"$gradlew" --console=plain assemblePlugin )
115-
"$GITHUB_WORKSPACE/scripts/verify-provenance.sh" "$dir"
116-
slug="$(basename "$dir" | tr '[:upper:]' '[:lower:]')"
117-
src="$(ls "$dir"/build/plugin/*.cgp | grep -v -- '-debug\.cgp$' | head -n1)"
118-
cp "$src" "dist/${slug}.cgp"
119-
done
99+
# Two kinds of addon, two build scripts (ADFA-6252). Each builds only its
100+
# own kind from the list and ignores the rest. No --ref: the previous
101+
# step already put the plugin-api-latest jars in libs/.
102+
# shellcheck disable=SC2086
103+
./scripts/build-plugins.sh --out dist $names
104+
# shellcheck disable=SC2086
105+
./scripts/build-templates.sh $names
120106
121107
- name: Build the source tarballs
122108
env:
123109
ONLY: ${{ steps.stage.outputs.only }}
124110
run: |
111+
# Templates are passed in with everything else and skipped inside the
112+
# tool, which logs the skip: a template ships no source tarball because
113+
# its .cgt is plain text and already is its source (ADFA-6252). Filtering
114+
# here instead would put the rule in two places.
125115
# shellcheck disable=SC2086
126116
uv run --directory tools/addons addons --root "$GITHUB_WORKSPACE" \
127117
tarball --out "$GITHUB_WORKSPACE/dist" --only $ONLY

‎.github/workflows/update-libs.yml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ jobs:
7171
RUN_NUMBER: ${{ github.run_number }}
7272
run: echo "name=build-$(date -u +%Y-%m-%d)-${RUN_NUMBER}" >> "$GITHUB_OUTPUT"
7373

74-
- name: Run update-libs script
75-
run: ./scripts/update-libs.sh
74+
# Refreshes libs/ from CodeOnTheGo@stage, then proves every plugin still
75+
# compiles against the new jars. Templates use no jars, so none are built.
76+
- name: Refresh libs and build plugins
77+
run: ./scripts/build-plugins.sh --ref stage
7678

7779
- name: Commit updated jars
7880
id: commit

‎.gitignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
**/.DS_Store
77
**/*.keystore
88
**/*.cgp
9+
# Template bundles and their provenance record are generated, never committed
10+
# (ADFA-6252). Each template addon also ignores its own, but keep the repo-wide
11+
# rule beside *.cgp so a stray one anywhere cannot be added by accident.
12+
**/*.cgt
13+
**/cgt-build.properties
14+
# Where the publish and build workflows stage artifacts
15+
dist/
916
**/release.properties
1017
**/RecentProject_database*
1118
**/agent/

0 commit comments

Comments
 (0)