Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,34 @@ on:

jobs:

build-vaadin24:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Each Vaadin runtime is exercised on the JDK that matches its baseline.
# Vaadin 14/23/24 run on Java 17; Vaadin 25 is compiled to Java 21 bytecode
# and only loads on Java 21, so it must be built and tested there.
# (maven.compiler.source/target=1.8 sets bytecode level only, not the runtime JDK.)
include:
- vaadin: '14'
java: '17'
- vaadin: '23'
java: '17'
- vaadin: '24'
java: '17'
- vaadin: '25'
java: '21'
name: Vaadin ${{ matrix.vaadin }} (JDK ${{ matrix.java }})
steps:
- uses: actions/checkout@v3
- name: Set up JDK
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: maven
Comment on lines 39 to 45

@coderabbitai coderabbitai Bot Jun 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read-only verification: resolve current supported major tags to immutable SHAs.
# Expected: choose a supported major tag and pin to its commit SHA in workflow YAML.

set -euo pipefail

for repo in actions/checkout actions/setup-java; do
  echo "== $repo =="
  for tag in v4 v5; do
    code=$(curl -s -o /tmp/ref.json -w "%{http_code}" \
      "https://api.github.com/repos/$repo/git/ref/tags/$tag")
    if [ "$code" = "200" ]; then
      sha=$(jq -r '.object.sha' /tmp/ref.json)
      echo "$tag -> $sha"
    fi
  done
done

Repository: FlowingCode/JsonMigrationHelper

Length of output: 311


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the full workflow with line numbers but keep output bounded by showing only relevant sections
FILE=".github/workflows/maven.yml"

echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,220p'

Repository: FlowingCode/JsonMigrationHelper

Length of output: 176


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/maven.yml"
echo "== grep uses/permissions/persist-credentials in $FILE =="
rg -n "uses:\s*actions/(checkout|setup-java)@|permissions:|persist-credentials" "$FILE" || true

echo
echo "== file excerpt around checkout/setup-java =="
awk 'NR>=30 && NR<=80 {printf "%5d  %s\n", NR, $0}' "$FILE"

echo
echo "== full file (bounded) =="
awk '{printf "%5d  %s\n", NR, $0}' "$FILE"

Repository: FlowingCode/JsonMigrationHelper

Length of output: 3264


🌐 Web query:

actions/checkout persist-credentials default true write permissions later steps

💡 Result:

In the actions/checkout action, the persist-credentials input defaults to true [1][2]. When enabled, this setting configures the local Git repository with the authentication token or SSH key used to check out the code [1][3]. This allows subsequent steps in the same job to execute authenticated Git commands (such as git fetch or git push) automatically without requiring further configuration [1][4]. Regarding security and permissions: 1. Credential Security: In newer versions of actions/checkout, credentials are stored in a secure, separate file under $RUNNER_TEMP rather than directly in the.git/config file, which helps prevent accidental credential leakage (for example, if artifacts are published) [1][4][5]. The token is automatically removed during the post-job cleanup phase [1][3]. 2. Access Scope: While setting persist-credentials to true configures Git to use these credentials, it does not fundamentally change the accessibility of the GITHUB_TOKEN within a job [6][5]. The GITHUB_TOKEN is available to all steps within a job by default, regardless of the actions/checkout configuration [6][5]. Consequently, an action could technically access the token through other channels even if persist-credentials is set to false [5]. 3. Opting Out: If you prefer not to have the credentials persisted in the Git configuration for your workflow steps, you can explicitly set persist-credentials: false in your workflow file [1][3]. Top results: [1][3][4][5]

Citations:


🌐 Web query:

actions/setup-java cache: maven required workflow permissions contents actions write

💡 Result:

The actions/setup-java action does not require "contents: write" permissions for caching Maven dependencies [1][2]. The official documentation explicitly recommends setting permissions to "contents: read" to ensure proper functionality [1][3]. The "contents: read" permission is sufficient because the action only needs to read your dependency files (e.g., pom.xml) to calculate the cache key and access the internal GitHub Actions Cache service, which is managed by the workflow environment [1][2][4]. You do not need write access to your repository contents to manage these dependencies [1].

Citations:


Harden third-party GitHub Actions in .github/workflows/maven.yml (pin + disable checkout credential persistence).

  • At lines 39-41, replace mutable/older actions/checkout@v3 and actions/setup-java@v3 with pinned commit SHAs.
  • Set persist-credentials: false for actions/checkout (defaults to true).
  • Add an explicit least-privilege permissions: block (e.g., contents: read) instead of relying on defaults.
Suggested patch
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
+        with:
+          persist-credentials: false
       - name: Set up JDK ${{ matrix.java }}
-        uses: actions/setup-java@v3
+        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654
🧰 Tools
🪛 actionlint (1.7.12)

[error] 39-39: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


[error] 41-41: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 zizmor (1.25.2)

[warning] 39-39: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 39-39: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 41-41: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/maven.yml around lines 39 - 45, Update the GitHub Actions
workflow to harden third-party action usage: replace the mutable
actions/checkout@v3 and actions/setup-java@v3 references with their pinned
commit SHAs (use the specific commit SHA for each action), set actions/checkout
to include persist-credentials: false, and add an explicit least-privilege
permissions block (e.g., permissions: contents: read) at the workflow level to
avoid relying on defaults; locate these changes around the uses of
actions/checkout and actions/setup-java in the maven.yml workflow and apply them
together.

Source: Linters/SAST tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Create an isue about this

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh issue create \
  --repo FlowingCode/JsonMigrationHelper \
  --title "ci: harden GitHub Actions workflow (pin action SHAs, least-privilege permissions)" \
  --assignee "javier-godoy" \
  --body "## Summary

The \`.github/workflows/maven.yml\` workflow uses mutable version tags (\`actions/checkout@v3\`, \`actions/setup-java@v3\`) and relies on default permissions, which poses a supply-chain security risk.

## Findings

1. **Unpinned action references** – \`actions/checkout@v3\` and \`actions/setup-java@v3\` should be pinned to immutable commit SHAs to prevent unexpected changes or supply-chain attacks.
2. **Credential persistence** – \`actions/checkout\` defaults to \`persist-credentials: true\`, which persists the GITHUB_TOKEN in the Git config for the duration of the job. Setting \`persist-credentials: false\` is the safer default for jobs that do not need authenticated Git operations after checkout.
3. **Implicit permissions** – The workflow does not declare an explicit \`permissions:\` block. Adding \`permissions: contents: read\` (or the minimum required) follows the principle of least privilege.

Additionally, \`actionlint\` reports that the v3 runners for both actions are too old to run on GitHub Actions and should be updated.

## References

- Flagged during review of PR `#36` in comment https://github.com/FlowingCode/JsonMigrationHelper/pull/36#discussion_r3388417907
- Requested by `@javier-godoy`
"

Length of output: 1546



@javier-godoy, the issue has been created: https://github.com/FlowingCode/JsonMigrationHelper/issues/38

- name: Build (Vaadin 24)
run: mvn -B package --file pom.xml
# Build only this version's test module plus its upstream (core, tests-shared)
# via -am, so the module compiles and its suite runs on the matching JDK.
- name: Build (Vaadin ${{ matrix.vaadin }})
run: mvn -B package -pl tests-v${{ matrix.vaadin }} -am
Comment on lines 17 to +49

@coderabbitai coderabbitai Bot Jun 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add least-privilege permissions for GITHUB_TOKEN.

This job currently inherits default token scopes. Add explicit read-only permissions to reduce blast radius if any action/step is compromised.

Suggested patch
 name: Java CI with Maven

 on:
   push:
     branches: [ "master" ]
   pull_request:
     branches: [ "master" ]

+permissions:
+  contents: read
+
 jobs:
🧰 Tools
🪛 actionlint (1.7.12)

[error] 39-39: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


[error] 41-41: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 zizmor (1.25.2)

[warning] 39-39: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 19-49: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 39-39: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 41-41: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/maven.yml around lines 17 - 49, The job currently inherits
default GITHUB_TOKEN scopes; add a least-privilege permissions block to the
build job to restrict token access (e.g. add a permissions mapping under the
"build" job such as permissions: contents: read and any other required read-only
scopes like packages: read) so the workflow uses a read-only token instead of
the default full-scoped token.

Source: Linters/SAST tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Report as a new issue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

gh issue create \
  --repo FlowingCode/JsonMigrationHelper \
  --assignee javier-godoy \
  --title "ci: add least-privilege permissions block to GitHub Actions workflow" \
  --body "## Summary

The \`.github/workflows/maven.yml\` build job currently inherits default \`GITHUB_TOKEN\` scopes, which is overly broad. A least-privilege \`permissions\` block should be added at the workflow (or job) level to reduce the blast radius if any action or step is compromised.

## Suggested fix

Add the following block to the workflow (top-level, after the \`on:\` section):

\`\`\`yaml
permissions:
  contents: read
\`\`\`

If the workflow ever needs to read packages from GHPR, also add \`packages: read\`.

## References

- Flagged in PR `#36` — comment: https://github.com/FlowingCode/JsonMigrationHelper/pull/36#discussion_r3388417899
- Detected by [zizmor](https://github.com/woodruffw/zizmor) rule \`excessive-permissions\`

## Requested by

`@javier-godoy`"

Length of output: 1058



@javier-godoy, the issue has been created: FlowingCode/JsonMigrationHelper#37ci: add least-privilege permissions block to GitHub Actions workflow.

309 changes: 309 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.flowingcode.vaadin</groupId>
<artifactId>json-migration-helper</artifactId>
<version>0.9.4-SNAPSHOT</version>
<name>Json Migration Helper</name>
<description>Json Migration Helper for Vaadin Flow</description>
<url>https://www.flowingcode.com/en/open-source/</url>

<!--
This is the published artifact. It is a self-contained POM (no parent) and is always
compiled against Vaadin 14. The compiled classes are designed to run against Vaadin 14,
23, 24 and 25; cross-version behavior is verified by the sibling tests-v* modules, which
run these same classes against each Vaadin runtime.
-->

<properties>
<vaadin.version>14.11.13</vaadin.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<drivers.dir>${project.basedir}/drivers</drivers.dir>
</properties>

<organization>
<name>Flowing Code</name>
<url>https://www.flowingcode.com</url>
</organization>

<inceptionYear>2025</inceptionYear>
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<scm>
<url>https://github.com/FlowingCode/JsonMigrationHelper</url>
<connection>scm:git:git://github.com/FlowingCode/JsonMigrationHelper.git</connection>
<developerConnection>scm:git:ssh://git@github.com:/FlowingCode/JsonMigrationHelper.git</developerConnection>
<tag>master</tag>
</scm>

<developers>
<developer>
<id>flowingcode</id>
<organization>Flowing Code</organization>
<organizationUrl>https://www.flowingcode.com</organizationUrl>
</developer>
</developers>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<type>pom</type>
<scope>import</scope>
<version>${vaadin.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>9.8</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
<version>9.8</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>3.0.0</version>
<optional>true</optional>
</dependency>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.vaadin.external.gwt</groupId>
<artifactId>gwt-elemental</artifactId>
<version>2.8.2.vaadin2</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<tagNameFormat>@{project.version}</tagNameFormat>
<releaseProfiles>release</releaseProfiles>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>patch-elemental-nodes</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.flowingcode.vaadin.jsonmigration.ElementalNodeAsmPostProcessor</mainClass>
<arguments>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/ElementalArrayNode.class</argument>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/ElementalBooleanNode.class</argument>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.class</argument>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.class</argument>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/ElementalObjectNode.class</argument>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/ElementalStringNode.class</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>patch-lit-renderer</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.flowingcode.vaadin.jsonmigration.LitRendererAsmPostProcessor</mainClass>
<arguments>
<argument>${project.build.outputDirectory}/com/flowingcode/vaadin/jsonmigration/LitRendererMigrationExtension.class</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>false</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Vaadin-Package-Version>1</Vaadin-Package-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.3.0</version>
<configuration>
<licenseName>apache_v2</licenseName>
<addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
<excludes>
<exclude>**/main/dev-bundle/**</exclude>
<exclude>**/main/bundles/**</exclude>
<exclude>**/main/frontend/**</exclude>
</excludes>
<extraExtensions>
<tsx>java</tsx>
</extraExtensions>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>directory</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<quiet>true</quiet>
<doclint>none</doclint>
<failOnWarnings>true</failOnWarnings>
<sourceFileExcludes>
<sourceFileExclude>**/ElementalNodeAsmPostProcessor.java</sourceFileExclude>
<sourceFileExclude>**/LitRendererAsmPostProcessor.java</sourceFileExclude>
</sourceFileExcludes>
<links>
<link>https://javadoc.io/doc/com.vaadin/vaadin-platform-javadoc/${vaadin.version}</link>
</links>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<!-- Generated file that shouldn't be included in add-ons -->
<excludes>
<exclude>META-INF/VAADIN/config/flow-build-info.json</exclude>
<exclude>com/flowingcode/vaadin/jsonmigration/ElementalNodeAsmPostProcessor.class</exclude>
<exclude>com/flowingcode/vaadin/jsonmigration/ElementalNodeAsmPostProcessor$*.class</exclude>
<exclude>com/flowingcode/vaadin/jsonmigration/LitRendererAsmPostProcessor.class</exclude>
<exclude>com/flowingcode/vaadin/jsonmigration/LitRendererAsmPostProcessor$*.class</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>gpg</id>
<activation>
<property>
<name>env.MAVEN_GPG_PASSPHRASE</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.7</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.8.0</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Loading
Loading