@payfit/nx-core 5.0.1 → 5.0.2-ephemeral-vibe-code-spacelift-stack-manager.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/executors/spacelift-stack-management/executor.d.ts +4 -0
- package/dist/src/executors/spacelift-stack-management/executor.js +180 -0
- package/dist/src/executors/spacelift-stack-management/executor.js.map +1 -0
- package/dist/src/executors/spacelift-stack-management/schema.json +31 -0
- package/package.json +1 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ExecutorContext } from '@nx/devkit';
|
|
2
|
+
import { SpaceliftStackManagementExecutorOptions, SpaceliftStackManagementExecutorSchema } from './schema';
|
|
3
|
+
declare const runExecutor: (options: SpaceliftStackManagementExecutorOptions, context: ExecutorContext) => Promise<SpaceliftStackManagementExecutorSchema>;
|
|
4
|
+
export default runExecutor;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs_1 = require("fs");
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const core_1 = require("@apollo/client/core");
|
|
6
|
+
const yaml_1 = require("yaml");
|
|
7
|
+
const logger_1 = require("../../utils/common/logger");
|
|
8
|
+
const graphql_service_1 = require("../../utils/spacelift/lib/graphql.service");
|
|
9
|
+
function getEnvVar(name) {
|
|
10
|
+
const value = process.env[name];
|
|
11
|
+
if (!value) {
|
|
12
|
+
throw new Error(`Missing env var ${name}`);
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function ensureSpaceliftAuthEnv() {
|
|
17
|
+
// Ensure required Spacelift credentials are provided
|
|
18
|
+
getEnvVar('SPACELIFT_KEY_ID');
|
|
19
|
+
getEnvVar('SPACELIFT_KEY_SECRET');
|
|
20
|
+
}
|
|
21
|
+
const CREATE_STACK = (0, core_1.gql) `
|
|
22
|
+
mutation CreateStack(
|
|
23
|
+
$input: StackInput!
|
|
24
|
+
$slug: String
|
|
25
|
+
$manageState: Boolean!
|
|
26
|
+
) {
|
|
27
|
+
stackCreate(input: $input, slug: $slug, manageState: $manageState) {
|
|
28
|
+
id
|
|
29
|
+
name
|
|
30
|
+
repository
|
|
31
|
+
branch
|
|
32
|
+
state
|
|
33
|
+
namespace
|
|
34
|
+
projectRoot
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
const UPDATE_STACK = (0, core_1.gql) `
|
|
39
|
+
mutation UpdateStack($id: ID!, $input: StackInput!) {
|
|
40
|
+
stackUpdate(id: $id, input: $input) {
|
|
41
|
+
id
|
|
42
|
+
name
|
|
43
|
+
repository
|
|
44
|
+
branch
|
|
45
|
+
state
|
|
46
|
+
namespace
|
|
47
|
+
projectRoot
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
const DELETE_STACK = (0, core_1.gql) `
|
|
52
|
+
mutation DeleteStack($id: ID!, $destroyResources: Boolean) {
|
|
53
|
+
stackDelete(id: $id, destroyResources: $destroyResources) {
|
|
54
|
+
id
|
|
55
|
+
name
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
const GET_STACK = (0, core_1.gql) `
|
|
60
|
+
query GetStack($id: ID!) {
|
|
61
|
+
stack(id: $id) {
|
|
62
|
+
id
|
|
63
|
+
name
|
|
64
|
+
repository
|
|
65
|
+
branch
|
|
66
|
+
administrative
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
const runExecutor = async (options, context) => {
|
|
71
|
+
try {
|
|
72
|
+
// Use default path if not provided
|
|
73
|
+
const configFile = options.configFile || 'spacelift.yaml';
|
|
74
|
+
const configPath = (0, path_1.resolve)(context.root, configFile);
|
|
75
|
+
logger_1.consola.info(`Reading stack configuration from: ${configPath}`);
|
|
76
|
+
const configContent = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
77
|
+
const config = (0, yaml_1.parse)(configContent);
|
|
78
|
+
logger_1.consola.box(`Creating Spacelift stack: ${config.name}`);
|
|
79
|
+
// Ensure authentication env vars are set (same pattern as other executors)
|
|
80
|
+
ensureSpaceliftAuthEnv();
|
|
81
|
+
// Initialize GraphQL service (handles JWT retrieval internally)
|
|
82
|
+
const graphQlService = new graphql_service_1.GraphQlService();
|
|
83
|
+
const action = options.action || 'update';
|
|
84
|
+
// Compute slug/ID from name for update/delete
|
|
85
|
+
const stackIdFromName = config.name
|
|
86
|
+
.trim()
|
|
87
|
+
.toLowerCase()
|
|
88
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
89
|
+
.replace(/(^-|-$)/g, '');
|
|
90
|
+
// Fetch current stack for update/delete paths to allow comparisons and avoid accidental changes
|
|
91
|
+
const currentStack = action !== 'create'
|
|
92
|
+
? (await graphQlService.query({
|
|
93
|
+
query: GET_STACK,
|
|
94
|
+
variables: { id: stackIdFromName },
|
|
95
|
+
})).stack
|
|
96
|
+
: undefined;
|
|
97
|
+
// Build the minimal required stack input
|
|
98
|
+
const stackInput = {
|
|
99
|
+
name: config.name,
|
|
100
|
+
repository: config.repository,
|
|
101
|
+
branch: config.branch,
|
|
102
|
+
// preserve existing administrative flag on update to avoid unintended changes
|
|
103
|
+
administrative: currentStack?.administrative ?? false,
|
|
104
|
+
};
|
|
105
|
+
logger_1.consola.info('Desired stack configuration (subset):', {
|
|
106
|
+
name: stackInput.name,
|
|
107
|
+
repository: stackInput.repository,
|
|
108
|
+
branch: stackInput.branch,
|
|
109
|
+
});
|
|
110
|
+
if (action === 'create') {
|
|
111
|
+
const result = await graphQlService.mutate({
|
|
112
|
+
mutation: CREATE_STACK,
|
|
113
|
+
variables: {
|
|
114
|
+
input: stackInput,
|
|
115
|
+
slug: undefined,
|
|
116
|
+
manageState: true,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const createdStack = result.stackCreate;
|
|
120
|
+
logger_1.consola.success(`Stack created successfully!`);
|
|
121
|
+
logger_1.consola.info(`Stack ID: ${createdStack.id}`);
|
|
122
|
+
return {
|
|
123
|
+
success: true,
|
|
124
|
+
stackId: createdStack.id,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (action === 'update') {
|
|
128
|
+
if (!currentStack) {
|
|
129
|
+
logger_1.consola.warn(`Stack ${stackIdFromName} not found. Nothing to update. Consider action=create if you want to create it.`);
|
|
130
|
+
return { success: true };
|
|
131
|
+
}
|
|
132
|
+
const skipIfUnchanged = options.skipIfUnchanged ?? true;
|
|
133
|
+
const isUnchanged = currentStack.name === stackInput.name &&
|
|
134
|
+
currentStack.repository === stackInput.repository &&
|
|
135
|
+
currentStack.branch === stackInput.branch;
|
|
136
|
+
if (skipIfUnchanged && isUnchanged) {
|
|
137
|
+
logger_1.consola.info('No changes detected. Skipping update.');
|
|
138
|
+
return { success: true, stackId: currentStack.id };
|
|
139
|
+
}
|
|
140
|
+
const result = await graphQlService.mutate({
|
|
141
|
+
mutation: UPDATE_STACK,
|
|
142
|
+
variables: {
|
|
143
|
+
id: stackIdFromName,
|
|
144
|
+
input: stackInput,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
const updatedStack = result.stackUpdate;
|
|
148
|
+
logger_1.consola.success(`Stack updated successfully!`);
|
|
149
|
+
logger_1.consola.info(`Stack ID: ${updatedStack.id}`);
|
|
150
|
+
return {
|
|
151
|
+
success: true,
|
|
152
|
+
stackId: updatedStack.id,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (action === 'delete') {
|
|
156
|
+
const result = await graphQlService.mutate({
|
|
157
|
+
mutation: DELETE_STACK,
|
|
158
|
+
variables: {
|
|
159
|
+
id: stackIdFromName,
|
|
160
|
+
destroyResources: options.destroyResources,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
const deletedStack = result.stackDelete;
|
|
164
|
+
logger_1.consola.success(`Stack deletion requested successfully!`);
|
|
165
|
+
return {
|
|
166
|
+
success: true,
|
|
167
|
+
stackId: deletedStack?.id,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`Unsupported action: ${action}`);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
logger_1.consola.error('Failed to create Spacelift stack:', error);
|
|
174
|
+
return {
|
|
175
|
+
success: false,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
exports.default = runExecutor;
|
|
180
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../src/executors/spacelift-stack-management/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"version": 2,
|
|
4
|
+
"title": "Spacelift Stack Management",
|
|
5
|
+
"description": "Create and manage Spacelift stacks from YAML configuration",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"configFile": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Path to the YAML configuration file containing stack definition",
|
|
11
|
+
"default": "spacelift.yaml"
|
|
12
|
+
},
|
|
13
|
+
"action": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Action to perform on the stack",
|
|
16
|
+
"enum": ["create", "update", "delete"],
|
|
17
|
+
"default": "update"
|
|
18
|
+
},
|
|
19
|
+
"destroyResources": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"description": "When deleting, also destroy resources",
|
|
22
|
+
"default": false
|
|
23
|
+
},
|
|
24
|
+
"skipIfUnchanged": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"description": "Skip update if YAML matches current stack",
|
|
27
|
+
"default": true
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"required": []
|
|
31
|
+
}
|