Skip to content

Commit

Permalink
kie-issues#1352: Enforce reproducible build on kie-tools
Browse files Browse the repository at this point in the history
  • Loading branch information
pefernan committed Jun 27, 2024
1 parent 366da81 commit f565c72
Show file tree
Hide file tree
Showing 26 changed files with 227 additions and 16 deletions.
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,79 @@ Bootstrapping installs the necessary dependencies for each package.
---

## Reproducible Builds for _maven-based_ packages

It is mandatory that any _maven-based_ that publishes artifacts runs [Reproducible Builds](https://reproducible-builds.org/)
to build it's artifacts, in this case in our `build:prod` scripts.

> IMPORTANT: the current version of the `maven-artifact-plugin` (3.4.1) used in `kie-tools` bans the `maven-flatten-plugin` that
> we use to generate deployable artifacts using the dynamic `${revision}` variable. You can check the full list of banned
> plugins [here](https://maven.apache.org/plugins-archives/maven-artifact-plugin-3.4.1/plugin-issues.html).
> The issue that caused the ban [flatten-maven-plugin/issues/256](https://github.com/mojohaus/flatten-maven-plugin/issues/256) was created
> due to a problem in `maven` (v3.8.1 ~ v3.8.2) and isn't a problem of the `maven-flatten-plugin` itself and did not require
> any action in the plugin. Actually in later versions of the `maven-artifact-plugin` the ban got revoked.
> Having this in mind, and due to the fact that `kie-tools` requires newer `maven` versions, our _Reproducible Builds_ require
> temporarily overriding the list of banned plugins, until we upgrade to a newer `maven-artifact-plugin` version.
To correctly enable _Reproducible Builds_ package follow the steps:

- Make sure the `package.json` depends on `@kie-tools/maven-base`
- Make the package `pom.xml` has `kie-tools-maven-base` as a parent and declares the `project.build.outputTimestamp` property like:

```xml
<project>
<parent>
<groupId>org.kie</groupId>
<artifactId>kie-tools-maven-base</artifactId>
<version>${revision}</version>
<relativePath>./node_modules/@kie-tools/maven-base/pom.xml</relativePath>
</parent>
...
<properties>
<project.build.outputTimestamp>2024-01-12T00:00:00Z</project.build.outputTimestamp>
</properties>
...
<projec>
```

- `@kie-tools/maven-base` provides a `reproducible` `maven` profile that can be enabled by using the `-Dreproducible`
argument in `build:prod` scripts, like:

```json
{
"scripts": {
"build:prod": "pnpm lint && run-script-os",
"build:prod:darwin:linux": "mvn clean deploy [...other maven options...] -Dreproducible",
"build:prod:win32": "pnpm powershell \"mvn clean deploy [...other maven options...] `-Dreproducible\"",
"install": "node install.js"
}
}
```

- Make your `env/index.js` import the `@kie-tools/maven-base` build env:

```javascript
const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");

module.exports = composeEnv([require("@kie-tools/root-env/env"), require("@kie-tools/maven-base/env")], {
vars: varsWithName({}),
get env() {},
});
```

- Modify the package `install.js` to configure the `mvn.config` file to override the list of `plugin-issues` plugins setting the `check.plugin-issues` flag.

```javascript
const buildEnv = require("./env");
const { setup } = require("@kie-tools/maven-config-setup-helper");
setup(`
-Drevision=${buildEnv.env.yourEnv.version}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);
```

---

## Applications

The Apache KIE Tools project contains several applications. To develop each one of them individually, refer to the instructions below.
Expand Down
2 changes: 1 addition & 1 deletion packages/extended-services-java/env/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const { getOrDefault, varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");

module.exports = composeEnv([require("@kie-tools/root-env/env")], {
module.exports = composeEnv([require("@kie-tools/root-env/env"), require("@kie-tools/maven-base/env")], {
vars: varsWithName({
EXTENDED_SERVICES_JAVA__host: {
default: "0.0.0.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/extended-services-java/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
const buildEnv = require("./env");
const { setup } = require("@kie-tools/maven-config-setup-helper");

console.log(buildEnv.env.mavenBase);

setup(`
-Drevision=${buildEnv.env.extendedServicesJava.version}
-Dquarkus.http.port=${buildEnv.env.extendedServicesJava.port}
-Dquarkus.http.host=${buildEnv.env.extendedServicesJava.host}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);
4 changes: 2 additions & 2 deletions packages/extended-services-java/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"build:dev:linux:darwin": "mvn clean install -DskipTests -DskipITs && pnpm dist",
"build:dev:win32": "pnpm powershell \"mvn clean install `-DskipTests `-DskipITs\" && pnpm dist",
"build:prod": "run-script-os",
"build:prod:linux:darwin": "mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -DskipITs=$(build-env endToEndTests.run --not) && pnpm dist",
"build:prod:win32": "pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-DskipITs=$(build-env endToEndTests.run --not)\" && pnpm dist",
"build:prod:linux:darwin": "mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -DskipITs=$(build-env endToEndTests.run --not) -Dreproducible && pnpm dist",
"build:prod:win32": "pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-DskipITs=$(build-env endToEndTests.run --not) `-Dreproducible\" && pnpm dist",
"copy:app": "run-script-os",
"copy:app:linux:darwin": "copyfiles -u 1 \"target/quarkus-app/**/*\" dist/",
"copy:app:win32": "copyfiles -u 1 \"target/quarkus-app/**\" dist/",
Expand Down
1 change: 1 addition & 0 deletions packages/extended-services-java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
</licenses>

<properties>
<project.build.outputTimestamp>2024-01-12T00:00:00Z</project.build.outputTimestamp>
<java.module.name>org.kie.tools.extended-services</java.module.name>
</properties>

Expand Down
1 change: 1 addition & 0 deletions packages/jbpm-quarkus-devui/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ const { setup } = require("@kie-tools/maven-config-setup-helper");

setup(`
-Drevision=${buildEnv.env.jbpmQuarkusDevuiExtension.version}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);
4 changes: 2 additions & 2 deletions packages/jbpm-quarkus-devui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"build:dev:darwin:linux": "mvn clean install -DskipTests",
"build:dev:win32": "pnpm powershell \"mvn clean install -DskipTests \"",
"build:prod": "pnpm lint && run-script-os",
"build:prod:darwin:linux": "mvn clean deploy -DdeployAtEnd -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -Dmaven.deploy.skip=$(build-env maven.deploy.skip)",
"build:prod:win32": "pnpm powershell \"mvn clean deploy `-DdeployAtEnd `-DskipTests `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-Dmaven.deploy.skip=$(build-env maven.deploy.skip)\"",
"build:prod:darwin:linux": "mvn clean deploy -DdeployAtEnd -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -Dmaven.deploy.skip=$(build-env maven.deploy.skip) -Dreproducible",
"build:prod:win32": "pnpm powershell \"mvn clean deploy `-DdeployAtEnd `-DskipTests `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-Dmaven.deploy.skip=$(build-env maven.deploy.skip) `-Dreproducible\"",
"install": "node install.js",
"lint": "echo 'Linting'",
"powershell": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command",
Expand Down
1 change: 1 addition & 0 deletions packages/jbpm-quarkus-devui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<packaging>pom</packaging>

<properties>
<project.build.outputTimestamp>2024-01-12T00:00:00Z</project.build.outputTimestamp>
<java.module.name>org.jbpm.quarkus.dev.ui</java.module.name>
</properties>

Expand Down
4 changes: 4 additions & 0 deletions packages/maven-base/env/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

const path = require("path");
const { varsWithName, composeEnv, getOrDefault } = require("@kie-tools-scripts/build-env");

module.exports = composeEnv([require("@kie-tools/root-env/env")], {
Expand All @@ -30,6 +31,9 @@ module.exports = composeEnv([require("@kie-tools/root-env/env")], {
return {
mavenBase: {
version: require("../package.json").version,
reproducibleBuildIssues: path.resolve(
"./node_modules/@kie-tools/maven-base/not-reproducible-plugins.properties"
),
},
maven: {
deploy: {
Expand Down
81 changes: 81 additions & 0 deletions packages/maven-base/not-reproducible-plugins.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# list of plugins that did not produce reproducible output in the past, with minimum reproducible version

# default org.apache.maven.plugins groupId
maven-archetype-plugin=3.2.0
# https://issues.apache.org/jira/browse/ARCHETYPE-590
maven-assembly-plugin=3.2.0
# https://issues.apache.org/jira/browse/MASSEMBLY-921
maven-jar-plugin=3.2.0
# https://issues.apache.org/jira/browse/MJAR-263
# https://issues.apache.org/jira/browse/MJAR-275
maven-ejb-plugin=3.1.0
# https://issues.apache.org/jira/browse/MEJB-128
maven-plugin-plugin=3.5.1
# https://issues.apache.org/jira/browse/MPLUGIN-326
maven-remote-resources-plugin=1.7.0
# https://issues.apache.org/jira/browse/MRRESOURCES-114
maven-shade-plugin=3.2.3
# https://issues.apache.org/jira/browse/MSHADE-352
# https://issues.apache.org/jira/browse/MSHADE-420 for some shaded jars, timezone counts: does not really make the build not reproducible, just harder
maven-source-plugin=3.2.1
# https://issues.apache.org/jira/browse/MSOURCES-123
maven-war-plugin=3.3.1
# https://issues.apache.org/jira/browse/MWAR-432
maven-ear-plugin=3.1.0
# https://issues.apache.org/jira/browse/MEAR-280
maven-rar-plugin=3.0.0
# https://issues.apache.org/jira/browse/MRAR-86
maven-acr-plugin=3.2.0
# https://issues.apache.org/jira/browse/MACR-53

# plugin-specific groupId

org.antlr+antlr3-maven-plugin=fail:https://github.com/antlr/antlr3/pull/195

org.apache.felix+maven-bundle-plugin=5.1.5
# https://issues.apache.org/jira/browse/FELIX-6495
# https://issues.apache.org/jira/browse/FELIX-6496
org.apache.karaf.tooling+karaf-maven-plugin=4.3.7
# https://issues.apache.org/jira/browse/KARAF-7367
org.apache.nifi+nifi-nar-maven-plugin=1.3.4
# https://issues.apache.org/jira/browse/NIFI-9857
org.apache.servicemix.tooling+depends-maven-plugin=fail:https://issues.apache.org/jira/browse/SM-5021

org.codehaus.plexus+plexus-component-metadata=2.1.0
# https://github.com/codehaus-plexus/plexus-containers/issues/27
org.codehaus.mojo+jaxb2-maven-plugin=fail:https://github.com/mojohaus/jaxb2-maven-plugin
#
org.codehaus.mojo+properties-maven-plugin=1.1.0

# DISABLING SINCE https://github.com/mojohaus/flatten-maven-plugin/issues/256 is completed with no change required
# https://github.com/mojohaus/properties-maven-plugin/pull/75
# org.codehaus.mojo+flatten-maven-plugin=fail:https://github.com/mojohaus/flatten-maven-plugin/issues/256

org.eclipse.sisu+sisu-maven-plugin=0.3.4
# https://github.com/eclipse/sisu.inject/pull/5
org.eclipse.jetty+jetty-jspc-maven-plugin=fail:https://github.com/eclipse/jetty.project/

org.jboss.jandex+jandex-maven-plugin=fail:https://github.com/wildfly/jandex-maven-plugin/pull/35

org.springframework.boot+spring-boot-maven-plugin=2.7.1
# https://github.com/spring-projects/spring-boot/issues/21005

org.vafer+jdeb=1.10
# https://github.com/tcurdt/jdeb/pull/363
39 changes: 39 additions & 0 deletions packages/maven-base/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,43 @@
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>reproducible-build</id>
<activation>
<property>
<name>reproducible</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-artifact-plugin</artifactId>
<executions>
<execution>
<id>check-buildplan</id>
<goals>
<goal>check-buildplan</goal>
</goals>
<!-- The execution's configuration is part of the pluginManagement. This piece here only makes sure the
execution is enabled (by specifying a phase) for full profile builds. -->
<phase>validate</phase>
</execution>
<execution>
<id>compare</id>
<goals>
<goal>compare</goal>
</goals>
<!-- The execution's configuration is part of the pluginManagement. This piece here only makes sure the
execution is enabled (by specifying a phase) for full profile builds. -->
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
1 change: 1 addition & 0 deletions packages/sonataflow-quarkus-devui/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ const { setup } = require("@kie-tools/maven-config-setup-helper");

setup(`
-Drevision=${buildEnv.env.sonataflowQuarkusDevuiExtension.version}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);
4 changes: 2 additions & 2 deletions packages/sonataflow-quarkus-devui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"build:dev:darwin:linux": "mvn clean install -DskipTests",
"build:dev:win32": "pnpm powershell \"mvn clean install -DskipTests \"",
"build:prod": "pnpm lint && run-script-os",
"build:prod:darwin:linux": "mvn clean deploy -DdeployAtEnd -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -Dmaven.deploy.skip=$(build-env maven.deploy.skip)",
"build:prod:win32": "pnpm powershell \"mvn clean deploy `-DdeployAtEnd `-DskipTests `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-Dmaven.deploy.skip=$(build-env maven.deploy.skip)\"",
"build:prod:darwin:linux": "mvn clean deploy -DdeployAtEnd -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -Dmaven.deploy.skip=$(build-env maven.deploy.skip) -Dreproducible",
"build:prod:win32": "pnpm powershell \"mvn clean deploy `-DdeployAtEnd `-DskipTests `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-Dmaven.deploy.skip=$(build-env maven.deploy.skip) `-Dreproducible\"",
"install": "node install.js",
"lint": "echo 'Linting'",
"powershell": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command",
Expand Down
1 change: 1 addition & 0 deletions packages/sonataflow-quarkus-devui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<packaging>pom</packaging>

<properties>
<project.build.outputTimestamp>2024-01-12T00:00:00Z</project.build.outputTimestamp>
<java.module.name>org.kie.kogito.quarkus.swf.dev.ui</java.module.name>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");

module.exports = composeEnv([require("@kie-tools/root-env/env")], {
module.exports = composeEnv([require("@kie-tools/root-env/env"), require("@kie-tools/maven-base/env")], {
vars: varsWithName({}),
get env() {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const version = buildEnv.env.vscodeJavaCodeCompletionExtensionPlugin.version;

setup(`
-Drevision=${version}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);

console.info("[vscode-java-code-completion-extension-plugin-install] Updating manifest file...");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"scripts": {
"build:dev": "mvn clean install -DskipTests",
"build:prod": "pnpm lint && run-script-os",
"build:prod:darwin:linux": "mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)",
"build:prod:win32": "pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)\"",
"build:prod:darwin:linux": "mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -Dreproducible",
"build:prod:win32": "pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-Dreproducible\"",
"install": "node install.js && pnpm install:mvnw",
"install:mvnw": "mvn -e org.apache.maven.plugins:maven-wrapper-plugin:3.3.0:wrapper -f ./",
"lint": "echo 'Linting'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
</modules>

<properties>
<project.build.outputTimestamp>2024-01-12T00:00:00Z</project.build.outputTimestamp>
<tycho.version>3.0.5</tycho.version>
<tycho.extras.version>${tycho.version}</tycho.extras.version>
<tycho.scmUrl>scm:git:https://github.com/apache/incubator-kie-tools.git</tycho.scmUrl>
Expand Down
2 changes: 1 addition & 1 deletion packages/yard-model/env/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");

module.exports = composeEnv([require("@kie-tools/root-env/env")], {
module.exports = composeEnv([require("@kie-tools/root-env/env"), require("@kie-tools/maven-base/env")], {
vars: varsWithName({}),
get env() {
return {
Expand Down
1 change: 1 addition & 0 deletions packages/yard-model/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ const { setup } = require("@kie-tools/maven-config-setup-helper");

setup(`
-Drevision=${buildEnv.env.yardModel.version}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);
4 changes: 2 additions & 2 deletions packages/yard-model/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"build:dev:darwin:linux": "mvn clean install -DskipTests",
"build:dev:win32": "pnpm powershell \"mvn clean install `-DskipTests\"",
"build:prod": "pnpm lint && run-script-os",
"build:prod:darwin:linux": "mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)",
"build:prod:win32": "pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)\"",
"build:prod:darwin:linux": "mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) -Dreproducible",
"build:prod:win32": "pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures) `-Dreproducible\"",
"install": "node install.js && pnpm install:mvnw",
"install:mvnw": "run-script-os",
"install:mvnw:darwin:linux": "mvn -e org.apache.maven.plugins:maven-wrapper-plugin:3.3.0:wrapper",
Expand Down
1 change: 1 addition & 0 deletions packages/yard-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
</licenses>

<properties>
<project.build.outputTimestamp>2024-01-12T00:00:00Z</project.build.outputTimestamp>
<yaml.mapper>0.4</yaml.mapper>
<helper.maven.plugin>3.2.0</helper.maven.plugin>
<maven.compiler.source>11</maven.compiler.source>
Expand Down
2 changes: 1 addition & 1 deletion packages/yard-validator-worker/env/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");

module.exports = composeEnv([require("@kie-tools/root-env/env")], {
module.exports = composeEnv([require("@kie-tools/root-env/env"), require("@kie-tools/maven-base/env")], {
vars: varsWithName({}),
get env() {
return {
Expand Down
1 change: 1 addition & 0 deletions packages/yard-validator-worker/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ const { setup } = require("@kie-tools/maven-config-setup-helper");

setup(`
-Drevision=${buildEnv.env.yardValidator.version}
-Dcheck.plugin-issues=${buildEnv.env.mavenBase.reproducibleBuildIssues}
`);
Loading

0 comments on commit f565c72

Please sign in to comment.