Compare commits

..

4 Commits

Author SHA1 Message Date
Roman Acevedo
9575cc1c87 fake commit to run flaky tests 2025-12-05 18:07:27 +01:00
Florian Hussonnois
3cbad1ce0d fix(tests): fix StatefulTriggerInterfaceTest 2025-12-05 17:56:32 +01:00
Debjyoti Shit
760050e9fc fix(ui): improve responsive layout and styling of flow editor and sidebar (#13371)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
Co-authored-by: Bart Ledoux <bledoux@kestra.io>
2025-12-05 17:35:25 +01:00
Nancy Sangani
43f47ec337 fix: error dialogue not appearing after first use of checks #13357 (#13364)
Co-authored-by: Miloš Paunović <paun992@hotmail.com>
2025-12-05 16:24:53 +01:00
7 changed files with 74 additions and 79 deletions

View File

@@ -1,6 +1,7 @@
package io.kestra.core.models.triggers;
import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.TenantInterface;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.runners.RunContextFactory;
import jakarta.inject.Inject;
@@ -22,21 +23,15 @@ class StatefulTriggerInterfaceTest {
RunContextFactory runContextFactory;
@Test
void shouldPersistAndReadState() throws Exception {
void shouldPersistAndReadState() {
var flow = Flow.builder()
.tenantId("main")
.namespace("io.kestra.unittest")
.id("test-flow")
.revision(1)
.build();
var runContext = runContextFactory.of(flow, Map.of(
"flow", Map.of(
"tenantId", "main",
"namespace", "io.kestra.unittest",
"id", "test-flow",
"revision", 1
)
));
var runContext = runContextFactory.of(flow, Map.of());
var key = defaultKey("ns", "test-flow", "trigger-persist");
var ttl = Optional.of(Duration.ofMinutes(5));
@@ -59,21 +54,15 @@ class StatefulTriggerInterfaceTest {
}
@Test
void shouldExpireOldEntriesAfterTTL() throws Exception {
void shouldExpireOldEntriesAfterTTL() {
var flow = Flow.builder()
.tenantId("main")
.namespace("io.kestra.unittest")
.id("test-flow")
.revision(1)
.build();
var runContext = runContextFactory.of(flow, Map.of(
"flow", Map.of(
"tenantId", "main",
"namespace", "io.kestra.unittest",
"id", "test-flow",
"revision", 1
)
));
var runContext = runContextFactory.of(flow, Map.of());
var key = defaultKey("ns", "test-flow", "trigger-ttl");
var ttl = Optional.of(Duration.ofMinutes(5));

View File

@@ -557,10 +557,6 @@ public class JdbcExecutor implements ExecutorInterface {
final FlowWithSource flow = findFlowOrThrow(execution);
executor = executor.withFlow(flow);
if (execution.getId().startsWith("shouldFail")) {
throw new RuntimeException("Simulated failure");
}
// schedule it for later if needed
if (execution.getState().getCurrent() == State.Type.CREATED && execution.getScheduleDate() != null && execution.getScheduleDate().isAfter(Instant.now())) {
ExecutionDelay executionDelay = ExecutionDelay.builder()

View File

@@ -3,18 +3,14 @@ package io.kestra.jdbc.runner;
import io.kestra.core.junit.annotations.LoadFlows;
import io.kestra.core.models.executions.Execution;
import io.kestra.core.models.executions.LogEntry;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.flows.State;
import io.kestra.core.queues.MessageTooBigException;
import io.kestra.core.queues.QueueException;
import io.kestra.core.queues.QueueFactoryInterface;
import io.kestra.core.queues.QueueInterface;
import io.kestra.core.repositories.FlowRepositoryInterface;
import io.kestra.core.runners.AbstractRunnerTest;
import io.kestra.core.runners.InputsTest;
import io.kestra.core.utils.IdUtils;
import io.kestra.core.utils.TestsUtils;
import io.kestra.plugin.core.log.Log;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.junit.jupiter.api.Test;
@@ -23,14 +19,9 @@ import org.slf4j.event.Level;
import reactor.core.publisher.Flux;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static io.kestra.core.repositories.AbstractFlowRepositoryTest.TEST_NAMESPACE;
import static io.kestra.core.tenant.TenantService.MAIN_TENANT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -40,9 +31,6 @@ public abstract class JdbcRunnerTest extends AbstractRunnerTest {
@Named(QueueFactoryInterface.EXECUTION_NAMED)
protected QueueInterface<Execution> executionQueue;
@Inject
protected FlowRepositoryInterface flowRepository;
public static final String NAMESPACE = "io.kestra.tests";
@Test
@@ -62,14 +50,6 @@ public abstract class JdbcRunnerTest extends AbstractRunnerTest {
).hasSize(2);
}
@Test
@LoadFlows("flows/valids/return.yaml")
void stuckExecutor() throws QueueException, InterruptedException, TimeoutException {
Execution wrongExecution = Execution.newExecution(flowRepository.findById(MAIN_TENANT, "io.kestra.tests", "return").get(), Collections.emptyList()).withScheduleDate(Instant.now().minus(Instant.now().toEpochMilli() - 100000, ChronoUnit.MILLIS));
executionQueue.emit(wrongExecution.toBuilder().id("shouldFail" + IdUtils.create()).build());
runnerUtils.runOne(MAIN_TENANT, "io.kestra.tests", "return");
}
@Test
@LoadFlows({"flows/valids/waitfor-child-task-warning.yaml"})
void waitForChildTaskWarning() throws Exception {

View File

@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
public class DockerService {
// DDDDDDD
public static DockerClient client(DockerClientConfig dockerClientConfig) {
DockerHttpClient dockerHttpClient = new ApacheDockerHttpClient.Builder()
.dockerHost(dockerClientConfig.getDockerHost())

7
ui/package-lock.json generated
View File

@@ -11,7 +11,6 @@
"dependencies": {
"@js-joda/core": "^5.6.5",
"@kestra-io/ui-libs": "^0.0.263",
"@swc/core-linux-x64-gnu": "1.15.3",
"@vue-flow/background": "^1.3.2",
"@vue-flow/controls": "^1.1.2",
"@vue-flow/core": "^1.47.0",
@@ -14767,9 +14766,9 @@
}
},
"node_modules/mdast-util-to-hast": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
"integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
"version": "13.2.1",
"resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
"integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",

View File

@@ -1,15 +1,21 @@
<template>
<div class="tabs-wrapper">
<div class="tabs">
<button
<el-tooltip
v-for="element of tabs"
:key="element.uid"
:class="{active: openTabs.includes(element.uid)}"
@click="setTabValue(element.uid)"
:content="element.button.label"
placement="bottom"
:showAfter="500"
>
<component class="tabs-icon" :is="element.button.icon" />
{{ element.button.label }}
</button>
<button
:class="{active: openTabs.includes(element.uid)}"
@click="setTabValue(element.uid)"
>
<component class="tabs-icon" :is="element.button.icon" />
<span class="tab-label">{{ element.button.label }}</span>
</button>
</el-tooltip>
</div>
<slot />
</div>
@@ -34,19 +40,19 @@
<style scoped lang="scss">
@use "@kestra-io/ui-libs/src/scss/color-palette.scss" as colorPalette;
.tabs-wrapper{
display:flex;
.tabs-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--ks-border-primary);
background: var(--ks-background-card);
background-image: linear-gradient(
to right,
colorPalette.$base-blue-400 0%,
colorPalette.$base-blue-500 35%,
rgba(colorPalette.$base-blue-500, 0) 55%,
rgba(colorPalette.$base-blue-500, 0) 100%
);
background-size: 250% 100%;
background-position: 100% 0;
transition: background-position .2s;
overflow-x: auto;
scrollbar-width: none;
.dark & {
background-image: linear-gradient(
to right,
@@ -56,35 +62,38 @@
rgba(colorPalette.$base-blue-700, 0) 100%
);
}
background-size: 250% 100%;
background-position: 100% 0;
transition: background-position .2s;
}
.tabs{
.tabs {
padding: .5rem 1rem;
display: flex;
flex-wrap: wrap;
gap: .25rem .5rem;
align-items: center;
gap: .5rem;
> button{
background: none;
border: none;
padding: .5rem;
font-size: .8rem;
> button {
background: transparent;
border: 1px solid transparent;
border-radius: 6px;
padding: 0.35rem 0.75rem;
font-size: 0.85rem;
white-space: nowrap;
color: var(--ks-color-text-primary);
display: inline-flex;
align-items: center;
justify-content: center;
transition: opacity .2s;
gap: .25rem;
opacity: .5;
transition: all 0.2s ease-in-out;
gap: 0.4rem;
opacity: .7;
&:hover{
color: var(--ks-color-text-secondary);
&:hover {
background-color: var(--ks-background-body);
opacity: 1;
}
&.active{
&.active {
background-color: var(--ks-background-body);
border-color: var(--ks-border-primary);
color: var(--ks-color-text-primary);
opacity: 1;
}
@@ -92,7 +101,25 @@
}
.tabs-icon {
margin-right: .25rem;
vertical-align: bottom;
font-size: 1.1em;
vertical-align: middle;
flex-shrink: 0;
}
@media (max-width: 1200px) {
.tab-label {
display: none;
}
.tabs {
gap: 0.25rem;
padding: 0.4rem 0.5rem;
}
.tabs > button {
padding: 0.5rem;
gap: 0;
aspect-ratio: 1 / 1;
}
}
</style>

View File

@@ -190,6 +190,8 @@
},
onSubmit(formRef) {
if (formRef && this.flowCanBeExecuted) {
this.checks = [];
this.executeClicked = false;
formRef.validate((valid) => {
if (!valid) {
return false;
@@ -223,6 +225,7 @@
nextStep: true,
});
}
this.executeClicked = true;
this.$emit("executionTrigger");
});
}