polyci 0.0.8 → 0.0.10

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.
Files changed (2) hide show
  1. package/dist/main.js +142 -141
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -133,91 +133,92 @@ function discoverModules(repoRoot, modulesRoot) {
133
133
  return modules;
134
134
  }
135
135
  function appendGlobalVariables(lines) {
136
- lines.push("variables:");
137
- lines.push(" IMAGE_LINUX: alpine:latest");
138
- lines.push(" IMAGE_NODE: node:alpine");
139
- lines.push(" IMAGE_GIT: alpine/git:latest");
140
- lines.push(" IMAGE_NGINX: nginx:alpine-slim");
141
- lines.push(" IMAGE_DOCKER: docker:latest");
142
- lines.push(" IMAGE_COMPOSE: docker:cli");
143
- lines.push(" GIT_PACKAGE: git");
144
- lines.push("");
145
- lines.push("stages:");
146
- lines.push(" - build");
147
- lines.push(" - test");
148
- lines.push(" - release");
149
- lines.push(" - publish");
150
- lines.push(" - deploy");
151
- lines.push("");
136
+ lines.push(`variables:`);
137
+ lines.push(` IMAGE_LINUX: alpine:latest`);
138
+ lines.push(` IMAGE_NODE: node:alpine`);
139
+ lines.push(` IMAGE_GIT: alpine/git:latest`);
140
+ lines.push(` IMAGE_NGINX: nginx:alpine-slim`);
141
+ lines.push(` IMAGE_DOCKER: docker:latest`);
142
+ lines.push(` IMAGE_COMPOSE: docker:cli`);
143
+ lines.push(` GIT_PACKAGE: git`);
144
+ lines.push(``);
145
+ lines.push(`stages:`);
146
+ lines.push(` - build`);
147
+ lines.push(` - test`);
148
+ lines.push(` - release`);
149
+ lines.push(` - publish`);
150
+ lines.push(` - deploy`);
151
+ lines.push(``);
152
152
  }
153
153
  function appendModuleBuildJob(lines, module) {
154
154
  lines.push(`${module.jobId}_build:`);
155
- lines.push(" stage: build");
156
- lines.push(" rules:");
157
- lines.push(" - changes:");
155
+ lines.push(` stage: build`);
156
+ lines.push(` rules:`);
157
+ lines.push(` - changes:`);
158
158
  lines.push(` - ${module.modulePath}/**/*`);
159
- lines.push(" image: $IMAGE_NODE");
160
- lines.push(" variables:");
159
+ lines.push(` image: $IMAGE_NODE`);
160
+ lines.push(` variables:`);
161
161
  lines.push(` MODULE_NAME: ${module.moduleName}`);
162
162
  lines.push(` MODULE_PATH: ${module.modulePath}`);
163
163
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
164
- lines.push(" script:");
165
- lines.push(" - cd $MODULE_PATH");
166
- lines.push(" - npm ci");
167
- lines.push(" - npm run build");
168
- lines.push(" artifacts:");
169
- lines.push(" paths:");
170
- lines.push(" - $MODULE_PATH/dist/");
171
- lines.push(" expire_in: 1 day");
172
- lines.push("");
164
+ lines.push(` script:`);
165
+ lines.push(` - cd $MODULE_PATH`);
166
+ lines.push(` - npm ci`);
167
+ lines.push(` - npm run build`);
168
+ lines.push(` artifacts:`);
169
+ lines.push(` paths:`);
170
+ lines.push(` - $MODULE_PATH/dist/`);
171
+ lines.push(` expire_in: 1 day`);
172
+ lines.push(``);
173
173
  }
174
174
  function appendModuleTestJob(lines, module) {
175
175
  lines.push(`${module.jobId}_test:`);
176
- lines.push(" stage: test");
177
- lines.push(" rules:");
178
- lines.push(" - changes:");
176
+ lines.push(` stage: test`);
177
+ lines.push(` rules:`);
178
+ lines.push(` - changes:`);
179
179
  lines.push(` - ${module.modulePath}/**/*`);
180
- lines.push(" needs:");
180
+ lines.push(` needs:`);
181
181
  lines.push(` - job: ${module.jobId}_build`);
182
- lines.push(" image: $IMAGE_LINUX");
183
- lines.push(" variables:");
182
+ lines.push(` image: $IMAGE_LINUX`);
183
+ lines.push(` variables:`);
184
184
  lines.push(` MODULE_NAME: ${module.moduleName}`);
185
185
  lines.push(` MODULE_PATH: ${module.modulePath}`);
186
186
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
187
- lines.push(" script:");
188
- lines.push(" - cd $MODULE_PATH");
189
- lines.push(' - echo "test is tasty"');
190
- lines.push("");
187
+ lines.push(` script:`);
188
+ lines.push(` - cd $MODULE_PATH`);
189
+ lines.push(` - echo "test is tasty"`);
190
+ lines.push(``);
191
191
  }
192
192
  function appendModuleReleaseJob(lines, module) {
193
193
  lines.push(`${module.jobId}_release:`);
194
- lines.push(" stage: release");
195
- lines.push(" rules:");
196
- lines.push(" - changes:");
194
+ lines.push(` stage: release`);
195
+ lines.push(` rules:`);
196
+ lines.push(` - changes:`);
197
197
  lines.push(` - ${module.modulePath}/**/*`);
198
- lines.push(" needs:");
198
+ lines.push(` needs:`);
199
199
  lines.push(` - job: ${module.jobId}_build`);
200
200
  lines.push(` - job: ${module.jobId}_test`);
201
- lines.push(" image: $IMAGE_NODE");
202
- lines.push(" variables:");
201
+ lines.push(` image: $IMAGE_NODE`);
202
+ lines.push(` variables:`);
203
203
  lines.push(` MODULE_NAME: ${module.moduleName}`);
204
204
  lines.push(` MODULE_PATH: ${module.modulePath}`);
205
205
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
206
- lines.push(" script:");
207
- lines.push(" - apk update");
208
- lines.push(" - apk add $GIT_PACKAGE");
209
- lines.push(" - cp -r ci $MODULE_PATH/ci");
210
- lines.push(" - cd $MODULE_PATH");
211
- lines.push(" - npm ci");
212
- lines.push(" - npx semalease semalease.env");
213
- lines.push(" - source semalease.env");
214
- lines.push(" - |");
206
+ lines.push(` script:`);
207
+ lines.push(` - apk update`);
208
+ lines.push(` - apk add $GIT_PACKAGE`);
209
+ lines.push(` - cp -r ci $MODULE_PATH/ci`);
210
+ lines.push(` - cd $MODULE_PATH`);
211
+ lines.push(` - npm ci`);
212
+ lines.push(` - git tag -l "ui-v*-$CI_COMMIT_BRANCH-*"`);
213
+ lines.push(` - npx semalease --tag-pattern "^${module.moduleName}-v(?<version>\\d+(\\.\\d+)*)-$CI_COMMIT_BRANCH-(?<increment>\\d+(\\.\\d+)*)$" semalease.env`);
214
+ lines.push(` - source semalease.env`);
215
+ lines.push(` - |`);
215
216
  lines.push(` if [ "$CI_COMMIT_BRANCH" = "main" ]; then`);
216
217
  lines.push(` PACKAGE_VERSION="$NEXT_VERSION"`);
217
218
  lines.push(` else`);
218
219
  lines.push(` PACKAGE_VERSION="$NEXT_VERSION-$CI_COMMIT_BRANCH-$NEXT_INCREMENT"`);
219
220
  lines.push(` fi`);
220
- lines.push(" - |");
221
+ lines.push(` - |`);
221
222
  lines.push(` if [ "$MODULE_TYPE" = "node-express" ]; then`);
222
223
  lines.push(` node -e "const fs=require('fs'); const pkg=JSON.parse(fs.readFileSync('package.json','utf8')); pkg.version=process.env.PACKAGE_VERSION; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\\n');"`);
223
224
  lines.push(` node ci/prepare-deploy-variables.js --instance-branch $CI_COMMIT_BRANCH`);
@@ -237,70 +238,70 @@ function appendModuleReleaseJob(lines, module) {
237
238
  lines.push(` - $MODULE_PATH/semalease.env`);
238
239
  lines.push(` - $MODULE_PATH/deploy.env`);
239
240
  lines.push(` expire_in: 1 day`);
240
- lines.push("");
241
+ lines.push(``);
241
242
  }
242
243
  function appendGlobalReleaseJob(lines, modules, mainBranch, tagTemplate, branchTagTemplate) {
243
- lines.push("release_and_tag:");
244
- lines.push(" stage: release");
245
- lines.push(" needs:");
244
+ lines.push(`release_and_tag:`);
245
+ lines.push(` stage: release`);
246
+ lines.push(` needs:`);
246
247
  for (const module of modules) {
247
248
  lines.push(` - job: ${module.jobId}_release`);
248
249
  lines.push(` optional: true`);
249
250
  }
250
- lines.push(" image: $IMAGE_NODE");
251
- lines.push(" variables:");
252
- lines.push(" GITLAB_TOKEN: $SEMANTIC_RELEASE_TOKEN # Used to push release commits/tags.");
253
- lines.push(" script:");
254
- lines.push(" - apk update");
255
- lines.push(" - apk add $GIT_PACKAGE");
256
- lines.push(" - set -euo pipefail");
257
- lines.push(" - git config user.email \"polyci@anarun.net\"");
258
- lines.push(" - git config user.name \"polyci\"");
259
- lines.push(" - git remote set-url origin \"https://oauth2:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"");
260
- lines.push(" - TAG_CREATED=false");
261
- lines.push("");
251
+ lines.push(` image: $IMAGE_NODE`);
252
+ lines.push(` variables:`);
253
+ lines.push(` GITLAB_TOKEN: $SEMANTIC_RELEASE_TOKEN # Used to push release commits/tags.`);
254
+ lines.push(` script:`);
255
+ lines.push(` - apk update`);
256
+ lines.push(` - apk add $GIT_PACKAGE`);
257
+ lines.push(` - set -euo pipefail`);
258
+ lines.push(` - git config user.email "polyci@anarun.net"`);
259
+ lines.push(` - git config user.name "polyci"`);
260
+ lines.push(` - git remote set-url origin "https://oauth2:\${GITLAB_TOKEN}@\${CI_SERVER_HOST}/\${CI_PROJECT_PATH}.git"`);
261
+ lines.push(` - TAG_CREATED=false`);
262
+ lines.push(``);
262
263
  for (const module of modules) {
263
264
  lines.push(` - echo "Tagging release for ${module.moduleName} (${module.modulePath})"`);
264
- lines.push(" - |");
265
+ lines.push(` - |`);
265
266
  lines.push(` if [ -f "${module.modulePath}/semalease.env" ]; then`);
266
267
  lines.push(` . "${module.modulePath}/semalease.env"`);
267
- lines.push(" TAG_NAME=\"\"");
268
+ lines.push(` TAG_NAME=""`);
268
269
  lines.push(` if [ "$CI_COMMIT_BRANCH" = "${mainBranch}" ]; then`);
269
- lines.push(" if [ \"${NEXT_VERSION:-}\" != \"${LATEST_VERSION:-}\" ]; then");
270
+ lines.push(` if [ "\${NEXT_VERSION:-}" != "\${LATEST_VERSION:-}" ]; then`);
270
271
  lines.push(` TAG_NAME="${applyTagTemplate(tagTemplate, module.moduleName)}"`);
271
- lines.push(" else");
272
+ lines.push(` else`);
272
273
  lines.push(` echo "Version did not change for ${module.moduleName} on branch $CI_COMMIT_BRANCH, skipping tag"`);
273
- lines.push(" fi");
274
- lines.push(" else");
275
- lines.push(" if [ \"${NEXT_VERSION:-}\" != \"${LATEST_VERSION:-}\" ] || [ \"${NEXT_INCREMENT:-}\" != \"${LATEST_INCREMENT:-}\" ]; then");
274
+ lines.push(` fi`);
275
+ lines.push(` else`);
276
+ lines.push(` if [ "\${NEXT_VERSION:-}" != "\${LATEST_VERSION:-}" ] || [ "\${NEXT_INCREMENT:-}" != "\${LATEST_INCREMENT:-}" ]; then`);
276
277
  lines.push(` TAG_NAME="${applyTagTemplate(branchTagTemplate, module.moduleName)}"`);
277
- lines.push(" else");
278
+ lines.push(` else`);
278
279
  lines.push(` echo "Version/increment did not change for ${module.moduleName} on branch $CI_COMMIT_BRANCH, skipping tag"`);
279
- lines.push(" fi");
280
- lines.push(" fi");
281
- lines.push(" if [ \"$TAG_NAME\" != \"\" ]; then");
280
+ lines.push(` fi`);
281
+ lines.push(` fi`);
282
+ lines.push(` if [ "$TAG_NAME" != "" ]; then`);
282
283
  if (module.moduleType === "node-express") {
283
284
  lines.push(` git add "${module.modulePath}/package.json"`);
284
285
  }
285
286
  else if (module.moduleType === "node-vite") {
286
287
  lines.push(` git add "${module.modulePath}/package.json" "${module.modulePath}/public/release.json"`);
287
288
  }
288
- lines.push(" git tag \"$TAG_NAME\"");
289
- lines.push(" TAG_CREATED=true");
290
- lines.push(" fi");
291
- lines.push(" else");
289
+ lines.push(` git tag "$TAG_NAME"`);
290
+ lines.push(` TAG_CREATED=true`);
291
+ lines.push(` fi`);
292
+ lines.push(` else`);
292
293
  lines.push(` echo "Missing ${module.modulePath}/semalease.env, skipping ${module.moduleName}"`);
293
- lines.push(" fi");
294
+ lines.push(` fi`);
294
295
  }
295
- lines.push("");
296
- lines.push(" - |");
297
- lines.push(" if [ \"$TAG_CREATED\" = true ]; then");
298
- lines.push(" git commit -m \"release: update affected modules\"");
299
- lines.push(" git push origin HEAD");
300
- lines.push(" git push origin --tags");
301
- lines.push(" else");
302
- lines.push(" echo \"No new tags created; skipping commit/push\"");
303
- lines.push(" fi");
296
+ lines.push(``);
297
+ lines.push(` - |`);
298
+ lines.push(` if [ "$TAG_CREATED" = true ]; then`);
299
+ lines.push(` git commit -m "release: update affected modules"`);
300
+ lines.push(` git push origin HEAD`);
301
+ lines.push(` git push origin --tags`);
302
+ lines.push(` else`);
303
+ lines.push(` echo "No new tags created; skipping commit/push"`);
304
+ lines.push(` fi`);
304
305
  lines.push(` artifacts:`);
305
306
  lines.push(` paths:`);
306
307
  for (const module of modules) {
@@ -308,66 +309,66 @@ function appendGlobalReleaseJob(lines, modules, mainBranch, tagTemplate, branchT
308
309
  lines.push(` - ${module.modulePath}/deploy.env`);
309
310
  }
310
311
  lines.push(` expire_in: 1 day`);
311
- lines.push("");
312
+ lines.push(``);
312
313
  }
313
314
  function appendModulePublishJob(lines, module) {
314
315
  lines.push(`${module.jobId}_publish:`);
315
- lines.push(" stage: publish");
316
- lines.push(" rules:");
317
- lines.push(" - changes:");
316
+ lines.push(` stage: publish`);
317
+ lines.push(` rules:`);
318
+ lines.push(` - changes:`);
318
319
  lines.push(` - ${module.modulePath}/**/*`);
319
- lines.push(" needs:");
320
+ lines.push(` needs:`);
320
321
  lines.push(` - job: ${module.jobId}_test`);
321
- lines.push(" - job: release_and_tag");
322
- lines.push(" image: $IMAGE_DOCKER");
323
- lines.push(" variables:");
322
+ lines.push(` - job: release_and_tag`);
323
+ lines.push(` image: $IMAGE_DOCKER`);
324
+ lines.push(` variables:`);
324
325
  lines.push(` MODULE_NAME: ${module.moduleName}`);
325
326
  lines.push(` MODULE_PATH: ${module.modulePath}`);
326
327
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
327
- lines.push(" script:");
328
- lines.push(" - cp -r ci $MODULE_PATH/ci");
329
- lines.push(" - cd $MODULE_PATH");
330
- lines.push(" - source deploy.env");
331
- lines.push(" - npm ci");
332
- lines.push(" - cp ci/$MODULE_TYPE/Dockerfile .");
333
- lines.push(" - docker build --tag $CI_REGISTRY_IMAGE/$MODULE_NAME:v$INSTANCE_VERSION .");
334
- lines.push(" - docker push $CI_REGISTRY_IMAGE/$MODULE_NAME:v$INSTANCE_VERSION");
335
- lines.push(" artifacts:");
336
- lines.push(" reports:");
337
- lines.push(" dotenv: $MODULE_PATH/deploy.env");
338
- lines.push(" expire_in: 1 day");
339
- lines.push("");
328
+ lines.push(` script:`);
329
+ lines.push(` - cp -r ci $MODULE_PATH/ci`);
330
+ lines.push(` - cd $MODULE_PATH`);
331
+ lines.push(` - source deploy.env`);
332
+ lines.push(` - npm ci`);
333
+ lines.push(` - cp ci/$MODULE_TYPE/Dockerfile .`);
334
+ lines.push(` - docker build --tag $CI_REGISTRY_IMAGE/$MODULE_NAME:v$INSTANCE_VERSION .`);
335
+ lines.push(` - docker push $CI_REGISTRY_IMAGE/$MODULE_NAME:v$INSTANCE_VERSION`);
336
+ lines.push(` artifacts:`);
337
+ lines.push(` reports:`);
338
+ lines.push(` dotenv: $MODULE_PATH/deploy.env`);
339
+ lines.push(` expire_in: 1 day`);
340
+ lines.push(``);
340
341
  }
341
342
  function appendModuleDeployJob(lines, module) {
342
343
  lines.push(`${module.jobId}_deploy:`);
343
- lines.push(" stage: deploy");
344
- lines.push(" rules:");
345
- lines.push(" - changes:");
344
+ lines.push(` stage: deploy`);
345
+ lines.push(` rules:`);
346
+ lines.push(` - changes:`);
346
347
  lines.push(` - ${module.modulePath}/**/*`);
347
- lines.push(" needs:");
348
+ lines.push(` needs:`);
348
349
  lines.push(` - job: ${module.jobId}_publish`);
349
- lines.push(" image: $IMAGE_COMPOSE");
350
- lines.push(" variables:");
350
+ lines.push(` image: $IMAGE_COMPOSE`);
351
+ lines.push(` variables:`);
351
352
  lines.push(` MODULE_NAME: ${module.moduleName}`);
352
353
  lines.push(` MODULE_PATH: ${module.modulePath}`);
353
354
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
354
- lines.push(" script:");
355
- lines.push(" - apk add --update --no-cache openssh");
356
- lines.push(" - eval $(ssh-agent -s)");
357
- lines.push(' - echo "$DEPLOY_USER_KEY" | tr -d \'\\r\' | ssh-add -');
358
- lines.push(" - mkdir -p ~/.ssh");
359
- lines.push(" - chmod 700 ~/.ssh");
360
- lines.push(" - ssh-keyscan -p $DEPLOY_PORT $DEPLOY_ADDRESS >> ~/.ssh/known_hosts");
361
- lines.push(" - chmod 644 ~/.ssh/known_hosts");
362
- lines.push(" - echo -n $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY");
363
- lines.push(' - docker context create remote --docker "host=ssh://$DEPLOY_USER@$DEPLOY_ADDRESS:$DEPLOY_PORT"');
364
- lines.push(" - docker context use remote");
365
- lines.push(" - cd ci");
366
- lines.push(" - docker compose -p $INSTANCE_CONTAINER down --remove-orphans");
367
- lines.push(" - docker compose pull");
368
- lines.push(" - docker compose -p $INSTANCE_CONTAINER up -d");
369
- lines.push(" - rm -rf ~/.ssh");
370
- lines.push("");
355
+ lines.push(` script:`);
356
+ lines.push(` - apk add --update --no-cache openssh`);
357
+ lines.push(` - eval $(ssh-agent -s)`);
358
+ lines.push(` - echo "$DEPLOY_USER_KEY" | tr -d '\\r' | ssh-add -`);
359
+ lines.push(` - mkdir -p ~/.ssh`);
360
+ lines.push(` - chmod 700 ~/.ssh`);
361
+ lines.push(` - ssh-keyscan -p $DEPLOY_PORT $DEPLOY_ADDRESS >> ~/.ssh/known_hosts`);
362
+ lines.push(` - chmod 644 ~/.ssh/known_hosts`);
363
+ lines.push(` - echo -n $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY`);
364
+ lines.push(` - docker context create remote --docker "host=ssh://$DEPLOY_USER@$DEPLOY_ADDRESS:$DEPLOY_PORT"`);
365
+ lines.push(` - docker context use remote`);
366
+ lines.push(` - cd ci`);
367
+ lines.push(` - docker compose -p $INSTANCE_CONTAINER down --remove-orphans`);
368
+ lines.push(` - docker compose pull`);
369
+ lines.push(` - docker compose -p $INSTANCE_CONTAINER up -d`);
370
+ lines.push(` - rm -rf ~/.ssh`);
371
+ lines.push(``);
371
372
  }
372
373
  function buildPipeline(modules, mainBranch, tagTemplate, branchTagTemplate) {
373
374
  const lines = [];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "polyci",
3
3
  "description": "Monorepo CI/CD utilities.",
4
- "version": "0.0.8",
4
+ "version": "0.0.10",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "author": "Alexander Tsarev",