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

fix build/CI and add backport workflow #161

Merged
merged 2 commits into from
Mar 4, 2022
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
66 changes: 53 additions & 13 deletions .github/workflows/CI-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,71 @@ on:
push:
branches:
- "*"

jobs:
build:
Build-ml:
strategy:
matrix:
java: [11, 14]

name: Build and Test MLCommons Plugin
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up JDK 1.14
- name: Setup Java ${{ matrix.java }}
uses: actions/setup-java@v1
with:
java-version: 1.14
java-version: ${{ matrix.java }}

- name: Checkout ML
# ml-commons
- name: Checkout MLCommons
uses: actions/checkout@v2

- name: Build with Gradle
run: ./gradlew build -Dopensearch.version=1.3.0

- name: Build and Run Tests
run: |
./gradlew build -Dopensearch.version=1.3.0-SNAPSHOT
- name: Publish to Maven Local
run: ./gradlew publishToMavenLocal -Dopensearch.version=1.3.0

run: |
./gradlew publishToMavenLocal -Dopensearch.version=1.3.0-SNAPSHOT
- name: Multi Nodes Integration Testing
run: ./gradlew integTest -PnumNodes=3
run: |
./gradlew integTest -PnumNodes=3
- name: Pull and Run Docker
run: |
plugin=`ls plugin/build/distributions/*.zip`
echo MLCommons plugin $plugin
version=1.3.0-SNAPSHOT
plugin_version=1.3.0.0-SNAPSHOT
echo Using OpenSearch $version with MLCommons $plugin_version
cd ..
if docker pull opensearchstaging/opensearch:$version
then
echo "FROM opensearchstaging/opensearch:$version" >> Dockerfile
echo "RUN if [ -d /usr/share/opensearch/plugins/opensearch-ml ]; then /usr/share/opensearch/bin/opensearch-plugin remove opensearch-ml; fi" >> Dockerfile
echo "ADD ml-commons/plugin/build/distributions/opensearch-ml-$plugin_version.zip /tmp/" >> Dockerfile
echo "RUN /usr/share/opensearch/bin/opensearch-plugin install --batch file:/tmp/opensearch-ml-$plugin_version.zip" >> Dockerfile
docker build -t opensearch-ml:test .
echo "imagePresent=true" >> $GITHUB_ENV
else
echo "imagePresent=false" >> $GITHUB_ENV
fi
- name: Run Docker Image
if: env.imagePresent == 'true'
run: |
cd ..
docker run -p 9200:9200 -d -p 9600:9600 -e "discovery.type=single-node" opensearch-ml:test
sleep 90
- name: Run MLCommons Test
if: env.imagePresent == 'true'
run: |
security=`curl -XGET https://localhost:9200/_cat/plugins?v -u admin:admin --insecure |grep opensearch-security|wc -l`
if [ $security -gt 0 ]
then
echo "Security plugin is available"
./gradlew integTest -Dtests.rest.cluster=localhost:9200 -Dtests.cluster=localhost:9200 -Dtests.clustername="docker-cluster" -Dhttps=true -Duser=admin -Dpassword=admin
else
echo "Security plugin is NOT available"
./gradlew integTest -Dtests.rest.cluster=localhost:9200 -Dtests.cluster=localhost:9200 -Dtests.clustername="docker-cluster"
fi

- name: Upload Coverage Report
uses: codecov/codecov-action@v1
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Backport
on:
pull_request_target:
types:
- closed
- labeled

jobs:
backport:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
name: Backport
steps:
- name: GitHub App token
id: github_app_token
uses: tibdex/github-app-token@v1.5.0
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
installation_id: 22958780

- name: Backport
uses: VachaShah/backport@v1.1.4
with:
github_token: ${{ steps.github_app_token.outputs.token }}
branch_name: backport/backport-${{ github.event.number }}
15 changes: 15 additions & 0 deletions .github/workflows/delete_backport_branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Delete merged branch of the backport PRs
on:
pull_request:
types:
- closed

jobs:
delete-branch:
runs-on: ubuntu-latest
if: startsWith(github.event.pull_request.head.ref,'backport/')
steps:
- name: Delete merged branch
uses: SvanBoxel/delete-merged-branch@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ This package uses the [Gradle](https://docs.gradle.org/current/userguide/usergui

#### Building from the command line

1. `./gradlew build` builds and tests
1. `./gradlew build` builds and tests, `./gradlew build buildDeb buildRpm` build RPM and DEB.
2. `./gradlew :run` launches a single node cluster with ml-commons plugin installed
3. `./gradlew :integTest` launches a single node cluster with ml-commons plugin installed and runs all integration tests except security. Use `./gradlew integTest -PnumNodes=<number>` to launch multi-node cluster.
4. ` ./gradlew :integTest --tests="<class path>.<test method>"` runs a single integration test class or method, for example `./gradlew integTest --tests="org.opensearch.ml.rest.RestMLTrainAndPredictIT.testTrainAndPredictKmeansWithEmptyParam"` or `./gradlew integTest --tests="org.opensearch.ml.rest.RestMLTrainAndPredictIT"`
Expand Down
15 changes: 12 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ buildscript {

ext {
opensearch_group = "org.opensearch"
opensearch_version = "${opensearch_version}"
common_utils_version = "${opensearchBaseVersion}.0-SNAPSHOT"
opensearch_version = System.getProperty("opensearch.version", "1.3.0-SNAPSHOT")
// 1.3.0 -> 1.3.0.0, and 1.3.0-SNAPSHOT -> 1.3.0.0-SNAPSHOT
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is 1.x.0 -> 1.x.0.0 a convention that we normally use for how the version evolve?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, other plugins like AD using same convention.

opensearch_build = opensearch_version.replaceAll(/(\.\d)([^\d]*)$/, '$1.0$2')
common_utils_version = System.getProperty("common_utils.version", opensearch_build)
}

repositories {
Expand All @@ -34,9 +36,16 @@ plugins {

apply plugin: "com.dorongold.task-tree"

ext {
isSnapshot = "true" == System.getProperty("build.snapshot", "true")
}

allprojects {
group = 'org.opensearch.ml'
version = "${opensearchBaseVersion}.0"
version = opensearch_version - "-SNAPSHOT" + ".0"
if (isSnapshot) {
version += "-SNAPSHOT"
}

apply from: "$rootDir/build-tools/repositories.gradle"

Expand Down
7 changes: 0 additions & 7 deletions gradle.properties

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public void predict() {
Assert.assertEquals(0.0, predictions.getRow(i).getValue(1).doubleValue(), 0.1);
}
}
Assert.assertTrue(anomalyCount > 3);// total anomalies 5
Assert.assertTrue("Fewer anomaly detected: " + anomalyCount, anomalyCount > 1);// total anomalies 5
}

@Test
Expand Down
73 changes: 71 additions & 2 deletions plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ext {
}

opensearchplugin {
name 'opensearch-ml-plugin'
name 'opensearch-ml'
description 'machine learning plugin for opensearch'
classname 'org.opensearch.ml.plugin.MachineLearningPlugin'
}
Expand All @@ -57,7 +57,7 @@ compileJava {
}

//TODO: check which one should be enabled
licenseHeaders.enabled = false
licenseHeaders.enabled = true
testingConventions.enabled = false
checkstyleTest.enabled = false
forbiddenApis.ignoreFailures = false
Expand Down Expand Up @@ -247,6 +247,71 @@ configurations.all {
resolutionStrategy.force 'commons-logging:commons-logging:1.2'
}

apply plugin: 'nebula.ospackage'

// This is afterEvaluate because the bundlePlugin ZIP task is updated afterEvaluate and changes the ZIP name to match the plugin name
afterEvaluate {
ospackage {
packageName = "${name}"
release = isSnapshot ? "0.1" : '1'
version = "${project.version}" - "-SNAPSHOT"

into '/usr/share/opensearch/plugins'
from(zipTree(bundlePlugin.archivePath)) {
into opensearchplugin.name
}

user 'root'
permissionGroup 'root'
fileMode 0644
dirMode 0755

requires('opensearch-oss', versions.opensearch, EQUAL)
packager = 'Amazon'
vendor = 'Amazon'
os = 'LINUX'
prefix '/usr'

license 'ASL-2.0'
maintainer 'OpenSearch <opensearch@amazon.com>'
url 'https://opensearch.org/downloads.html'
summary '''
ML plugin for OpenSearch.
Github https://github.com/opensearch-project/ml-commons.
'''.stripIndent().replace('\n', ' ').trim()
}

buildRpm {
arch = 'NOARCH'
dependsOn 'assemble'
finalizedBy 'renameRpm'
task renameRpm(type: Copy) {
from("$buildDir/distributions")
into("$buildDir/distributions")
include archiveName
rename archiveName, "${packageName}-${version}.rpm"
doLast { delete file("$buildDir/distributions/$archiveName") }
}
}

buildDeb {
arch = 'all'
dependsOn 'assemble'
finalizedBy 'renameDeb'
task renameDeb(type: Copy) {
from("$buildDir/distributions")
into("$buildDir/distributions")
include archiveName
rename archiveName, "${packageName}-${version}.deb"
doLast { delete file("$buildDir/distributions/$archiveName") }
}
}

task buildPackages(type: GradleBuild) {
tasks = ['build', 'buildRpm', 'buildDeb']
}
}

spotless {
java {
removeUnusedImports()
Expand All @@ -256,6 +321,10 @@ spotless {
}
}

tasks.withType(licenseHeaders.class) {
additionalLicense 'AL ', 'Apache', 'Licensed under the Apache License, Version 2.0 (the "License")'
}

checkstyle {
toolVersion = '8.29'
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void search(SearchRequest request, ActionListener<SearchResponse> actionL
try (ThreadContext.StoredContext context = client.threadPool().getThreadContext().stashContext()) {
client.search(request, listener);
} catch (Exception e) {
log.error(e);
log.error("Failed to search", e);
listener.onFailure(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.ml.rest;

import static org.opensearch.common.xcontent.ToXContent.EMPTY_PARAMS;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.ml.rest;

import static org.opensearch.ml.indices.MLIndicesHandler.ML_TASK_INDEX;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -90,7 +91,13 @@ MLStatsNodesRequest getRequest(RestRequest request) {
Set<String> getStatsToBeRetrieved(RestRequest request, Set<String> validStats, List<String> requestedStats) {
if (requestedStats.contains(MLStatsNodesRequest.ALL_STATS_KEY)) {
throw new IllegalArgumentException(
String.format("Request %s contains both %s and individual stats", request.path(), MLStatsNodesRequest.ALL_STATS_KEY)
String
.format(
Locale.ROOT,
"Request %s contains both %s and individual stats",
request.path(),
MLStatsNodesRequest.ALL_STATS_KEY
)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public MLStats(Map<String, MLStat<?>> stats) {
*/
public MLStat<?> getStat(String key) throws IllegalArgumentException {
if (!stats.keySet().contains(key)) {
throw new IllegalArgumentException("Stat=\"" + key + "\" does not exist");
throw new IllegalArgumentException("Stat \"" + key + "\" does not exist");
}
return stats.get(key);
}
Expand Down
8 changes: 4 additions & 4 deletions plugin/src/main/java/org/opensearch/ml/stats/StatNames.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ public class StatNames {
public static String ML_TOTAL_MODEL_COUNT = "ml_total_model_count";

public static String requestCountStat(FunctionName functionName, ActionName actionName) {
return String.format("ml_%s_%s_request_count", functionName, actionName, Locale.ROOT).toLowerCase(Locale.ROOT);
return String.format(Locale.ROOT, "ml_%s_%s_request_count", functionName, actionName).toLowerCase(Locale.ROOT);
}

public static String failureCountStat(FunctionName functionName, ActionName actionName) {
return String.format("ml_%s_%s_failure_count", functionName, actionName, Locale.ROOT).toLowerCase(Locale.ROOT);
return String.format(Locale.ROOT, "ml_%s_%s_failure_count", functionName, actionName).toLowerCase(Locale.ROOT);
}

public static String executingRequestCountStat(FunctionName functionName, ActionName actionName) {
return String.format("ml_%s_%s_executing_request_count", functionName, actionName, Locale.ROOT).toLowerCase(Locale.ROOT);
return String.format(Locale.ROOT, "ml_%s_%s_executing_request_count", functionName, actionName).toLowerCase(Locale.ROOT);
}

public static String modelCountStat(FunctionName functionName) {
return String.format("ml_%s_model_count", functionName, Locale.ROOT).toLowerCase(Locale.ROOT);
return String.format(Locale.ROOT, "ml_%s_model_count", functionName).toLowerCase(Locale.ROOT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ private void predict(
OpenSearchException e = new OpenSearchException(
"User: " + requestUser.getName() + " does not have permissions to run predict by model: " + request.getModelId()
);
log.debug(e);
handlePredictFailure(mlTask, internalListener, e, false);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public void createMLTask(MLTask mlTask, ActionListener<IndexResponse> listener)
* Update ML task with default listener.
* @param taskId task id
* @param updatedFields updated field and values
* @param timeoutInMillis time out waiting for updating task semaphore, zero or negative means don't wait at all
*/
public void updateMLTask(String taskId, Map<String, Object> updatedFields, long timeoutInMillis) {
updateMLTask(taskId, updatedFields, ActionListener.wrap(response -> {
Expand Down
Loading