sync-submodule
Checklist and steps for syncing the skywalking submodule to a new upstream tag or commit. Covers all required checks and updates.
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-10
- Stars
- ★ 13
- Forks
- 1
01 前言 Front Matter
- name
- sync-submodule
- description
- Checklist and steps for syncing the skywalking submodule to a new upstream tag or commit. Covers all required checks and updates.
02 资源文件 11
- 参考文档references/01-prerequisites.md1.9 KB
- 参考文档references/02-starters-and-removed-features.md9.6 KB
- 参考文档references/03-jackson-3.md4.2 KB
- 参考文档references/04-core-framework.md4.2 KB
- 参考文档references/05-build-and-dependencies.md6.2 KB
- 参考文档references/06-configuration-properties.md3.0 KB
- 参考文档references/07-web-and-messaging.md7.3 KB
- 参考文档references/08-testing.md6.0 KB
- 参考文档references/09-actuator-and-observability.md2.7 KB
- 参考文档references/10-kotlin-and-java-build-config.md1.3 KB
- 参考文档references/11-checklist-pitfalls-resources.md5.9 KB
03 SKILL.md 正文
Sync SkyWalking Submodule
Checklist for updating the skywalking/ submodule to a new upstream tag/commit.
1. Update Submodule
cd skywalking && git fetch origin --tags && git checkout <tag-or-commit>
Verify the upstream <revision> in skywalking/pom.xml — the Makefile extracts it for -Dskywalking.version.
2. Install Upstream to Local Maven Repo
make init-skywalking
3. Analyze Changes
Compare the old and new commits to identify what changed:
cd skywalking && git log --oneline <old-commit>..<new-commit>
Key areas to check for impact
| Area | What to look for |
|---|---|
OAL engine (oal-rt/) |
API changes to OALEngineV2 |
MAL engine (meter-analyzer/) |
API changes to MALClassGenerator, new grammar tokens |
LAL engine (log-analyzer/) |
API changes to LALClassGenerator |
TAL engine (trace-analyzer/) |
API changes to TALClassGenerator, TalDSL.of, TALConfigs.load, metric declaration fields |
| New modules | New ModuleDefine/ModuleProvider classes |
| New OAL files | oal/*.oal |
| New MAL rules | otel-rules/, meter-analyzer-config/, log-mal-rules/, envoy-metrics-rules/, telegraf-rules/, zabbix-rules/ |
| New LAL rules | lal/*.yaml |
| New TAL rules | tal/*.yaml |
| Same-FQCN files changed | Upstream versions of files we replace in oap-libs-for-graalvm/ |
| New config fields | Changes to ModuleConfig subclasses |
| application.yml | New module sections, new config properties |
| pom.xml deps | New module artifacts, version bumps |
4. Required Updates (Checklist)
Module wiring (if new modules added)
- [ ] Add dependency to root
pom.xml<dependencyManagement> - [ ] Add dependency to
oap-graalvm-server/pom.xml<dependencies> - [ ] Register module+provider in
GraalVMOAPServerStartUp.java - [ ] Add
(moduleName, providerName)pair toAcceptedModules.java - [ ] Add module config section to
application.yml
Config handling (if new ModuleConfig classes)
- [ ] Re-run config-generator to regenerate
YamlConfigLoaderUtils.javaandmodule-config-classes.txt:./mvnw -pl build-tools/build-common,build-tools/config-generator install -DskipTests -Dskywalking.version=<version> ./mvnw -pl build-tools/config-generator exec:java \ -Dexec.args="oap-graalvm-server/src/main/java/org/apache/skywalking/oap/server/library/util/YamlConfigLoaderUtils.java build-tools/precompiler/src/main/resources/META-INF/module-config-classes.txt" \ -Dskywalking.version=<version> - [ ] If config class has no
@Setterat class level, create same-FQCN replacement inoap-libs-for-graalvm/with@Setteradded - [ ] Add shade exclusion for replaced config class
OAL changes (if new .oal files or scopes)
- [ ] New OAL files are auto-discovered via
OALDefineSPI — verify in precompiler output - [ ] Add generated metrics + builder classes to
reachability-metadata.jsoninoap-graalvm-native - [ ] Verify with:
jar tf build-tools/precompiler/target/precompiler-*-generated.jar | grep "oal/rt"
Rule adoption policy (OAL / MAL / LAL / TAL)
Every rule file upstream adds or changes is adopted, without exception. The distro must never trail upstream on bundled rules. Concretely, for each new or changed file:
- [ ] It is pre-compiled:
otel-rules/**,meter-analyzer-config/*,log-mal-rules/*,envoy-metrics-rules/*,telegraf-rules/*,zabbix-rules/*,lal/*,tal/*,oal/*.oalare all auto-discovered by the precompiler; verify the counts in its log (MAL: compiled N rules from <dir>,LAL pre-compilation,TAL pre-compilation,Precompiler: N metrics). - [ ] It is enabled by default exactly as upstream: mirror upstream
application.yml(enabledOtelMetricsRules,meterAnalyzerActiveFiles,lalFiles,malFiles, ...). - [ ]
rule-file-inventory.properties(+ section counts) andprecompiled-yaml-sha256.propertiescover it. - [ ] A MAL comparison test exists for every new MAL file (auto-discovery mode:
generateComparisonTests("<dir>/<file>.yaml")); LAL tests for new LAL files. - [ ]
docs/distro-policy.mdcounts are refreshed. - [ ] It is browsable: the precompiler exports raw rule files to
META-INF/rule-source/for the read-only/runtime/rule+/runtime/oalcatalogs — nothing to do per file, but keepBundledRuleCatalogHandlerTestexpectations current if a file is renamed.
E2E adoption
When upstream adds an e2e case for a new rule set, adopt it if it is compose-only:
- [ ] Prefer mock/replay style cases (e.g.
airflow/mock,banyandb) over ones that need a real product cluster or build an agent from source; those go to the CI matrix only if cheap. - [ ] Copy the case to
test/e2e/cases/<name>/with the distrooapservice (imageskywalking-oap-native:latest,SW_HEALTH_CHECKER/SW_STORAGE_BANYANDB_TARGETS/SW_CONFIGURATION, thenc 11800healthcheck) and reference the upstream case files by relative path (../../../../skywalking/test/e2e-v2/cases/<case>/...) for build contexts, mounted configs andverify.cases.includesso expectations track upstream automatically. - [ ] Add a
.github/workflows/ci.ymle2e matrix entry. - [ ] Not adoptable: cases that mount rule YAML at runtime (needs runtime compile),
runtime-rule/*,dsl-debugging/{mal,lal-*}(seed rules via runtime-rule), ZooKeeper/etcd cluster cases.dsl-debugging/oalIS adopted (test/e2e/cases/dsl-debugging-oal): it debugs a bundled OAL rule. - [ ] DSL debugging stays live: the precompiler calls
DSLDebugCodegenSwitch.enableInjection()before generating and setssetContent(...)on the MAL/LAL generators; if upstream changes the probe codegen orGateHolder, re-check thedsl-management,dsl-debugginganddsl-debugging-oale2e cases.
MAL/LAL changes (if new rule files)
- [ ] New MAL rules under
otel-rules/with glob**/*are auto-compiled by precompiler - [ ] New LAL rules must be added to
lalFilesinapplication.yml - [ ] Update
enabledOtelMetricsRulesinapplication.ymlfor new otel rule directories - [ ] Create MAL comparison tests in
oap-graalvm-server/src/test/.../mal/
Inventory updates
- [ ] Add new provider to
provider-inventory.properties - [ ] Add new rule files to
rule-file-inventory.properties
Distribution packaging
- [ ] Add runtime config files (not DSL scripts) to
distribution.xmlandnative-distribution.xml - [ ] Update
docs/distro-policy.mdmodule table - [ ] Update
docs/version-mapping.md
E2E test environment
- [ ] Update
test/e2e/script/env:SW_UPSTREAM_COMMIT— submodule HEADSW_E2E_SERVICE_COMMIT— last commit touchingtest/e2e-v2/java-test-service/SW_BANYANDB_COMMIT— match upstreamtest/e2e-v2/script/envSW_AGENT_JAVA_COMMIT— match upstream
- [ ] Add new e2e test cases if upstream added new features with e2e tests
- [ ] Add new test entries to
.github/workflows/ci.ymlmatrix
Same-FQCN replacement staleness
- [ ] Run
ReplacementClassStalenessTest— if upstream changed files we replace, update replacements - [ ] Run
PrecompiledYamlStalenessTest— update SHA-256 hashes for changed YAML files
5. Build & Test
make compile # Compile everything
make test # Run all 1300+ tests
6. Native Image Verification
make native-image-macos # Cross-compile for Linux (on macOS)
make docker-native # Build Docker image
docker tag skywalking-oap-native skywalking-oap-native:latest
# Run e2e smoke test
e2e run -c test/e2e/cases/simple-java-agent/e2e.yaml
Check OAP logs for reflection errors:
docker logs <container> 2>&1 | grep "ERROR\|NoSuchMethodException\|ClassNotFoundException"
7. Common Pitfalls
-
New module = three lists:
GraalVMOAPServerStartUpregistration,provider-inventory.properties, ANDbuild-tools/build-common/.../AcceptedModules.java. The config-generator discovers providers only throughAcceptedModules, so a module missing there gets nocopyTo<Config>branch inYamlConfigLoaderUtilsand the OAP dies at boot withUnknown config type— after the JVM unit tests passed. -
Always
./mvnw clean installbefore a native build after a submodule bump: a resumed build (-rf :precompiler, no clean) reuses the oldoap-libs-for-graalvm/*/target/*.jar, and maven-shade merges that stale shaded jar with the fresh upstream jar; the stale copy wins, JVM unit tests still pass, and the native OAP dies at boot withNoClassDefFoundErroron a moved class. -
Same-name MAL counter windows: since 11.0.0
CounterWindowis keyed by sample name, not metric name, so the comparison harness runs the fresh and pre-compiled paths back to back with aCounterWindow.INSTANCE.reset()in between. -
Diff the public API of every same-FQCN replacement, not only the constructors: a Lombok
@Getterupstream adds a method the replacement must keep (11.0.0:FilterExpression#getLiteral(), read byAnalyzeronly inside the debug-gated filter probe). The comparison tests never take that branch, so the miss surfaces asNoSuchMethodErroron the ingestion thread the moment an operator starts a session.FilteredRuleDebugCaptureTestcovers the MAL filter probe; add the equivalent when a new probe reads a replaced class. -
Protobuf
JsonFormatneeds reflection metadata: it prints/parses generated messages through the accessor table, which looks getters up withClass.getMethod. The precompiler registers the descriptor closure of every LAL input type plus the OTLP/HTTP JSON receivers'Export*ServiceRequestandLogData(protoJsonRoots→addProtoMessageEntries); when upstream starts JSON-parsing or printing another generated type (git grep "JsonFormat\.(parser|printer)"), extend the root set or the native image answersGenerated message class ... missing method ...(11.1: the ai-agent case's OTLP/JSON log posts exposed the missing OTLP roots). -
LALOutputBuilderimplementations are a hand list: the precompiler resolvesoutputTypeshort names through the SPI at build time, but their reflection entries sit inPrecompiler'sconfigPojoslist. A new builder (11.1:ConversationFilefromai-agent-conversation) goes on that list, and its module must be a precompiler dependency or the LAL rule fails to compile. -
Explicit-input MAL tests go stale when upstream adds a rule to an existing file:
OapTest-style tests (hand-builtbuildInput) fail with "both paths returned EMPTY" on the new rule until its sample family is added to the input; auto-discovery tests pick new rules up by themselves. -
Classpath resources must be globbed into the native image:
oap-graalvm-native'sreachability-metadata.jsonlists the resources the binary embeds. JVM unit tests never notice a missing one; the native OAP dies at boot (11.1:classpath:query-protocol/gen-ai-evaluation-record.graphqls, now covered by thequery-protocol/*.graphqlsglob). When upstream starts reading a new classpath resource (not aconfig/file), add a glob there and boot the native image. -
Armeria instantiates handler-referenced classes reflectively:
@ExceptionHandler,@RequestConverterand@Decoratortargets need constructor metadata. The precompiler'sscanArmeriaHandlerscollects all three (11.1 added@Decoratorfor the AI agent conversation view'sCompressResponse; without it the native OAP dies at boot with "cannot inject the dependency for ..."). A new Armeria annotation that names a class needs the same treatment. -
Jackson response POJOs need reflection metadata: Armeria
HttpResponse.ofJson(pojo)/@ProducesJsonserialize through Jackson, which finds no properties in the native image without metadata and answers HTTP 400 ("No serializer found for class ..."). The precompiler'sscanQueryEntityClassescoversorg.apache.skywalking.oap.query.*.entity.*andorg.apache.skywalking.oap.server.admin.*.response.*(the latter added in 11.1 after the storage suite'sadmin inspectcases exposed it); a POJO outside those packages must be registered by hand. The same holds for request bodies (@ConsumesJson) and for Gson-printed answers, which silently come out as{}instead of failing. 11.1 found three that no e2e case reached:/status/cluster/nodes(coreAddress, HTTP 500),/status/alarm/*(core.alarm.provider.status,{}) and the AWS Firehose receiver (FirehoseReq, HTTP 400 on every post). Audit withgit grep -n "@ProducesJson\|@ConsumesJson\|ofJson(\|GSON.toJson"over the handlers (and@RequestObjectparameters) and boot the native image against each route. -
Stale upstream build output hides missing metadata:
make init-skywalkingdoes not clean, so a resource upstream deleted survives inskywalking/**/target/classesand the installed jars, and the precompiler still scans it. 11.0.0 deletedquery-protocol/ui-configuration.graphqls; a local tree kept it, so the GraphQL type scan kept registeringDashboardSettingandui-managementpassed locally while CI's clean build failed it. Compare the precompiler'sScanned GraphQL types: N matched from M schema typesandGenerated reflect-config.json with N entrieslines with CI's, and clean-install any upstream module whosetarget/classesholds files itssrc/main/resourcesno longer has. -
Native OAP boots faster than upstream assumes: a case whose BanyanDB has no healthcheck (
service_startedonly, e.g. the distroless-pluginsimage) lets the native OAP connect before BanyanDB listens, and it exits onUNAVAILABLE. Wrap the OAP entrypoint inuntil nc -z .... -
Upstream e2e cases that bind-mount
java-test-servicejars: don't build them in CI; every module is published asghcr.io/apache/skywalking/<module>:${SW_E2E_SERVICE_COMMIT}with the jar at/app.jar— run the image directly, or copy the jar out through an init container when an agent image must run it (virtual-genaispring-ai-service,banyandb-trace-samplingtrace-mocker). -
A DSL that creates metrics needs both
MeterSystemreplacements to track upstream's API: the precompiler's build-timeMeterSystem(build-tools/precompiler/...) and the runtime one (server-core-for-graalvm). 11.1 TAL callscreateMetrics→MeterSystem#limitLabels, which neither replacement had; the build-time call fails the precompiler, the runtime one fails boot. TAL creates its metrics through the shared build-timeMeterSystem, so its meter classes land intal-meter-classes.txt, and the runtimeTalDSLreplayscreate+limitLabelsfrom the manifest. -
Retire a replacement when upstream removes the reason for it: 11.1
HttpAlarmCallbackmoved itsHttpClientfrom a static field to a constructor argument; keeping the old lazy-static replacement would have dropped the constructor every hook subclass calls. Diff each changed replacement's upstream source against the reason in its header, not only its API. -
Stream data registered by hand needs constructor metadata:
IWorkerInstanceSetter.put(..., Class)of a non-@Streamclass (11.1: TALPairingFact) is rebuilt byRemoteHandleWorkerwithnewInstance()on the receiving OAP node. The StorageBuilders scan misses it, and only a cluster shows the failure. Add a constructor entry inPrecompiler.generateReflectConfig. -
Jackson YAML/JSON DTOs outside
*.entity.*/*.response.*: the status module's/debugging/*bodies (Debugging*Rsp) are serialized by Jackson; the entity scan covers them since 11.1. A new handler that returns POJOs from another package must be added toscanQueryEntityClasses. -
Upstream default switches can silently empty an e2e case: 11.1 made native OTLP span storage the default, so
otlp-traces(Zipkin API assertions) needsSW_OTEL_TRACE_STORAGE: zipkin. -
Diff upstream
server-starter's dependencies against the distro poms on every sync: a module that ships only SPI implementations, noModuleDefine, is invisible toImmigrationScopeTest.ios-analyzer(iOSSpanListeners, 11.0.0) was never bundled, and the iOS MAL/LAL rules kept the gap hidden until theiose2e case was adopted in 11.1. Anything missing must be policy-excluded (cluster/configuration/storage plugins,runtime-rule) or added. -
TAL rules are user-editable: keep the precompiler pass and the
TalDSL/TALConfigsreplacements free of shipped-rule assumptions.TALPrecompileTest(fixtures) andTALDocScriptsTest(upstream's documented scripts, extracted from the docs and spliced where the practices page says) guard that; when upstream's docs move a snippet or the shipped rule loses an anchor line, the test names it. -
Reflection errors at native image runtime: New classes instantiated via
Class.forName().newInstance()need entries inreflect-config.jsonorreachability-metadata.json -
Config loading failures: New
ModuleConfigsubclasses need config-generator regeneration AND may need@Settersame-FQCN replacement -
Missing config files: Runtime config files (non-DSL) must be in distribution assembly descriptors
-
OAL builder registration: OAL-generated builder classes need constructor entries in
reachability-metadata.json -
Config-generator runs against upstream classpath: Setter checks see upstream classes (no
@Setter), not our for-graalvm replacements — the generator trusts that for-graalvm modules will provide setters
04 同仓库更多 Skills
gh-pull-request
Verify, commit, and push changes on a PR branch. Runs pre-flight checks (compile, checkstyle, license headers) before every push. Also creates the PR if one doesn't exist yet.
ci-e2e-debug
Download and inspect CI e2e test logs from GitHub Actions artifacts. Use when investigating e2e test failures in CI.