Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup environments #89

Merged
merged 7 commits into from
Aug 30, 2023
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: 29 additions & 0 deletions .ci/environments/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Environments CI scripts

This folder contains update scripts which would be called for a specific environments.

## Updating branch for an environment

The `.ci/environments/update.sh` script is responsible to execute the update/migration.

It expect at least one parameter, namely the "environment", corresponding to the folder which will be "executed" (e.g. *quarkus-3*, *quarkus-main*, etc) and optionally some more which would be transmitted to the `before.sh` and/or `after.sh` scripts.

Please look at the specific environment README file for more information about the needed parameters for the before and after scripts.

### Execute script

To execute migration from an environment, ***WITHOUT*** extra parameters:

`.ci/environments/update.sh <environment>`

To execute migration from an environment ***WITH*** extra paramerers:

`.ci/environments/update.sh <environment> <extra_param1> <extra_param2>`

### What happens ?

When called, the update script will (in order and if exists):

1. call `<environment>/before.sh` script with extra parameters
2. apply patches from the `<environment>/patches` folder in alphanumeric order
3. call `<environment>/before.sh` script with extra parameters
13 changes: 13 additions & 0 deletions .ci/environments/common/update_quarkus.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail

mvn_cmd="mvn ${BUILD_MVN_OPTS:-} ${BUILD_MVN_OPTS_QUARKUS_UPDATE:-}"

source <(curl -s https://raw.githubusercontent.com/kiegroup/kogito-pipelines/main/dsl/seed/scripts/install_quarkus.sh)

echo "Update project with Quarkus version ${QUARKUS_VERSION}"

set -x

# Update with Quarkus version and commit
# Nothing to do here
81 changes: 81 additions & 0 deletions .ci/environments/quarkus-3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# quarkus-3 environment scripts

This folder contains specific script(s)/patch(es) for the Quarkus 3 migration.

**Here is the command:**

```bash
.ci/environments/update.sh quarkus-3
```

Steps of the basic execution:

- Execute `before.sh` script
In the basic execution, this script will skip the rewrite commands, which is taking a lot of time to perform.
If you want to perform the rewrite or update the "before.sh" patch, please see next sections.
- Apply all patches from `patches` folder

## Full execution

**Command:**

```bash
.ci/environments/update.sh quarkus-3 rewrite
```

Steps of the full execution:

- Execute the rewrite execution
- Synchronize the libraries' version with Quarkus BOM
- Store the changes from previous steps into the `patches/001_before_sh.patch` file
- Apply patches from `patches` folder

## Patches information

1. the `0001_before_sh.patch` is generated executing the `before.sh` script; it then contains all the `openrewrite` migration and the synchronization of libraries with quarkus ones (see next section)
2. all other patches have been made manually
3. if some other modifications are needed, they should be created as `patch`, following numerations
4. if some patch does not apply anymore, it has to be recreated manually; in case of the first one, it means to execute the `before.sh` script again

## How to recreate the `001_before_sh.patch` file ?

The `001_before_sh.patch` file contains all changes from a rewrite execution.
In case of a full execution, this file will be overriden with the new changes.

You can also regenerate that file without having to run the full quarkus-3 environment migration.
To do so, just run:

```bash
.ci/environments/quarkus-3/before.sh rewrite
```

## Recipe files

There are 3 recipe files:

- `project-recipe.yml` is the recipe file to update in case you need a new recipe
- `quarkus3-base-recipe.yml` is the base recipe setup by Quarkus team in https://github.com/quarkusio/quarkus-updates. You should not modify it !
- `quarkus3.yml` is the final recipe file and is a compute of the previous 2 files, plus some processing.
See also comments in [Jbang script](jbang/CreateKieQuarkusProjectMigrationRecipe.java) for more details on the generation.

### How to reset the quarkus3.yaml recipe file ?

The `before.sh` script should handle the reset of the `quarkus3.yml` recipe file when executed with `rewrite` command.

In case you want to do manually, just run:

```bash
cd .ci/environments/quarkus-3 && curl -Ls https://sh.jbang.dev | bash -s - jbang/CreateKieQuarkusProjectMigrationRecipe.java; cd -
```

### How to update the Quarkus version ?

If you are setting a new Quarkus version:

1. Update `quarkus-devtools-common` version in `jbang/CreateKieQuarkusProjectMigrationRecipe.java` file
2. Update `QUARKUS_VERSION` in `jbang/CreateKieQuarkusProjectMigrationRecipe.java` file
3. Update `QUARKUS_UPDATES_BASE_URL` with the corresponding released version of https://github.com/quarkusio/quarkus-updates recipe file
4. Run the jbang script to update the `quarkus3.yml` file
```bash
cd .ci/environments/quarkus-3 && curl -Ls https://sh.jbang.dev | bash -s - jbang/CreateKieQuarkusProjectMigrationRecipe.java true; cd -
```
15 changes: 15 additions & 0 deletions .ci/environments/quarkus-3/after.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
set -euo pipefail

script_dir_path=$(cd `dirname "${BASH_SOURCE[0]}"`; pwd -P)
mvn_cmd="mvn ${BUILD_MVN_OPTS:-} ${BUILD_MVN_OPTS_QUARKUS_UPDATE:-}"

# Retrieve current Maven project version
project_version=$(mvn -q -Dexpression=project.version -DforceStdout help:evaluate)
# New version is based on current project version and increment the Major => (M+1).m.y
new_version=$(echo ${project_version} | awk -F. -v OFS=. '{$1 += 1 ; print}')

# Change version
set -x
${mvn_cmd} -fae -N -e versions:update-parent -Dfull -DparentVersion="[${new_version}]" -DallowSnapshots=true -DgenerateBackupPoms=false
${mvn_cmd} -fae -N -e versions:update-child-modules -Dfull -DallowSnapshots=true -DgenerateBackupPoms=false
89 changes: 89 additions & 0 deletions .ci/environments/quarkus-3/before.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash
set -euo pipefail

script_dir_path=$(cd `dirname "${BASH_SOURCE[0]}"`; pwd -P)
mvn_cmd="mvn ${BUILD_MVN_OPTS:-} ${BUILD_MVN_OPTS_QUARKUS_UPDATE:-}"
ci="${CI:-false}"

rewrite_plugin_version=4.43.0
quarkus_version=${QUARKUS_VERSION:-3.0.0.Final}

quarkus_recipe_file="${script_dir_path}/quarkus3.yml"
patch_file="${script_dir_path}"/patches/0001_before_sh.patch

if [ "${ci}" = "true" ]; then
# In CI we need the main branch snapshot artifacts deployed locally
set -x
${mvn_cmd} clean install -Dquickly
set +x
fi

rewrite=${1:-'none'}
behavior=${2:-'none'}
echo "rewrite "${rewrite}
if [ "rewrite" != ${rewrite} ]; then
echo "No rewrite to be done. Exited"
exit 0
fi

export MAVEN_OPTS="-Xmx16192m"

echo "Update project with Quarkus version ${quarkus_version}"

set -x

project_version=$(${mvn_cmd} -q -Dexpression=project.version -DforceStdout help:evaluate)

# Regenerate quarkus3 recipe
cd ${script_dir_path}
curl -Ls https://sh.jbang.dev | \
bash -s - jbang/CreateKieQuarkusProjectMigrationRecipe.java \
-v version.io.quarkus=${quarkus_version}
cd -

# Launch Quarkus 3 Openrewrite
${mvn_cmd} org.openrewrite.maven:rewrite-maven-plugin:${rewrite_plugin_version}:run \
-Drewrite.configLocation="${quarkus_recipe_file}" \
-DactiveRecipes=io.quarkus.openrewrite.Quarkus \
-Drewrite.recipeArtifactCoordinates=org.kie:jpmml-migration-recipe:"${project_version}" \
-Denforcer.skip \
-fae \
-Dexclusions=**/target \
-DplainTextMasks=**/kmodule.xml

# Update dependencies with Quarkus 3 bom
# ${mvn_cmd} \
# -pl :drools-build-parent \
# -DremotePom=io.quarkus:quarkus-bom:${quarkus_version} \
# -DupdatePropertyVersions=true \
# -DupdateDependencies=true \
# -DgenerateBackupPoms=false \
# versions:compare-dependencies

# Create the `patches/0001_before_sh.patch` file
git add .
git reset "${quarkus_recipe_file}" # Do not include recipe file
git diff --cached > "${patch_file}"
git reset

# Commit the change on patch
if [ "$(git status --porcelain ${patch_file})" != '' ]; then
if [ "$(git status --porcelain ${quarkus_recipe_file})" != '' ]; then
git add "${quarkus_recipe_file}" # We suppose that if the recipe has changed, the patch file as well
fi
git add "${patch_file}"
git commit -m '[Quarkus 3] Updated rewrite data'

git reset --hard
if [ "${behavior}" = 'push_changes' ]; then
git_remote="${GIT_REMOTE:-origin}"
branch=$(git branch --show-current)
echo "Pushing changes to ${git_remote}/${branch} after rebase "
git fetch ${git_remote}
git rebase ${git_remote}/${branch}
git push ${git_remote} ${branch}
fi
fi

# Reset all other changes as they will be applied next by the `patches/0001_before_sh.patch` file
git reset --hard
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.commons.io.IOUtils;

import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.update.QuarkusUpdateRecipe;
import io.quarkus.devtools.project.update.QuarkusUpdateRecipeIO;
import io.quarkus.devtools.project.update.operations.UpdatePropertyOperation;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

///usr/bin/env jbang "$0" "$@" ; exit $?
// Version to be changed when needed
//DEPS io.quarkus:quarkus-devtools-common:3.0.0.Final
//DEPS info.picocli:picocli:4.5.0

/*
* This script will generate the final `quarkus3.yml` file based on:
* - quarkus recipe file (see `QUARKUS_UPDATES_BASE_URL` constant)
* - local project-recipe.yaml => Specific project repository rules
*
* We use a lot of managed dependencies, it concatenates both files but it also add some new rules:
* In the Quarkus recipe, the dependencies rules are modified only for direct dependencies but not for managed dependencies.
* So the script adds a new step:
* - Reads all modified direct dependencies from the Quarkus recipe
* - Generates one managed dependency rule for each of them
*/
@Command(name = "migrationrecipecli", mixinStandardHelpOptions = true, version = "migrationrecipecli 0.1",
description = "migrationrecipecli to create the Q3 migration recipe for a project")
class CreateKieQuarkusProjectMigrationRecipeCli implements Callable<Integer> {

@Option(names={ "-d", "--download-quarkus-recipe"}, description = "Download quarkus update recipe for final recipe generation")
private boolean downloadQuarkusRecipe = false;

@Option(names={ "-v", "--property-version"}, description = "(multi). Add a dynamic property version to the final recipe")
private Map<String, String> versionProperties = new HashMap<>();

static final String QUARKUS_UPDATES_BASE_URL = "https://raw.githubusercontent.com/quarkusio/quarkus-updates/1.0.0/recipes/src/main/resources/quarkus-updates/core/3alpha.yaml";

static final Path quarkus3DownloadedRecipePath = Paths.get("quarkus3-base-recipe.yml");
static final Path quarkus3GeneratedRecipePath = Paths.get("quarkus3.yml");
static final Path projectBaseRecipePath = Paths.get("project-recipe.yml");

@Override
public Integer call() throws Exception { // your business logic goes here...
if (downloadQuarkusRecipe) {
System.out.println("Downloading recipe from Quarkus");
Files.write(quarkus3DownloadedRecipePath, new URL(QUARKUS_UPDATES_BASE_URL).openStream().readAllBytes());
}

if (!Files.exists(quarkus3DownloadedRecipePath)) {
System.out.println("The Quarkus base recipe (" + quarkus3DownloadedRecipePath.getFileName()
+ ") does not exist into the folder. Please download it manually or add the `true` parameter to the script call !");
return 1;
}

List<Object> quarkusRecipes = QuarkusUpdateRecipeIO
.readRecipesYaml(Files.readString(quarkus3DownloadedRecipePath));
QuarkusUpdateRecipe mainRecipe = new QuarkusUpdateRecipe()
.buildTool(BuildTool.MAVEN);
versionProperties.forEach((property, version) -> {
System.out.println("Add Property '" + property + "' with value '" + version + "'");
mainRecipe.addOperation(new UpdatePropertyOperation(property, version));
});

if (Files.exists(projectBaseRecipePath)) {
System.out.println("Adding Project base recipe(s)");
mainRecipe.addRecipes(QuarkusUpdateRecipeIO.readRecipesYaml(Files.readString(projectBaseRecipePath)));
} else {
System.out.println("No Project base recipe(s) available. Nothing done here ...");
}

System.out.println("Adding Managed dependency recipe(s)");
Map<String, Object> managedDependencyMainRecipe = Map.of(
"type", "specs.openrewrite.org/v1beta/recipe",
"name", "org.kie.ManagedDependencies",
"displayName", "Update Managed Dependencies",
"description", "Update all managed dependencies based on dependency updates from Quarkus.",
"recipeList", retrieveAllChangeDependencyRecipesToManagedDependency(quarkusRecipes));
mainRecipe.addRecipe(managedDependencyMainRecipe);

System.out.println("Adding Quarkus base recipe(s)");
mainRecipe.addRecipes(quarkusRecipes);

System.out.println("Writing main recipe");
QuarkusUpdateRecipeIO.write(quarkus3GeneratedRecipePath, mainRecipe);

return 0;
}


public static void main(String... args) throws Exception {
int exitCode = new CommandLine(new CreateKieQuarkusProjectMigrationRecipeCli()).execute(args);
System.exit(exitCode);
}

private List<Object> retrieveAllChangeDependencyRecipesToManagedDependency(List<Object> recipes) {
List<Object> changeDependencyRecipeList = new ArrayList<>();
recipes.forEach(r -> {
if (r instanceof Map) {
List<Object> recipeList = (List<Object>) ((Map<String, Object>) r).get("recipeList");
recipeList.forEach(recipeMap -> {
if (recipeMap instanceof Map) {
((Map<String, Map<String, Object>>) recipeMap).forEach((recipeName, args) -> {
if (recipeName.equals("org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId")) {
args.remove("overrideManagedVersion");
if (!args.containsKey("newArtifactId")) {
args.put("newArtifactId", args.get("oldArtifactId"));
}
changeDependencyRecipeList.add(Map
.of("org.openrewrite.maven.ChangeManagedDependencyGroupIdAndArtifactId", args));
}
});
}
});
}
});
return changeDependencyRecipeList;
}
}
13 changes: 13 additions & 0 deletions .ci/environments/quarkus-3/patches/0001_before_sh.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/pom.xml b/pom.xml
index 0c0f0f1..cb07444 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,7 +48,7 @@
</modules>

<properties>
- <version.org.jpmml.evaluator>1.5.1</version.org.jpmml.evaluator> <!-- ATTENTION 1.5.1 intentional, because 1.5.1 evaluators works with 1.5.1 -->
+ <version.org.jpmml.evaluator>1.6.4</version.org.jpmml.evaluator> <!-- ATTENTION 1.5.1 intentional, because 1.5.1 evaluators works with 1.5.1 -->
</properties>

<dependencyManagement>
Loading
Loading