polyci 0.0.7 → 0.0.9

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 +152 -150
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -133,90 +133,91 @@ 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(` - npx semalease --tag-pattern "^${module.moduleName}-v(?<version>\\d+(\\.\\d+)*)-$CI_COMMIT_BRANCH-(?<increment>\\d+(\\.\\d+)*)$" semalease.env`);
213
+ lines.push(` - source semalease.env`);
214
+ lines.push(` - |`);
215
215
  lines.push(` if [ "$CI_COMMIT_BRANCH" = "main" ]; then`);
216
216
  lines.push(` PACKAGE_VERSION="$NEXT_VERSION"`);
217
217
  lines.push(` else`);
218
218
  lines.push(` PACKAGE_VERSION="$NEXT_VERSION-$CI_COMMIT_BRANCH-$NEXT_INCREMENT"`);
219
219
  lines.push(` fi`);
220
+ lines.push(` - |`);
220
221
  lines.push(` if [ "$MODULE_TYPE" = "node-express" ]; then`);
221
222
  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');"`);
222
223
  lines.push(` node ci/prepare-deploy-variables.js --instance-branch $CI_COMMIT_BRANCH`);
@@ -236,69 +237,70 @@ function appendModuleReleaseJob(lines, module) {
236
237
  lines.push(` - $MODULE_PATH/semalease.env`);
237
238
  lines.push(` - $MODULE_PATH/deploy.env`);
238
239
  lines.push(` expire_in: 1 day`);
239
- lines.push("");
240
+ lines.push(``);
240
241
  }
241
242
  function appendGlobalReleaseJob(lines, modules, mainBranch, tagTemplate, branchTagTemplate) {
242
- lines.push("release_and_tag:");
243
- lines.push(" stage: release");
244
- lines.push(" needs:");
243
+ lines.push(`release_and_tag:`);
244
+ lines.push(` stage: release`);
245
+ lines.push(` needs:`);
245
246
  for (const module of modules) {
246
247
  lines.push(` - job: ${module.jobId}_release`);
247
248
  lines.push(` optional: true`);
248
249
  }
249
- lines.push(" image: $IMAGE_NODE");
250
- lines.push(" variables:");
251
- lines.push(" GITLAB_TOKEN: $SEMANTIC_RELEASE_TOKEN # Used to push release commits/tags.");
252
- lines.push(" script:");
253
- lines.push(" - apk update");
254
- lines.push(" - apk add $GIT_PACKAGE");
255
- lines.push(" - |");
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("");
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(``);
262
262
  for (const module of modules) {
263
- lines.push(` echo "Tagging release for ${module.moduleName} (${module.modulePath})"`);
264
- lines.push(` if [ -f "${module.modulePath}/semalease.env" ]; then`);
265
- lines.push(` . "${module.modulePath}/semalease.env"`);
266
- lines.push(" TAG_NAME=\"\"");
267
- lines.push(` if [ "$CI_COMMIT_BRANCH" = "${mainBranch}" ]; then`);
268
- lines.push(" if [ \"${NEXT_VERSION:-}\" != \"${LATEST_VERSION:-}\" ]; then");
269
- lines.push(` TAG_NAME="${applyTagTemplate(tagTemplate, module.moduleName)}"`);
270
- lines.push(" else");
271
- lines.push(` echo "Version did not change for ${module.moduleName} on branch $CI_COMMIT_BRANCH, skipping tag"`);
272
- lines.push(" fi");
273
- lines.push(" else");
274
- lines.push(" if [ \"${NEXT_VERSION:-}\" != \"${LATEST_VERSION:-}\" ] || [ \"${NEXT_INCREMENT:-}\" != \"${LATEST_INCREMENT:-}\" ]; then");
275
- lines.push(` TAG_NAME="${applyTagTemplate(branchTagTemplate, module.moduleName)}"`);
276
- lines.push(" else");
277
- lines.push(` echo "Version/increment did not change for ${module.moduleName} on branch $CI_COMMIT_BRANCH, skipping tag"`);
278
- lines.push(" fi");
279
- lines.push(" fi");
280
- lines.push(" if [ \"$TAG_NAME\" != \"\" ]; then");
263
+ lines.push(` - echo "Tagging release for ${module.moduleName} (${module.modulePath})"`);
264
+ lines.push(` - |`);
265
+ lines.push(` if [ -f "${module.modulePath}/semalease.env" ]; then`);
266
+ lines.push(` . "${module.modulePath}/semalease.env"`);
267
+ lines.push(` TAG_NAME=""`);
268
+ lines.push(` if [ "$CI_COMMIT_BRANCH" = "${mainBranch}" ]; then`);
269
+ lines.push(` if [ "\${NEXT_VERSION:-}" != "\${LATEST_VERSION:-}" ]; then`);
270
+ lines.push(` TAG_NAME="${applyTagTemplate(tagTemplate, module.moduleName)}"`);
271
+ lines.push(` else`);
272
+ 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`);
276
+ lines.push(` TAG_NAME="${applyTagTemplate(branchTagTemplate, module.moduleName)}"`);
277
+ lines.push(` else`);
278
+ 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`);
281
282
  if (module.moduleType === "node-express") {
282
- lines.push(` git add "${module.modulePath}/package.json"`);
283
+ lines.push(` git add "${module.modulePath}/package.json"`);
283
284
  }
284
285
  else if (module.moduleType === "node-vite") {
285
- lines.push(` git add "${module.modulePath}/package.json" "${module.modulePath}/public/release.json"`);
286
+ lines.push(` git add "${module.modulePath}/package.json" "${module.modulePath}/public/release.json"`);
286
287
  }
287
- lines.push(" git tag \"$TAG_NAME\"");
288
- lines.push(" TAG_CREATED=true");
289
- lines.push(" fi");
290
- lines.push(" else");
291
- lines.push(` echo "Missing ${module.modulePath}/semalease.env, skipping ${module.moduleName}"`);
292
- lines.push(" fi");
288
+ lines.push(` git tag "$TAG_NAME"`);
289
+ lines.push(` TAG_CREATED=true`);
290
+ lines.push(` fi`);
291
+ lines.push(` else`);
292
+ lines.push(` echo "Missing ${module.modulePath}/semalease.env, skipping ${module.moduleName}"`);
293
+ lines.push(` fi`);
293
294
  }
294
- lines.push("");
295
- lines.push(" if [ \"$TAG_CREATED\" = true ]; then");
296
- lines.push(" git commit -m \"release: update affected modules\"");
297
- lines.push(" git push origin HEAD");
298
- lines.push(" git push origin --tags");
299
- lines.push(" else");
300
- lines.push(" echo \"No new tags created; skipping commit/push\"");
301
- lines.push(" fi");
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`);
302
304
  lines.push(` artifacts:`);
303
305
  lines.push(` paths:`);
304
306
  for (const module of modules) {
@@ -306,66 +308,66 @@ function appendGlobalReleaseJob(lines, modules, mainBranch, tagTemplate, branchT
306
308
  lines.push(` - ${module.modulePath}/deploy.env`);
307
309
  }
308
310
  lines.push(` expire_in: 1 day`);
309
- lines.push("");
311
+ lines.push(``);
310
312
  }
311
313
  function appendModulePublishJob(lines, module) {
312
314
  lines.push(`${module.jobId}_publish:`);
313
- lines.push(" stage: publish");
314
- lines.push(" rules:");
315
- lines.push(" - changes:");
315
+ lines.push(` stage: publish`);
316
+ lines.push(` rules:`);
317
+ lines.push(` - changes:`);
316
318
  lines.push(` - ${module.modulePath}/**/*`);
317
- lines.push(" needs:");
319
+ lines.push(` needs:`);
318
320
  lines.push(` - job: ${module.jobId}_test`);
319
- lines.push(" - job: release_and_tag");
320
- lines.push(" image: $IMAGE_DOCKER");
321
- lines.push(" variables:");
321
+ lines.push(` - job: release_and_tag`);
322
+ lines.push(` image: $IMAGE_DOCKER`);
323
+ lines.push(` variables:`);
322
324
  lines.push(` MODULE_NAME: ${module.moduleName}`);
323
325
  lines.push(` MODULE_PATH: ${module.modulePath}`);
324
326
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
325
- lines.push(" script:");
326
- lines.push(" - cp -r ci $MODULE_PATH/ci");
327
- lines.push(" - cd $MODULE_PATH");
328
- lines.push(" - source deploy.env");
329
- lines.push(" - npm ci");
330
- lines.push(" - cp ci/$MODULE_TYPE/Dockerfile .");
331
- lines.push(" - docker build --tag $CI_REGISTRY_IMAGE/$MODULE_NAME:v$INSTANCE_VERSION .");
332
- lines.push(" - docker push $CI_REGISTRY_IMAGE/$MODULE_NAME:v$INSTANCE_VERSION");
333
- lines.push(" artifacts:");
334
- lines.push(" reports:");
335
- lines.push(" dotenv: $MODULE_PATH/deploy.env");
336
- lines.push(" expire_in: 1 day");
337
- lines.push("");
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(``);
338
340
  }
339
341
  function appendModuleDeployJob(lines, module) {
340
342
  lines.push(`${module.jobId}_deploy:`);
341
- lines.push(" stage: deploy");
342
- lines.push(" rules:");
343
- lines.push(" - changes:");
343
+ lines.push(` stage: deploy`);
344
+ lines.push(` rules:`);
345
+ lines.push(` - changes:`);
344
346
  lines.push(` - ${module.modulePath}/**/*`);
345
- lines.push(" needs:");
347
+ lines.push(` needs:`);
346
348
  lines.push(` - job: ${module.jobId}_publish`);
347
- lines.push(" image: $IMAGE_COMPOSE");
348
- lines.push(" variables:");
349
+ lines.push(` image: $IMAGE_COMPOSE`);
350
+ lines.push(` variables:`);
349
351
  lines.push(` MODULE_NAME: ${module.moduleName}`);
350
352
  lines.push(` MODULE_PATH: ${module.modulePath}`);
351
353
  lines.push(` MODULE_TYPE: ${module.moduleType}`);
352
- lines.push(" script:");
353
- lines.push(" - apk add --update --no-cache openssh");
354
- lines.push(" - eval $(ssh-agent -s)");
355
- lines.push(' - echo "$DEPLOY_USER_KEY" | tr -d \'\\r\' | ssh-add -');
356
- lines.push(" - mkdir -p ~/.ssh");
357
- lines.push(" - chmod 700 ~/.ssh");
358
- lines.push(" - ssh-keyscan -p $DEPLOY_PORT $DEPLOY_ADDRESS >> ~/.ssh/known_hosts");
359
- lines.push(" - chmod 644 ~/.ssh/known_hosts");
360
- lines.push(" - echo -n $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY");
361
- lines.push(' - docker context create remote --docker "host=ssh://$DEPLOY_USER@$DEPLOY_ADDRESS:$DEPLOY_PORT"');
362
- lines.push(" - docker context use remote");
363
- lines.push(" - cd ci");
364
- lines.push(" - docker compose -p $INSTANCE_CONTAINER down --remove-orphans");
365
- lines.push(" - docker compose pull");
366
- lines.push(" - docker compose -p $INSTANCE_CONTAINER up -d");
367
- lines.push(" - rm -rf ~/.ssh");
368
- lines.push("");
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(``);
369
371
  }
370
372
  function buildPipeline(modules, mainBranch, tagTemplate, branchTagTemplate) {
371
373
  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.7",
4
+ "version": "0.0.9",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "author": "Alexander Tsarev",