name: Prepare v17.6.8 release on: push: branches: - feature/v17.6.8-developer-console-ux permissions: contents: write jobs: prepare: if: github.actor != 'github-actions[bot]' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: feature/v17.6.8-developer-console-ux - uses: actions/setup-node@v4 with: node-version: 22 - name: Update release files shell: bash run: | python - <<'PY' from pathlib import Path import json old='20260908-v17-6-7-classic-offer-pdf' new='20260908-v17-6-8-developer-console-ux' old_cache='sun-catering-pwa-v72-20260908-v17-6-7-classic-offer-pdf' new_cache='sun-catering-pwa-v73-20260908-v17-6-8-developer-console-ux' p=Path('public/core/performance.js') s=p.read_text() s=s.replace("const VERSION='17.6.7';","const VERSION='17.6.8';",1) s=s.replace(f"const RELEASE='{old}';",f"const RELEASE='{new}';",1) loader=""" function loadDeveloperUX(){\n if(window.SunDeveloperUXV1768||document.getElementById('sunDeveloperUXV1768Script'))return;\n const script=document.createElement('script');script.id='sunDeveloperUXV1768Script';script.src=`core/developer-console-v1768.js?v=${RELEASE}`;script.async=true;script.onerror=()=>console.error('[Caterium] Не загрузился модуль developer-console-v1768.js');document.head.appendChild(script);\n }\n""" if 'function loadDeveloperUX()' not in s: s=s.replace(' const start=()=>{',loader+' const start=()=>{',1) s=s.replace('loadHotfix();loadOpsUX();loadUXFix();scan(document);startMemoryTimer();','loadHotfix();loadOpsUX();loadUXFix();loadDeveloperUX();scan(document);startMemoryTimer();',1) s=s.replace('loadHotfix,loadOpsUX,loadUXFix,disconnect:','loadHotfix,loadOpsUX,loadUXFix,loadDeveloperUX,disconnect:',1) p.write_text(s) p=Path('public/service-worker.js') s=p.read_text().replace(old_cache,new_cache).replace(f"const VERSION='{old}';",f"const VERSION='{new}';") needle='`./core/classic-offer-pdf-v1767.js?v=${VERSION}`' if 'developer-console-v1768.js' not in s: s=s.replace(needle,needle+',`./core/developer-console-v1768.js?v=${VERSION}`',1) p.write_text(s) p=Path('public/index.html') p.write_text(p.read_text().replace(old,new)) p=Path('package.json') pkg=json.loads(p.read_text()) pkg['version']='17.6.8' check=pkg['scripts']['check:syntax'] add='node --check public/core/developer-console-v1768.js' if add not in check: pkg['scripts']['check:syntax']=check+' && '+add p.write_text(json.dumps(pkg,ensure_ascii=False,indent=2)+'\n') p=Path('docs/release-manifest.json') m=json.loads(p.read_text()) m['version']='v17.6.8' m['pwaCache']='v73-20260908-v17-6-8-developer-console-ux' m['release']=new m['notes']='Developer Console UX: fixed async DOM race errors, stable company numbering and deletion, accounts grouped by company, compact plan matrix, grouped production error journal.' m['developerCompanyNumbers']=True m['developerCompanyDelete']=True m['developerAccountsGroupedByCompany']=True m['developerPlansCompactMatrix']=True m['developerJournalGroupedErrors']=True m['developerJournalFiltersLocalCopies']=True m['developerDomRaceFix']=True m['developerConsoleUXModule']='core/developer-console-v1768.js' m['developerSqlMigration']='SUPABASE-V17.6.8-DEVELOPER-CONSOLE-UX.sql' p.write_text(json.dumps(m,ensure_ascii=False,indent=2)+'\n') p=Path('tests/static-security.mjs') s=p.read_text() s=s.replace("classic=readPub('core/classic-offer-pdf-v1767.js');","classic=readPub('core/classic-offer-pdf-v1767.js'),developerUX=readPub('core/developer-console-v1768.js');",1) s=s.replace("if(!sw.includes('v17-6-7-classic-offer-pdf')||!sw.includes('classic-offer-pdf-v1767.js')||sw.includes('offer-gallery-data.js'))fail('service worker cache is stale');else ok('PWA cache updated to v17.6.7');", "if(!sw.includes('v17-6-8-developer-console-ux')||!sw.includes('developer-console-v1768.js')||!sw.includes('classic-offer-pdf-v1767.js')||sw.includes('offer-gallery-data.js'))fail('service worker cache is stale');else ok('PWA cache updated to v17.6.8');",1) s=s.replace("if(html.includes('20260907-v17-6-0-stability-security')||!html.includes('20260908-v17-6-7-classic-offer-pdf')||!html.includes('classic-offer-pdf-v1767.js'))fail('index still serves stale core asset version');else ok('index cache-busting is current');", "if(html.includes('20260907-v17-6-0-stability-security')||!html.includes('20260908-v17-6-8-developer-console-ux')||!html.includes('classic-offer-pdf-v1767.js'))fail('index still serves stale core asset version');else ok('index cache-busting is current');",1) s=s.replace("if(/service_role\\s*[:=]\\s*['\"][A-Za-z0-9._-]{20,}/i.test(ops+hotfix+ux+classic)||/eyJ[a-zA-Z0-9_-]{30,}/.test(ops+hotfix+ux+classic))fail('possible secret in ops/hotfix/ux/classic module');else ok('ops/hotfix/ux/classic modules have no hard-coded secret');", "if(!developerUX.includes(\"const VERSION='17.6.8'\")||!developerUX.includes('sun_dev_delete_company_v1768')||!developerUX.includes('sun_dev_error_groups_v1768')||!developerUX.includes('selectedAccountsWorkspace')||!developerUX.includes('sun-dev-plan-matrix')||!developerUX.includes('KNOWN_DOM_RACE'))fail('v17.6.8 Developer Console UX module missing');else ok('v17.6.8 Developer Console UX module present');\nif(/service_role\\s*[:=]\\s*['\"][A-Za-z0-9._-]{20,}/i.test(ops+hotfix+ux+classic+developerUX)||/eyJ[a-zA-Z0-9_-]{30,}/.test(ops+hotfix+ux+classic+developerUX))fail('possible secret in ops/hotfix/ux/classic/developer module');else ok('ops/hotfix/ux/classic/developer modules have no hard-coded secret');",1) p.write_text(s) p=Path('tests/release-check.mjs') s=p.read_text() s=s.replace("classic=read('core/classic-offer-pdf-v1767.js');","classic=read('core/classic-offer-pdf-v1767.js'),developerUX=read('core/developer-console-v1768.js');",1) s=s.replace("check(sw.includes('v72-20260908-v17-6-7-classic-offer-pdf')&&sw.includes('classic-offer-pdf-v1767.js'),'service worker cache is v17.6.7');","check(sw.includes('v73-20260908-v17-6-8-developer-console-ux')&&sw.includes('classic-offer-pdf-v1767.js')&&sw.includes('developer-console-v1768.js'),'service worker cache is v17.6.8');",1) s=s.replace("check(index.includes('20260908-v17-6-7-classic-offer-pdf')&&index.includes('classic-offer-pdf-v1767.js')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.6.7');","check(index.includes('20260908-v17-6-8-developer-console-ux')&&index.includes('classic-offer-pdf-v1767.js')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.6.8');",1) s=s.replace("check(String(releaseManifest.pwaCache||'').includes('v72-20260908-v17-6-7-classic-offer-pdf'),'release manifest points to current PWA cache');","check(String(releaseManifest.pwaCache||'').includes('v73-20260908-v17-6-8-developer-console-ux'),'release manifest points to current PWA cache');",1) s=s.replace("['17.6.2','17.6.3','17.6.4','17.6.5','17.6.6','17.6.7']","['17.6.2','17.6.3','17.6.4','17.6.5','17.6.6','17.6.7','17.6.8']",1) s=s.replace("release notes exist through v17.6.7","release notes exist through v17.6.8",1) s=s.replace("check(pkg.version==='17.6.7','package version is v17.6.7');","check(pkg.version==='17.6.8','package version is v17.6.8');",1) insert="""check(developerUX.includes(\"const VERSION='17.6.8'\")&&developerUX.includes('sun_dev_delete_company_v1768')&&developerUX.includes('sun_dev_error_groups_v1768'),'Developer Console v17.6.8 module is versioned');\ncheck(developerUX.includes('selectedAccountsWorkspace')&&developerUX.includes('sun-dev-plan-matrix'),'accounts are grouped by company and plans use compact matrix');\ncheck(developerUX.includes('KNOWN_DOM_RACE')&&developerUX.includes('prepareAsyncRoots'),'Developer Console async DOM race is guarded');\ncheck(releaseManifest.developerCompanyNumbers===true&&releaseManifest.developerCompanyDelete===true&&releaseManifest.developerAccountsGroupedByCompany===true&&releaseManifest.developerPlansCompactMatrix===true&&releaseManifest.developerJournalGroupedErrors===true,'release manifest records Developer Console UX changes');\n""" s=s.replace('if(bad)process.exit(1);',insert+'if(bad)process.exit(1);',1) p.write_text(s) p=Path('tests/app.spec.mjs') s=p.read_text().replace("expect(result.version).toBe('17.6.7');","expect(result.version).toBe('17.6.8');",1) if "v17.6.8 Developer Console UX module boots" not in s: s += """\n\ntest('v17.6.8 Developer Console UX module boots', async ({ page }) => {\n await page.goto('/index.html',{waitUntil:'domcontentloaded'});\n const source=fs.readFileSync(path.join(process.cwd(),'public','core','developer-console-v1768.js'),'utf8');\n await page.evaluate(()=>{\n document.body.innerHTML='
';\n window.SunDeveloperV22={open:async()=>true,activateTab:async()=>true};\n window.SunCloudV2={getClient:()=>null};\n window.SunEnterprise={toast:()=>null};\n });\n await page.addScriptTag({content:source});\n await page.waitForFunction(()=>Boolean(window.SunDeveloperUXV1768),null,{timeout:5000});\n const result=await page.evaluate(()=>window.SunDeveloperUXV1768.checks());\n expect(result.version).toBe('17.6.8');\n});\n""" p.write_text(s) Path('docs/releases/V17.6.8-CHANGES.txt').write_text('''Caterium v17.6.8 — Developer Console UX\n\n- Исправлена гонка DOM при открытии и переключении вкладок кабинета разработчика, вызывавшая className/null и reading add.\n- Компаниям присваивается постоянный последовательный номер, который не переиспользуется после удаления.\n- В разделе «Компании» добавлено безопасное удаление с двойным подтверждением. Связанные данные компании удаляются каскадно, Auth-аккаунты сохраняются.\n- «Аккаунты» сгруппированы по компаниям: сначала выбирается компания, затем видны только её пользователи. Добавлена группа «Без компании».\n- «Тарифы» переведены на компактную матрицу функций вместо длинных повторяющихся списков.\n- «Журнал» группирует одинаковые ошибки и отделяет актуальные production-ошибки от шума старых локальных file:// копий.\n- Добавлен серверный RPC для сгруппированного журнала, постоянной нумерации и удаления компаний.\n''') PY npm install --package-lock-only - name: Commit release preparation shell: bash run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add public package.json package-lock.json docs tests git commit -m "Prepare Caterium v17.6.8 Developer Console UX" git push origin HEAD:feature/v17.6.8-developer-console-ux