ops: schedd 0.7.0 (cancelUrl-канал), dry-run мок-publish оба зелёные, ТЗ worker-cancel-url

- schedd.Dockerfile: daemon 0.6.0 → 0.7.0 (cancel-канал: cancelUrl в accepted-envelope)
- tasks.json: publish+githubDistro с dryRun:true у обеих тасок (мок-publish dry, ноль мутаций)
- compose: DRY_RUN=1 безопасный дефолт; ozon state персистентен (bind-mount, noop работает)
- тесты: мок-publish dry — yandex 13/13, ozon 10/10, GitHub/Gitea/verdaccio чисто
- баг cancel воспроизведён (воркер продолжает после cancel) → ТЗ worker-cancel-url обеим командам
This commit is contained in:
2026-08-20 23:49:51 +03:00
parent a5ee6c88a7
commit 5d57f49e80
6 changed files with 138447 additions and 10 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
{
"lastSpecSha256": "8756930c9921a569473dee082586af4e390f45497d4a1dd3ba4b7b622e232822",
"recipeVersion": "1.3.0",
"recipeVersion": "1.4.0",
"lastSpecSnapshot": "2026-08-20",
"lastRunAt": "2026-08-20T10:19:48.760Z"
"lastRunAt": "2026-08-20T20:41:06.064Z",
"publishedVersion": "0.1.0"
}

View File

@@ -57,6 +57,10 @@ services:
UNISENDER_FROM: noreply@snolla.com
NPM_TOKEN: ${NPM_TOKEN:-}
GITHUB_TOKEN: ${GITHUB_TOKEN:-}
# мок-publish: verdaccio (npm) + Gitea (репо/релизы)
PUBLISH_REGISTRY: ${PUBLISH_REGISTRY:-}
PUBLISH_REMOTE_BASE: ${PUBLISH_REMOTE_BASE:-}
PUBLISH_GH_API_BASE: ${PUBLISH_GH_API_BASE:-}
volumes:
- ./data-ym:/app/data
ports:
@@ -76,8 +80,11 @@ services:
# внутренний крон не нужен — расписанием рулит sched (ozon 2:00).
# 31 февраля не наступает никогда: страховая от двойного запуска.
CRON_SCHEDULE: "0 0 29 2 *"
# персистентность state/output на хосте (фикс state-output-in-image-layer):
# /app/data — единая точка, bind-mount ./data-ozon ниже.
STATE_FILE: /app/data/state.json
LOCK_FILE: /app/data/pipeline.lock
OUTPUT_DIR: /app/data/output/typescript
# безопасный дефолт: DRY_RUN=1. Реальный мок-publish — только явным data.dryRun=false в таске.
DRY_RUN: "1"
BROWSER_CDP_URL: http://browser:9222
NTFY_URL: http://ntfy
@@ -89,10 +96,12 @@ services:
NOTIFY_EMAIL_TO: ${NOTIFY_EMAIL_TO:-}
GH_TOKEN: ${GITHUB_TOKEN:-}
NPM_TOKEN: ${NPM_TOKEN:-}
# мок-publish: verdaccio (npm) + Gitea (репо/релизы) — без выхода в npmjs/github.com
PUBLISH_REGISTRY: ${PUBLISH_REGISTRY:-}
PUBLISH_REMOTE_BASE: ${PUBLISH_REMOTE_BASE:-}
PUBLISH_GH_API_BASE: ${PUBLISH_GH_API_BASE:-}
volumes:
- ./data-ozon:/app/data
# state.json на хост — иначе живёт в слое образа (run.js хардкодит ROOT) и теряется при пересоздании
- ./data-ozon/state.json:/app/state.json
# снапшот спеки из репо (fetch антиботом не ходим — dry-run от ручного снапшота)
- ./data-ozon-openapi:/app/openapi
ports:

View File

@@ -28,6 +28,9 @@ const tpl = fs.readFileSync(tplPath, 'utf8');
const subs = {
__SCHED_API_KEY__: env.SCHED_API_KEY,
__WEBHOOK_SECRET__: env.WEBHOOK_SECRET,
__PUBLISH_REGISTRY__: env.PUBLISH_REGISTRY || 'null',
__PUBLISH_REMOTE_BASE__: env.PUBLISH_REMOTE_BASE || 'null',
__PUBLISH_GH_API_BASE__: env.PUBLISH_GH_API_BASE || 'null',
};
let out = tpl;

View File

@@ -1,6 +1,6 @@
# schedd — опубликованный daemon из приватного реестра (verdaccio), как на проде.
# @sched/daemon@0.6.0 (latest) + deps (core 0.46.0) — фикс 2026-08-20: applyTask
# переносит timeoutMs при upsert; дефолт absent = -1 (никогда не авто-терминировать).
# @sched/daemon@0.7.0 (latest) + deps (core 0.47.0) — cancel-канал воркеру: accepted-envelope
# несёт cancelUrl, POST /runs/:id/cancel сначала POSTит {runId} на cancelUrl, потом финиширует.
# node >= 24 (engines у daemon; node:sqlite).
FROM node:24-alpine
RUN apk add --no-cache git
@@ -8,7 +8,7 @@ WORKDIR /app
ENV NODE_ENV=production
ARG VERDACCIO_TOKEN
RUN npm config set //verdaccio.kzntsv.site/:_authToken=${VERDACCIO_TOKEN} \
&& npm install -g @sched/daemon@0.6.0 --registry=https://verdaccio.kzntsv.site --no-audit --no-fund
&& npm install -g @sched/daemon@0.7.0 --registry=https://verdaccio.kzntsv.site --no-audit --no-fund
EXPOSE 8080
VOLUME ["/data"]
ENTRYPOINT ["schedd"]

View File

@@ -10,7 +10,8 @@
"envelope": true,
"auth": { "apiKey": "__SCHED_API_KEY__" },
"data": {
"stages": ["hash", "patch", "diff", "classify", "generate", "fix", "build", "postman", "state"]
"stages": ["hash", "patch", "diff", "classify", "generate", "fix", "build", "postman", "state", "publish"],
"dryRun": true
}
}
},
@@ -26,7 +27,8 @@
"envelope": true,
"auth": { "apiKey": "__SCHED_API_KEY__" },
"data": {
"stages": ["fetch", "detect", "diff", "classify", "patch", "generate", "fix", "build", "test", "postmanGenerate", "postman"],
"stages": ["fetch", "detect", "diff", "classify", "patch", "generate", "fix", "build", "test", "postmanGenerate", "postman", "publish", "githubDistro"],
"dryRun": true,
"repo": "https://github.com/yandex-market/yandex-market-partner-api",
"branch": "main",
"workDir": "/app/data/clone",
@@ -34,6 +36,9 @@
"statePath": "data/state.json",
"outputDir": "data/output/typescript",
"testsDir": "tests/client",
"registry": "__PUBLISH_REGISTRY__",
"remoteBase": "__PUBLISH_REMOTE_BASE__",
"githubApiBase": "__PUBLISH_GH_API_BASE__",
"notify": {
"ntfy": { "url": "http://ntfy", "topic": "ym-client-builder" },
"email": { "to": "vitya.kuznetsov@gmail.com", "endpoint": "http://unisender-mock:8080/ru/transactional/api/v1/email/send.json", "on": ["published", "report", "failed"] }