Skip to content

Commit

Permalink
Merge branch 'refs/heads/staging' into NU-1694-add-datepicker-to-edit…
Browse files Browse the repository at this point in the history
…or-table

# Conflicts:
#	designer/client/cypress/e2e/__image_snapshots__/electron/Linux/Process with data should have counts button and modal #3.png
  • Loading branch information
Dzuming committed Jun 13, 2024
2 parents bd993cc + d82f033 commit 40e75ef
Show file tree
Hide file tree
Showing 99 changed files with 1,685 additions and 612 deletions.
33 changes: 20 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: Release
on:
workflow_dispatch:
inputs:
release_version:
description: "Released Nussknacker version"
required: true
type: string
backport_release:
description: "Backport release - 'latest' tag won't be updated on docker"
required: true
Expand All @@ -12,22 +16,20 @@ on:
required: true
default: true
type: boolean
release_version:
description: "Fill it if backport or RC. Otherwise with-defaults will be used"
required: false
type: string

jobs:
build:
runs-on: ubuntu-latest
env:
SBT_RELEASE_NEXT_VERSION: ${{ (inputs.release_version && format('{0} {1} with-defaults', 'release-version', inputs.release_version)) || 'with-defaults' }}
NU_DOCKER_UPDATE_LATEST: ${{ inputs.backport_release == false && inputs.release_candidate == false }}
NUSSKNACKER_VERSION: ${{ inputs.release_version }}
NEXT_VERSION_RELEASE: ${{ inputs.backport_release == false && inputs.release_candidate == false }}
SBT_RELEASE_NEXT_VERSION: ${{ format('{0} {1} with-defaults', 'release-version', inputs.release_version) }}
NU_INSTALLATION_EXAMPLE_ACCESS_TOKEN: ${{ secrets.NU_INSTALLATION_EXAMPLE_PAT }}
steps:
- name: "Output variables"
run: |
echo Backport release is ${{ inputs.backport_release }}, Release Candidate is ${{ inputs.release_candidate }}.
echo Docker update latest is ${{ env.NU_DOCKER_UPDATE_LATEST }}
echo Docker update latest is ${{ env.NEXT_VERSION_RELEASE }}
echo SBT release next version is ${{ env.SBT_RELEASE_NEXT_VERSION }}
- name: "Validate release branch name"
Expand Down Expand Up @@ -109,22 +111,27 @@ jobs:
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USER }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
# dockerUpBranchLatest is set to false because branch latest tags are used by cypress tests and
dockerUpLatest: ${{ env.NU_DOCKER_UPDATE_LATEST }}
dockerUpLatest: ${{ env.NEXT_VERSION_RELEASE }}
# we don't update release-xxx-latest tag, because the image built during the release doesn't contain developer's extensions which are required by cypress tests
dockerUpBranchLatest: false
run: sbt 'release ${{ env.SBT_RELEASE_NEXT_VERSION }} skip-tests'

- name: "Push to master"
if: ${{ env.NU_DOCKER_UPDATE_LATEST == 'true' }}
if: ${{ env.NEXT_VERSION_RELEASE == 'true' }}
run: git push origin HEAD:master -f

- name: Push installation example to GH nussknacker-installation-example repository
if: ${{ env.NEXT_VERSION_RELEASE == 'true' }}
run: |
./.github/workflows/scripts/publishNuInstallationExample.sh
- name: "Read nussknacker short description from file"
if: ${{ env.NU_DOCKER_UPDATE_LATEST == 'true' }}
if: ${{ env.NEXT_VERSION_RELEASE == 'true' }}
id: short_nu
run: echo "::set-output name=short::$(cat dockerhub/nussknacker/short.txt)"

- name: "Dockerhub publish readme nussknacker"
if: ${{ env.NU_DOCKER_UPDATE_LATEST == 'true' }}
if: ${{ env.NEXT_VERSION_RELEASE == 'true' }}
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
Expand All @@ -134,12 +141,12 @@ jobs:
readme-filepath: "dockerhub/nussknacker/README.md"

- name: "Read nussknacker-lite-runtime-app short description from file"
if: ${{ env.NU_DOCKER_UPDATE_LATEST == 'true' }}
if: ${{ env.NEXT_VERSION_RELEASE == 'true' }}
id: short_nu_lite
run: echo "::set-output name=short::$(cat dockerhub/nussknacker-lite-runtime-app/short.txt)"

- name: "Dockerhub publish readme nussknacker-lite-runtime-app"
if: ${{ env.NU_DOCKER_UPDATE_LATEST == 'true' }}
if: ${{ env.NEXT_VERSION_RELEASE == 'true' }}
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/scripts/publishNuInstallationExample.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash -ex

if [ -z "$NU_INSTALLATION_EXAMPLE_ACCESS_TOKEN" ]; then
echo "NU_INSTALLATION_EXAMPLE_ACCESS_TOKEN variable has to be defined"
exit 1
fi

if [ -z "$NUSSKNACKER_VERSION" ]; then
echo "NUSSKNACKER_VERSION variable has to be defined"
exit 1
fi

cleanup() {
rm -rf nu-installation-example-repo
}

cleanup # just for sure

trap cleanup EXIT

git clone "https://$NU_INSTALLATION_EXAMPLE_ACCESS_TOKEN@github.com/TouK/nussknacker-installation-example.git" nu-installation-example-repo
cd nu-installation-example-repo
git remote set-url origin "https://$NU_INSTALLATION_EXAMPLE_ACCESS_TOKEN@github.com/TouK/nussknacker-installation-example.git"

rm -rf ./*
cp -r ../examples/installation/* .
echo "NUSSKNACKER_VERSION=$NUSSKNACKER_VERSION" > .env

git config user.email "actions@github.com"
git config user.name "GitHub Actions"
git add .
git commit -m "Publishing $NUSSKNACKER_VERSION installation example"
git tag "$NUSSKNACKER_VERSION"
git push -f origin master --tags
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,8 @@ lazy val liteKafkaComponentsTests: Project = (project in lite("components/kafka-
libraryDependencies ++= {
Seq(
"org.scalacheck" %% "scalacheck" % scalaCheckV % Test,
"org.scalatestplus" %% s"scalacheck-$scalaCheckVshort" % scalaTestPlusV % Test
"org.scalatestplus" %% s"scalacheck-$scalaCheckVshort" % scalaTestPlusV % Test,
"org.scalatestplus" %% "mockito-4-11" % scalaTestPlusV % Test,
)
},
)
Expand Down
3 changes: 2 additions & 1 deletion designer/client/cypress/e2e/tableEditor.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ describe("Table editor", () => {
});

// For now, it's a separate test. However, we can merge it should display rich table editor when fixed
it("should change columns position", () => {
// TODO: Fix flaky tests on CI
it.skip("should change columns position", () => {
cy.viewport("macbook-15");
cy.visitNewProcess(seed, "table", "Default");
cy.intercept("POST", "/api/nodes/*/validation", (request) => {
Expand Down
8 changes: 4 additions & 4 deletions designer/client/src/components/modals/CustomActionDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function CustomActionDialog(props: WindowContentProps<WindowKind, CustomA

const [value, setValue] = useState<UnknownRecord>();

const confirm = useCallback(async () => {
const confirmAction = useCallback(async () => {
await HttpService.customAction(processName, action.name, value, comment).then((response) => {
if (response.isSuccess) {
dispatch(loadProcessState(processName));
Expand All @@ -124,10 +124,10 @@ export function CustomActionDialog(props: WindowContentProps<WindowKind, CustomA
const { t } = useTranslation();
const buttons: WindowButtonProps[] = useMemo(
() => [
{ title: t("dialog.button.cancel", "cancel"), action: () => props.close(), classname: LoadingButtonTypes.secondaryButton },
{ title: t("dialog.button.confirm", "confirm"), action: () => confirm() },
{ title: t("dialog.button.cancel", "Cancel"), action: () => props.close(), classname: LoadingButtonTypes.secondaryButton },
{ title: t("dialog.button.confirm", "Ok"), action: () => confirmAction() },
],
[confirm, props, t],
[confirmAction, props, t],
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { StatusType } from "../../../Process/types";
import { ToolbarButton } from "../../../toolbarComponents/toolbarButtons";
import { ToolbarButtonProps } from "../../types";
import UrlIcon from "../../../UrlIcon";
import { ACTION_DIALOG_WIDTH } from "../../../../stylesheets/variables";

type CustomActionProps = {
action: CustomAction;
Expand Down Expand Up @@ -39,6 +40,7 @@ export default function CustomActionButton(props: CustomActionProps) {
open<CustomAction>({
title: action.name,
kind: WindowKind.customAction,
width: ACTION_DIALOG_WIDTH,
meta: action,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { WindowKind, useWindows } from "../../../../windowManager";
import { ToggleProcessActionModalData } from "../../../modals/DeployProcessDialog";
import { ToolbarButton } from "../../../toolbarComponents/toolbarButtons";
import { ToolbarButtonProps } from "../../types";
import { ACTION_DIALOG_WIDTH } from "../../../../stylesheets/variables";

export default function CancelDeployButton(props: ToolbarButtonProps) {
const { t } = useTranslation();
Expand All @@ -33,6 +34,7 @@ export default function CancelDeployButton(props: ToolbarButtonProps) {
open<ToggleProcessActionModalData>({
title: message,
kind: WindowKind.deployProcess,
width: ACTION_DIALOG_WIDTH,
meta: { action },
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { StatusType } from "../../../Process/types";
import { ToolbarButton } from "../../../toolbarComponents/toolbarButtons";
import { ToolbarButtonProps } from "../../types";
import UrlIcon from "../../../UrlIcon";
import { ACTION_DIALOG_WIDTH } from "../../../../stylesheets/variables";

type CustomActionProps = {
action: CustomAction;
Expand Down Expand Up @@ -39,6 +40,7 @@ export default function CustomActionButton(props: CustomActionProps) {
open<CustomAction>({
title: action.name,
kind: WindowKind.customAction,
width: ACTION_DIALOG_WIDTH,
meta: action,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { WindowKind } from "../../../../windowManager";
import { ToggleProcessActionModalData } from "../../../modals/DeployProcessDialog";
import { ToolbarButton } from "../../../toolbarComponents/toolbarButtons";
import { ToolbarButtonProps } from "../../types";
import { ACTION_DIALOG_WIDTH } from "../../../../stylesheets/variables";

export default function DeployButton(props: ToolbarButtonProps) {
const dispatch = useDispatch();
Expand Down Expand Up @@ -49,6 +50,7 @@ export default function DeployButton(props: ToolbarButtonProps) {
open<ToggleProcessActionModalData>({
title: message,
kind: WindowKind.deployProcess,
width: ACTION_DIALOG_WIDTH,
meta: { action, displayWarnings: true },
})
}
Expand Down
2 changes: 2 additions & 0 deletions designer/client/src/stylesheets/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export const PANEL_BUTTON_SIZE = SIDEBAR_WIDTH / 4;
export const PANEL_BUTTON_SMALL_SIZE = SIDEBAR_WIDTH / 6;

export const MODAL_HEADER_HEIGHT = 30;

export const ACTION_DIALOG_WIDTH = 652;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package pl.touk.nussknacker.engine.api.deployment
import pl.touk.nussknacker.engine.api.deployment.inconsistency.InconsistentStateDetector
import pl.touk.nussknacker.engine.api.process.{ProcessIdWithName, ProcessName}
import pl.touk.nussknacker.engine.deployment.CustomActionDefinition
import pl.touk.nussknacker.engine.newdeployment

import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.Future
Expand Down Expand Up @@ -32,6 +33,8 @@ trait DeploymentManagerInconsistentStateHandlerMixIn {

trait DeploymentManager extends AutoCloseable {

def deploymentSynchronisationSupport: DeploymentSynchronisationSupport

def processCommand[Result](command: DMScenarioCommand[Result]): Future[Result]

final def getProcessState(idWithName: ProcessIdWithName, lastStateAction: Option[ProcessAction])(
Expand Down Expand Up @@ -71,3 +74,13 @@ trait DeploymentManager extends AutoCloseable {
Future.failed(new NotImplementedError())

}

sealed trait DeploymentSynchronisationSupport

trait DeploymentSynchronisationSupported extends DeploymentSynchronisationSupport {

def getDeploymentStatusesToUpdate: Future[Map[newdeployment.DeploymentId, DeploymentStatus]]

}

case object NoDeploymentSynchronisationSupport extends DeploymentSynchronisationSupport
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package pl.touk.nussknacker.engine.api.deployment

import enumeratum.EnumEntry.UpperSnakecase
import enumeratum.{Enum, EnumEntry}
import io.circe.Codec
import io.circe.generic.extras.semiauto.deriveUnwrappedCodec

// Currently DeploymentStatus are limited set of allowed statuses. Only ProblemDeploymentStatus can have different
// descriptions depending on DM implementation. It makes implementation of logic based on statuses easier. In case
// if we have requirement to make it more flexible, we can relax this restriction.
sealed trait DeploymentStatus extends EnumEntry with UpperSnakecase {
def name: DeploymentStatusName = DeploymentStatusName(entryName)
}

sealed abstract class NoAttributesDeploymentStatus extends DeploymentStatus

final case class ProblemDeploymentStatus(description: String) extends DeploymentStatus {
override def name: DeploymentStatusName = ProblemDeploymentStatus.name
}

object DeploymentStatus extends Enum[DeploymentStatus] {

override def values = findValues

object Problem {

private val DefaultDescription = "There are some problems with deployment."

val Failed: ProblemDeploymentStatus = ProblemDeploymentStatus(DefaultDescription)

val FailureDuringDeploymentRequesting: ProblemDeploymentStatus = ProblemDeploymentStatus(
"There were some problems with deployment requesting"
)

}

case object DuringDeploy extends NoAttributesDeploymentStatus
case object Running extends NoAttributesDeploymentStatus
case object Finished extends NoAttributesDeploymentStatus
case object Restarting extends NoAttributesDeploymentStatus
case object DuringCancel extends NoAttributesDeploymentStatus
case object Canceled extends NoAttributesDeploymentStatus

}

object ProblemDeploymentStatus {
def name: DeploymentStatusName = DeploymentStatusName("PROBLEM")

def extractDescription(status: DeploymentStatus): Option[String] =
status match {
case problem: ProblemDeploymentStatus =>
Some(problem.description)
case _: NoAttributesDeploymentStatus =>
None
}

}

final case class DeploymentStatusName(value: String) {
override def toString: String = value
}

object DeploymentStatusName {

implicit val codec: Codec[DeploymentStatusName] = deriveUnwrappedCodec[DeploymentStatusName]

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.Future
import scala.concurrent.duration._

class CachingProcessStateDeploymentManager(delegate: DeploymentManager, cacheTTL: FiniteDuration)
extends DeploymentManager {
class CachingProcessStateDeploymentManager(
delegate: DeploymentManager,
cacheTTL: FiniteDuration,
override val deploymentSynchronisationSupport: DeploymentSynchronisationSupport
) extends DeploymentManager {

private val cache: AsyncCache[ProcessName, List[StatusDetails]] = Caffeine
.newBuilder()
Expand Down Expand Up @@ -68,7 +71,7 @@ object CachingProcessStateDeploymentManager extends LazyLogging {
scenarioStateCacheTTL
.map { cacheTTL =>
logger.debug(s"Wrapping DeploymentManager: $delegate with caching mechanism with TTL: $cacheTTL")
new CachingProcessStateDeploymentManager(delegate, cacheTTL)
new CachingProcessStateDeploymentManager(delegate, cacheTTL, delegate.deploymentSynchronisationSupport)
}
.getOrElse {
logger.debug(s"Skipping ProcessState caching for DeploymentManager: $delegate")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,30 @@ package pl.touk.nussknacker.engine.api.deployment.simple

import pl.touk.nussknacker.engine.api.deployment.StateStatus.StatusName
import pl.touk.nussknacker.engine.api.deployment.simple.SimpleStateStatus.ProblemStateStatus.defaultActions
import pl.touk.nussknacker.engine.api.deployment.{ScenarioActionName, StateDefinitionDetails, StateStatus}
import pl.touk.nussknacker.engine.api.deployment.{
DeploymentStatus,
NoAttributesDeploymentStatus,
NoAttributesStateStatus,
ProblemDeploymentStatus,
ScenarioActionName,
StateDefinitionDetails,
StateStatus
}
import pl.touk.nussknacker.engine.api.process.VersionId

import java.net.URI

object SimpleStateStatus {

def fromDeploymentStatus(deploymentStatus: DeploymentStatus): StateStatus = {
deploymentStatus match {
case noAttributes: NoAttributesDeploymentStatus => NoAttributesStateStatus(noAttributes.name.value)
// We assume that all deployment status have default allowedActions. Non-default allowedActions have only
// statuses that are not deployment statuses but scenario statuses.
case problem: ProblemDeploymentStatus => ProblemStateStatus(problem.description)
}
}

// Represents general problem.
final case class ProblemStateStatus(description: String, allowedActions: List[ScenarioActionName] = defaultActions)
extends StateStatus {
Expand Down
Loading

0 comments on commit 40e75ef

Please sign in to comment.