Repository navigation
ci: port PR validation to GitHub Actions - #9441
Open
vaadin-bot wants to merge 12 commits into
Open
vaadin-bot wants to merge 12 commits into
vaadin-bot wants to merge 12 commits into
Conversation
Ports the two TeamCity builds that validate platform PRs — "Vaadin Platform PR validation" (bt210) and "Vaadin Platform PR validation (gradle)" (bt232) — into one workflow. Both configs are the same 26-step template and only differ in which steps are enabled, so they become the two `suite` entries of a `validate` matrix: the Maven ITs and the Gradle test project run in parallel, each doing its own `mvn install`, the way the two TeamCity builds do on two agents. The shared part (steps 1-11) is the contributor CI-rights and skip-ci guard, BOM generation, `versions:set 99.0-SNAPSHOT` and the production install. The Maven suite then runs step 15's ITs plus step 25's bower tests on branches that still declare `bower-it`; the Gradle suite runs step 17 (`./gradlew clean build`) and step 18 (the mismatched-jna check). Deviations from TeamCity, all commented in the workflow: - The ITs use the Chrome preinstalled on the runner instead of the internal Selenium grid and the Sauce Connect tunnel around it, so they cover one browser where the grid fanned them out over a set. For the Gradle suite this means leaving `hubHostname` unset, which makes TestBench fall back to a local Chrome; passing `runLocally` would not work, as build.gradle forwards only `testsInParallel`, `test.use.hub` and `hubHostname` into the test JVM. - The CI-rights check reads `author_association` from the PR payload rather than calling /collaborators with a bot PAT. - TeamCity holds the TestBench licence in an agent-wide parameter that every step inherits; here it is written once to ~/.vaadin/proKey from secrets.TB_LICENSE, as sbom.yml and pit.yml already do. - Java and node versions are pinned instead of probed, since this workflow lives on one branch. Steps that only exist for older branches (Java 8/11 builds, OSGi) and the disabled TeamCity steps are not ported, nor is the agent housekeeping of steps 3 and 26. Steps 7 and 8, the version consistency test, are left out for now: both are inert in TeamCity today, their node commands being `echo skip:`-ed out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both suites failed in run #34934763370 with SessionNotCreatedException: session not created: Chrome instance exited on every test — 178 Maven ITs and all 10 Gradle ITs. The runner has no X display, and TestBench's local-driver path starts a plain, non-headless Chrome, so the browser exits the moment it launches. TeamCity never hit this: it points both suites at the internal Selenium grid, so no browser has ever started on the build machine itself. Wraps the three browser steps in `xvfb-run -a` and prints the Chrome and xvfb-run locations in the environment info. Xvfb rather than -Dcom.vaadin.testbench.Parameters.headless=true, which TestBench does support, because build.gradle forwards only testsInParallel, test.use.hub, the licence and hubHostname into the test JVM — a system property set on the gradlew command line would never reach TestBench. One mechanism for both suites is worth more here than saving the virtual display. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`build-frontend` fails for vaadin-platform-react-hybrid-test-prod with Failed to generate OpenAPI spec: Failed to find browser-callable classes Hilla discovers endpoints by forking Spring Boot's SpringApplicationAotProcessor and reading the reachability-metadata.json it produces. That process exits 1, and its report says why: SLF4J(W): Class path contains multiple SLF4J providers. SLF4J(W): Found provider [org.slf4j.simple.SimpleServiceProvider] SLF4J(W): Found provider [ch.qos.logback.classic.spi.LogbackServiceProvider] SLF4J(I): Actual provider is of type [org.slf4j.simple.SimpleServiceProvider] Exception in thread "main" java.lang.IllegalStateException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Both modules declare slf4j-simple as their provider but excluded logback-classic from spring-boot-starter-web only, so Logback still arrived through vaadin-spring-boot-starter, hilla-spring-boot-starter and (in the security module) the security and validation starters. With two providers present, which one wins is classpath-order dependent: when slf4j-simple wins, Spring Boot's LogbackLoggingSystem asserts and the AOT processor dies, taking Hilla's endpoint discovery with it. Excludes spring-boot-starter-logging — logback-classic plus the log4j/jul bridges — from every Spring Boot starter in both modules, so slf4j-simple is the only provider regardless of classpath order. This is why TeamCity has been green on commits that fail on GitHub Actions: the two CIs land on opposite sides of that election, so the bug is latent on TeamCity rather than absent. Neither module has a simplelogger.properties or logback.xml, so no logging config changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ZheSun88
force-pushed
the
ci/pr-validation-github-actions
branch
from
September 15, 2026 07:37
cf058a2 to
1e68129
Compare
Contributor
Dependencies Report
|
The runs carried a deprecation annotation for every pinned action: checkout, setup-java, setup-node, upload-artifact and setup-maven all targeted Node 20 and were being forced onto Node 24. Two of the five needed more than a v5 pin, so each is on its first Node 24 release rather than uniformly v5: actions/checkout v4 -> v5 (node24) actions/setup-node v4 -> v5 (node24) actions/setup-java v4 -> v5 (node24) actions/upload-artifact v4 -> v6 (v5 is still node20) stCarolas/setup-maven v5 -> v5.1 (v5 is still node20; pit.yml uses v5.1) upload-artifact v6 keeps every input this workflow uses. Newer majors exist (checkout/upload-artifact/setup-node are at v7, setup-java at v6); this stops at the first release that clears the warning rather than taking those breaking changes on in a CI-migration PR. Also gives vaadin-platform-hybrid-test the same logging exclusion as the react-hybrid modules. It has one Spring Boot starter and is not in this build's reactor, so it is not broken today, but it carries the same logback-classic-only exclusion next to an slf4j-simple dependency. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1e68129 and 3e637ba kept slf4j-simple as the SLF4J provider and excluded spring-boot-starter-logging from every Spring Boot starter, so Logback could not win the provider election and break the AOT processor behind Hilla's endpoint discovery. That needs one exclusion per starter, because a Maven exclusion only cuts the path it is declared on, and any starter added later silently brings Logback back. Nothing needs slf4j-simple: none of the modules has a simplelogger.properties, and the dependency was copied in with the modules. Dropping it leaves Logback as the only provider, which is what Spring Boot's LoggingSystem expects, and removes every exclusion. Verified with -Pproduction package on all three modules: build-frontend passes, and the security module's UserInfoService endpoint is still generated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bumps NODE_VERSION from 24.21.0 to 26.10.0, the latest 26.x release. TeamCity still installs Node 24, so this workflow now runs the build on a newer Node than TeamCity does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The check lived inline in the build, which means it cannot be changed in a pull request, reviewed, or run by hand, and every branch runs whatever the build configuration says rather than what the branch declares. The script does what the two build steps did together: it reads the versions out of versions.json, where the first step ran jq, and then runs the comparisons the second step wrote out to a file. A version may still be passed in the environment, so the build can keep setting them while it is moved over. Only the branch a pull request targets and the token are read from the environment now, as neither can be worked out from the sources.
versions.json no longer lists the web components one by one, so versions.core.button.jsVersion is undefined and the check compared flow-components against the string 'null'. @vaadin/react-components is released in lockstep with the web components, so its jsVersion is the web component version now. That makes the React-components-versus-web-components comparison compare the version with itself, so it is removed, along with the rcVersion override that only fed it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on top
The two suites each ran the full preparation and `mvn install`, the way
TeamCity's two builds do on two agents. Now a `build` job installs the
platform modules once and publishes everything under com/vaadin and
dev/hilla, which after the purge at its start is exactly this build: the
modules it installed and the Flow, Hilla and component snapshots it
resolved. Four jobs run in parallel on top of it:
- npm-tests: vaadin-platform-test and the reload benchmark (step 15),
plus the bower tests on branches that have them (step 25)
- react-tests: the two react-hybrid modules (step 15)
- javadocs: the release's -Pjavadocs build of vaadin-platform-javadoc,
which PR validation did not cover before
- gradle-tests: the Gradle test project and the jna check (steps 17/18)
The test jobs pass -DskipPlatform, so only the test modules are built
and the platform modules come from what `build` installed. `build`
itself drops the npm-it, react-hybrid and hybrid-security profiles,
which only add test modules.
The shared preparation moves into a local composite action,
prepare-build, which every build job runs: the BOMs and the javadoc pom
are generated and git-ignored, so each job has to generate them and
set the reactor version the same way before using the artifacts.
Steps 7 and 8, the version consistency test, come back as their own
job running scripts/versionConsistency.js. It needs no Maven build, so
it runs beside `build` and a mismatch does not hold up the tests.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The step piped `mvn -U help:all-profiles` into `grep -q ... && bower=true || bower=false`, so a Maven failure read as "no bower profile", the step passed, and Maven's output went to grep instead of the log. When maven.vaadin.com/vaadin-prereleases stopped serving com/vaadin, this was the step that failed to resolve flow-bom, yet the error only showed up in the versions:set step after it, as a failure cached "during a previous attempt". help:all-profiles reads every module, BOM imports included, so it is the first step to hit an unresolvable artifact. Its output now goes to a file: the step fails and prints it when Maven fails, and greps it otherwise. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The pack step collected its directories with `ls -d com/vaadin dev/hilla`, and ls exits 2 when any of its paths is missing. Hilla is published under com.vaadin now, so dev/hilla is never there, and under `bash -e` the step died on that exit status before tar ran, with no output. Each directory is now tested with `if [ -d ]` and packed when present. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the two TeamCity builds that validate platform PRs — "Vaadin Platform PR validation" (bt210) and "Vaadin Platform PR validation (gradle)" (bt232) — into a single workflow,
.github/workflows/pr-validation.yml.Both TeamCity configs are the same 26-step template and differ only in which steps are enabled, so they become the two
suiteentries of avalidatematrix. The Maven ITs and the Gradle test project run in parallel, each doing its ownmvn install, the way the two TeamCity builds do on two agents.guardversions:set, install)validate, both suitesvalidate,suite: mavenvalidate,suite: gradleEvery step is mapped in a comment block at the top of the file, including the ones deliberately dropped.
Deviations from TeamCity
All marked
DEVIATIONin the workflow:hubHostnameunset, which makes TestBench fall back to a local Chrome — passingrunLocallywould not work, sincebuild.gradleforwards onlytestsInParallel,test.use.hubandhubHostnameinto the test JVM.author_associationfrom the PR payload instead of calling/collaboratorswith a bot PAT.secrets.TB_LICENSEwritten to~/.vaadin/proKey, assbom.ymlandpit.ymlalready do. TeamCity keeps it in an agent-wide parameter that every step inherits.Left out for now
Steps 7 and 8, the version consistency test. Both are inert in TeamCity today — build #7711 has their node commands
echo skip:-ed out — so porting them would only report on a state nobody is acting on. They want a job of their own whenever that changes, since they need neither the Maven build nor its local repository.Notes for review
mvn installcosts runner minutes, not wall clock: the two suites install concurrently. Sharing it via a cached~/.m2would make PR feedback slower, because the Maven ITs also reuse the warmtarget/andnode_modules/that the install leaves in the working tree.🤖 Generated with Claude Code