Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49372e0b98 |
No files matched your search
+28
-11
@@ -1,14 +1,31 @@
|
|||||||
|
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
||||||
|
# See: https://circleci.com/docs/reference/configuration-reference/
|
||||||
version: 2.1
|
version: 2.1
|
||||||
setup: true
|
|
||||||
orbs:
|
# Define a job to be invoked later in a workflow.
|
||||||
qqq-orb: kingsrook/qqq-orb@0.8
|
# See: https://circleci.com/docs/guides/orchestrate/jobs-steps/#jobs-overview & https://circleci.com/docs/reference/configuration-reference/#jobs
|
||||||
|
jobs:
|
||||||
|
say-hello:
|
||||||
|
# Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub.
|
||||||
|
# See: https://circleci.com/docs/guides/execution-managed/executor-intro/ & https://circleci.com/docs/reference/configuration-reference/#executor-job
|
||||||
|
docker:
|
||||||
|
# Specify the version you desire here
|
||||||
|
# See: https://circleci.com/developer/images/image/cimg/base
|
||||||
|
- image: cimg/base:current
|
||||||
|
|
||||||
|
# Add steps to the job
|
||||||
|
# See: https://circleci.com/docs/guides/orchestrate/jobs-steps/#steps-overview & https://circleci.com/docs/reference/configuration-reference/#steps
|
||||||
|
steps:
|
||||||
|
# Checkout the code as the first step.
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: "Say hello"
|
||||||
|
command: "echo Hello, World!"
|
||||||
|
|
||||||
|
# Orchestrate jobs using workflows
|
||||||
|
# See: https://circleci.com/docs/guides/orchestrate/workflows/ & https://circleci.com/docs/reference/configuration-reference/#workflows
|
||||||
workflows:
|
workflows:
|
||||||
setup:
|
say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow.
|
||||||
|
# Inside the workflow, you define the jobs you want to run.
|
||||||
jobs:
|
jobs:
|
||||||
- qqq-orb/generate_pipeline:
|
- say-hello
|
||||||
orb_version: '0.8'
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
ignore: automation/qbit-rc-pending
|
|
||||||
tags:
|
|
||||||
only: /^v\d+\.\d+\.\d+$/
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
name: build
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
jobs:
|
|
||||||
maven:
|
|
||||||
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/maven.yaml@v1
|
|
||||||
secrets: inherit
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,74 +1,25 @@
|
|||||||
|
# Cut the next release candidate (QRun-IO/qqq docs/QRUN-QBIT-REPO-STANDARD.md, C6):
|
||||||
|
# run this workflow by hand, or merge a develop PR labelled `release:rc`. It merges develop into
|
||||||
|
# the release line and the release/* push runs CircleCI publish_release_candidate.
|
||||||
name: Release candidate
|
name: Release candidate
|
||||||
'on':
|
|
||||||
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
dry_run:
|
dry_run:
|
||||||
description: Plan a cut without changing release state
|
description: Print the plan without merging or creating branches
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
finalize:
|
|
||||||
description: Retry finalization of an existing cut; do not cut another RC
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
recover:
|
|
||||||
description: Recover the same published RC after a deployment timeout; never
|
|
||||||
reupload
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
circle_build:
|
|
||||||
description: Original Circle publisher build number (recovery only)
|
|
||||||
type: string
|
|
||||||
default: ''
|
|
||||||
merge_sha:
|
|
||||||
description: Existing cut merge_sha (finalize retry only)
|
|
||||||
type: string
|
|
||||||
default: ''
|
|
||||||
bump_sha:
|
|
||||||
description: Existing cut bump_sha (finalize retry only)
|
|
||||||
type: string
|
|
||||||
default: ''
|
|
||||||
branch:
|
|
||||||
description: Existing cut branch (finalize retry only)
|
|
||||||
type: string
|
|
||||||
default: ''
|
|
||||||
version:
|
|
||||||
description: Existing cut version (finalize retry only)
|
|
||||||
type: string
|
|
||||||
default: ''
|
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types: [closed]
|
||||||
- closed
|
branches: [develop]
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
repository_dispatch:
|
|
||||||
types:
|
|
||||||
- qbit-rc-published
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
actions: read
|
|
||||||
checks: read
|
|
||||||
jobs:
|
jobs:
|
||||||
release-rc:
|
release-rc:
|
||||||
if: github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch'
|
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release:rc'))
|
||||||
|| (github.event_name == 'pull_request' && github.event.pull_request.merged
|
uses: QRun-IO/.github/.github/workflows/qbit-release-rc.yml@main
|
||||||
== true && github.event.pull_request.base.ref == 'develop' && contains(github.event.pull_request.labels.*.name,
|
|
||||||
'release:rc'))
|
|
||||||
uses: QRun-IO/qqq-orb/.github/workflows/qbit-release-rc.yml@cc30f599e63c8e41629c99d23395bac1adb8bc44
|
|
||||||
with:
|
with:
|
||||||
dry_run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || false
|
dry_run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }}
|
||||||
}}
|
|
||||||
finalize: ${{ github.event_name == 'repository_dispatch' || (github.event_name
|
|
||||||
== 'workflow_dispatch' && inputs.finalize) }}
|
|
||||||
recover: ${{ github.event_name == 'workflow_dispatch' && inputs.recover || false
|
|
||||||
}}
|
|
||||||
circle_build: ${{ github.event_name == 'workflow_dispatch' && inputs.circle_build
|
|
||||||
|| '' }}
|
|
||||||
merge_sha: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.merge_sha
|
|
||||||
|| inputs.merge_sha || '' }}
|
|
||||||
bump_sha: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.bump_sha
|
|
||||||
|| inputs.bump_sha || '' }}
|
|
||||||
branch: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.branch
|
|
||||||
|| inputs.branch || '' }}
|
|
||||||
version: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.version
|
|
||||||
|| inputs.version || '' }}
|
|
||||||
secrets: inherit
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
profile: qbit
|
|
||||||
orb_version: '0.8'
|
|
||||||
default_branch: develop
|
|
||||||
java_version: '21'
|
|
||||||
browsers: true
|
|
||||||
api_checks: false
|
|
||||||
docs_only: false
|
|
||||||
release_on_main: false
|
|
||||||
release_tag_policy: stable
|
|
||||||
test_branch_policy: non-release
|
|
||||||
publish:
|
|
||||||
snapshot: true
|
|
||||||
release_candidate: true
|
|
||||||
release: true
|
|
||||||
asciidoc: false
|
|
||||||
release_completion: true
|
|
||||||
@@ -5,17 +5,6 @@ and [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Reconciled legacy release-branch history with the current Gitea CI while retaining the develop
|
|
||||||
SNAPSHOT revision, so normal RC cuts can merge cleanly.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- SQL changelog headers: explanatory "-- Include it from the host..." comments were parsed as a
|
|
||||||
licensed Liquibase `include` directive. Replaced with neutral wording; changeset bodies and
|
|
||||||
schema are unchanged.
|
|
||||||
|
|
||||||
## [0.1.0] - Unreleased
|
## [0.1.0] - Unreleased
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ section E (summary in [docs/DESIGN.md](docs/DESIGN.md)).
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.kingsrook.qbits</groupId>
|
<groupId>com.kingsrook.qbits</groupId>
|
||||||
<artifactId>qbit-cluster</artifactId>
|
<artifactId>qbit-cluster</artifactId>
|
||||||
<version>0.1.0-RC.1</version><!-- first release; see GitHub releases for the latest -->
|
<version>0.1.0-RC.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,7 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<qqq.version>4.1.0-RC.26</qqq.version> <!-- feeds qbit-build-parent's qqq-bom-pom import -->
|
<revision>0.1.0-RC.1</revision>
|
||||||
<revision>0.3.0-SNAPSHOT</revision>
|
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<jacoco.version>0.8.15</jacoco.version>
|
<jacoco.version>0.8.15</jacoco.version>
|
||||||
@@ -29,7 +28,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.kingsrook</groupId>
|
<groupId>com.kingsrook</groupId>
|
||||||
<artifactId>qbit-build-parent</artifactId>
|
<artifactId>qbit-build-parent</artifactId>
|
||||||
<version>2.2.1</version>
|
<version>2.0.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.kingsrook.qbits</groupId>
|
<groupId>com.kingsrook.qbits</groupId>
|
||||||
@@ -212,7 +211,7 @@
|
|||||||
<activeByDefault>true</activeByDefault>
|
<activeByDefault>true</activeByDefault>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<qqq.snapshot.version>4.1.0-RC.26</qqq.snapshot.version>
|
<qqq.snapshot.version>4.1.0-SNAPSHOT</qqq.snapshot.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -225,6 +224,18 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>sonatype-snapshots</id>
|
||||||
|
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
@@ -67,6 +67,8 @@ public class ClusterNodesWidgetRenderer extends AbstractWidgetRenderer
|
|||||||
static final String NODE = "node";
|
static final String NODE = "node";
|
||||||
static final String STATUS = "status";
|
static final String STATUS = "status";
|
||||||
static final String HEARTBEAT = "heartbeat";
|
static final String HEARTBEAT = "heartbeat";
|
||||||
|
static final String WHERE = "where";
|
||||||
|
static final String VERSION = "version";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ public class ClusterNodesWidgetRenderer extends AbstractWidgetRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
TableData table = new TableData(null, List.of(
|
TableData table = new TableData(null, List.of(
|
||||||
column("Role", ROLE), column("Node", NODE), column("Status", STATUS), column("Last heartbeat", HEARTBEAT)), rows)
|
column("Role", ROLE), column("Node", NODE), column("Status", STATUS), column("Last heartbeat", HEARTBEAT), column("Where", WHERE), column("Version", VERSION)), rows)
|
||||||
.withNoRowsFoundHTML("No nodes are running. A node appears here once it starts with the Cluster qbit.")
|
.withNoRowsFoundHTML("No nodes are running. A node appears here once it starts with the Cluster qbit.")
|
||||||
.withRowsPerPage(50)
|
.withRowsPerPage(50)
|
||||||
.withHidePaginationDropdown(true);
|
.withHidePaginationDropdown(true);
|
||||||
@@ -110,29 +112,17 @@ public class ClusterNodesWidgetRenderer extends AbstractWidgetRenderer
|
|||||||
{
|
{
|
||||||
Map<String, Object> row = new LinkedHashMap<>();
|
Map<String, Object> row = new LinkedHashMap<>();
|
||||||
row.put(ROLE, roleLabel(role));
|
row.put(ROLE, roleLabel(role));
|
||||||
row.put(NODE, nodeText(node));
|
row.put(NODE, node.getValueString(ClusterTables.NODE_ID));
|
||||||
row.put(STATUS, statusText(node));
|
row.put(STATUS, statusText(node));
|
||||||
row.put(HEARTBEAT, age(node.getValueInstant(ClusterTables.HEARTBEAT_AT), now));
|
row.put(HEARTBEAT, age(node.getValueInstant(ClusterTables.HEARTBEAT_AT), now));
|
||||||
|
row.put(WHERE, Stream.of(node.getValueString(ClusterTables.K8S_NODE_NAME), node.getValueString(ClusterTables.ZONE), node.getValueString(ClusterTables.DEPLOYMENT))
|
||||||
|
.filter(StringUtils::hasContent).collect(Collectors.joining(", ")));
|
||||||
|
row.put(VERSION, node.getValueString(ClusterTables.VERSION) == null ? "" : node.getValueString(ClusterTables.VERSION));
|
||||||
return (row);
|
return (row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** The node id, with where it runs and its version folded in (four columns
|
|
||||||
** keep the table readable at every width): "web-7f9 (k8s-2, website-backend, 0.1.110)".
|
|
||||||
*******************************************************************************/
|
|
||||||
static String nodeText(QRecord node)
|
|
||||||
{
|
|
||||||
String details = Stream.of(node.getValueString(ClusterTables.K8S_NODE_NAME), node.getValueString(ClusterTables.ZONE), node.getValueString(ClusterTables.DEPLOYMENT),
|
|
||||||
node.getValueString(ClusterTables.VERSION))
|
|
||||||
.filter(StringUtils::hasContent).collect(Collectors.joining(", "));
|
|
||||||
String nodeId = node.getValueString(ClusterTables.NODE_ID);
|
|
||||||
return (details.isEmpty() ? nodeId : nodeId + " (" + details + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** "Up", "Draining", "Up, drain requested", "Lost".
|
** "Up", "Draining", "Up, drain requested", "Lost".
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
-- https://www.apache.org/licenses/LICENSE-2.0
|
-- https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
-- qbit-cluster schema (QRun-IO/qqq docs/specs/2026-10-15-cluster-ha-design.md section E).
|
-- qbit-cluster schema (QRun-IO/qqq docs/specs/2026-10-15-cluster-ha-design.md section E).
|
||||||
-- Load this file from the host's master changelog, then the defaults:
|
-- Include it from the host's master changelog, then the defaults:
|
||||||
--
|
--
|
||||||
-- - include: { file: db/liquibase/qbit-cluster/cluster.changelog.sql }
|
-- - include: { file: db/liquibase/qbit-cluster/cluster.changelog.sql }
|
||||||
-- - include: { file: db/liquibase/qbit-cluster/cluster-defaults.changelog.sql }
|
-- - include: { file: db/liquibase/qbit-cluster/cluster-defaults.changelog.sql }
|
||||||
|
|||||||
@@ -89,14 +89,7 @@ class ClusterQBitProducerTest extends BaseClusterTest
|
|||||||
assertThat(QAlertTypeMetaData.of(qInstance, ClusterAlerts.NODE_LOST)).isNotNull();
|
assertThat(QAlertTypeMetaData.of(qInstance, ClusterAlerts.NODE_LOST)).isNotNull();
|
||||||
assertThat(HealthChecksMetaData.ofOrWithNew(qInstance).getChecks()).anyMatch(check -> ClusterHeartbeatHealthCheck.NAME.equals(check.getName()));
|
assertThat(HealthChecksMetaData.ofOrWithNew(qInstance).getChecks()).anyMatch(check -> ClusterHeartbeatHealthCheck.NAME.equals(check.getName()));
|
||||||
assertThat(qInstance.getRuntimeServices()).extracting(reference -> reference.getName()).containsOnlyOnce(ClusterRuntimeService.class.getName());
|
assertThat(qInstance.getRuntimeServices()).extracting(reference -> reference.getName()).containsOnlyOnce(ClusterRuntimeService.class.getName());
|
||||||
////////////////////////////////////////////////////////////////////
|
assertThat(ClusterQBitProducer.version()).isEqualTo("0.1.0-RC.1");
|
||||||
// the version comes from the build (filtered qbit-cluster.properties) //
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
assertThat(ClusterQBitProducer.version()).matches("[0-9]+[.][0-9]+[.][0-9]+(-[A-Za-z0-9.]+)?");
|
|
||||||
if(System.getProperty("qbit.artifactVersion") != null)
|
|
||||||
{
|
|
||||||
assertThat(ClusterQBitProducer.version()).isEqualTo(System.getProperty("qbit.artifactVersion"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class ClusterSettingsWidgetHealthTest extends BaseClusterTest
|
|||||||
assertThat(rows.get(0).get("heartbeat")).isEqualTo("5 hours ago");
|
assertThat(rows.get(0).get("heartbeat")).isEqualTo("5 hours ago");
|
||||||
assertThat(rows.get(2).get("status")).isEqualTo("Up, drain requested");
|
assertThat(rows.get(2).get("status")).isEqualTo("Up, drain requested");
|
||||||
assertThat(rows.get(3).get("heartbeat")).isEqualTo("3 minutes ago");
|
assertThat(rows.get(3).get("heartbeat")).isEqualTo("3 minutes ago");
|
||||||
assertThat(table.getColumns()).as("four columns: readable at every width").hasSize(4);
|
assertThat(table.getColumns()).hasSize(6);
|
||||||
assertThat(lost).isNotNull();
|
assertThat(lost).isNotNull();
|
||||||
|
|
||||||
assertThat(ClusterNodesWidgetRenderer.class).isNotNull();
|
assertThat(ClusterNodesWidgetRenderer.class).isNotNull();
|
||||||
|
|||||||
Reference in new issue
Block a user