Compare commits

...
Author SHA1 Message Date
james.maesandClaude Fable 5.1 433523ca5b fix(processes): keep SendTestEventToWebhook's records past its input screen
The input form sat at step 0, before the streamed-ETL preview step. The
records chosen when the process starts reach only the steps of that first
run, and the preview step is what keeps them (as queryFilterJson) for the
later steps; with the form first, the run stopped before any backend step,
so submitting the form failed with "No records were selected for running
this process" from every UI API client.

The form now follows the preview step. Its value is read only by the load
step. SendTestEventToWebhookProcessTest runs the process the way a UI does
(records at init, none on the continuation) and failed before this change.

Refs QRun-IO/qqq#1361

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 05:16:46 -06:00
james.maesandCodex 92760ff091 ci: enroll in the shared QQQ orb (#38)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 19:55:54 -05:00
james.maesandCodex 80bdbff868 ci: use shared orb pipelines and source scanning (#32)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 10:41:35 -05:00
5 changed files with 149 additions and 54 deletions

No files matched your search

+10 -53
View File
@@ -1,57 +1,14 @@
version: 2.1
setup: true
orbs:
qqq-orb: kingsrook/qqq-orb@0.5.0
qqq-orb: kingsrook/qqq-orb@0.8
workflows:
test_only:
setup:
jobs:
- qqq-orb/mvn_test_only:
context: [ qqq-maven-registry-credentials ]
filters:
branches:
ignore: /(develop|main|release/.*|hotfix/.*|integration.*)/
tags:
only: []
publish_snapshot:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: snapshot
filters:
branches:
only:
- develop
publish_release_candidate:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: release_candidate
filters:
branches:
only:
- /release\/.*/
publish_release:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: release
filters:
branches:
only: [ main ]
tags:
only: [ /v.*/ ]
publish_hotfix_release:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: hotfix
filters:
branches:
only:
- /hotfix\/.*/
- qqq-orb/generate_pipeline:
orb_version: '0.8'
filters:
branches:
ignore: automation/qbit-rc-pending
tags:
only: /v.*/
+23
View File
@@ -0,0 +1,23 @@
name: CodeQL
'on':
push:
branches:
- main
- develop
- release/**
- hotfix/**
pull_request: {}
schedule:
- cron: 41 16 * * 0
workflow_dispatch: {}
permissions:
contents: read
actions: read
security-events: write
packages: read
concurrency:
group: codeql-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
analyze:
uses: QRun-IO/qqq-orb/.github/workflows/qbit-codeql.yml@c288a8864fe9054f68410e1d78f5863aea4c4d22
+16
View File
@@ -0,0 +1,16 @@
profile: qbit
orb_version: '0.8'
default_branch: develop
java_version: '21'
browsers: true
api_checks: false
docs_only: false
release_on_main: true
release_tag_policy: v-prefix
test_branch_policy: feature-no-hotfix
publish:
snapshot: true
release_candidate: true
release: true
hotfix: true
asciidoc: false
@@ -73,7 +73,15 @@ public class SendTestEventToWebhookProcessMetaDataProducer extends MetaDataProdu
))
.getProcessMetaData();
processMetaData.withStep(0, new QFrontendStepMetaData()
//////////////////////////////////////////////////////////////////////////
// the input screen goes after the first backend (preview) step, not //
// before it: the records chosen when the process starts reach only //
// the steps of that first run, and the preview step is what keeps //
// them (as queryFilterJson) for the later steps. As step 0 the screen //
// stopped the first run before any backend step, so the records were //
// lost and the extract failed with "No records were selected". //
//////////////////////////////////////////////////////////////////////////
processMetaData.withStep(1, new QFrontendStepMetaData()
.withName("input")
.withComponent(new QFrontendComponentMetaData()
.withType(QComponentType.EDIT_FORM))
@@ -0,0 +1,91 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2025. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qbits.webhooks.processes;
import java.util.List;
import com.kingsrook.qbits.webhooks.BaseTest;
import com.kingsrook.qqq.backend.core.actions.processes.QProcessCallback;
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/*******************************************************************************
** Runs SendTestEventToWebhook the way a UI does: records are given only when
** the process starts (the init call); the continuation of the first screen
** carries no records.
*******************************************************************************/
class SendTestEventToWebhookProcessTest extends BaseTest
{
/*******************************************************************************
** The records chosen at init must still be there after the input screen.
*******************************************************************************/
@Test
void testRecordsFromInitSurviveTheInputScreen() throws QException
{
Integer webhookId = insert(newWebhook("Test receiver"));
///////////////////////////////////////////////////////////////////////
// init: records come in through the callback, as the UI API's init //
// passes recordIds; the run stops at the first frontend step //
///////////////////////////////////////////////////////////////////////
RunProcessInput initInput = new RunProcessInput();
initInput.setProcessName(SendTestEventToWebhookProcessMetaDataProducer.NAME);
initInput.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
initInput.setCallback(new QProcessCallback()
{
@Override
public QQueryFilter getQueryFilter()
{
return (new QQueryFilter(new QFilterCriteria("id", QCriteriaOperator.IN, List.of(webhookId))));
}
});
RunProcessOutput initOutput = new RunProcessAction().execute(initInput);
assertThat(initOutput.getException()).isEmpty();
assertThat(initOutput.getProcessState().getNextStepName()).contains("input");
//////////////////////////////////////////////////////////////////////
// continue after the input screen, with no callback: the extract //
// must still find the webhook chosen at init //
//////////////////////////////////////////////////////////////////////
RunProcessInput stepInput = new RunProcessInput();
stepInput.setProcessName(SendTestEventToWebhookProcessMetaDataProducer.NAME);
stepInput.setProcessUUID(initOutput.getProcessUUID());
stepInput.setStartAfterStep("input");
stepInput.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
stepInput.addValue("uponSuccessUpdateUnhealthyWebhooksToProbation", true);
RunProcessOutput stepOutput = new RunProcessAction().execute(stepInput);
assertThat(stepOutput.getException()).isEmpty();
assertThat(stepOutput.getProcessState().getNextStepName()).contains("review");
assertThat(stepOutput.getValues().get("recordCount")).isEqualTo(1);
}
}