build_native.py33 lines
#!/usr/bin/env python3
import hashlib,json,os,shutil,subprocess,tarfile
from pathlib import Path
from validate_static import validate
root=Path.cwd();cfg=json.loads((root/'publication.json').read_text());out=root/'public'
if out.exists():raise SystemExit('public exists: use a fresh checkout')
out.mkdir()
if cfg['kind']=='marketing':
 src=root/'Курс для беременных 2026/Маркетинговые материалы'
 shutil.copy2(src/'recepty---25a9d15c-9cda-432f-9444-d94255eb206e.html',out/'index.html')
 for p in src.glob('recipe-*.png'):shutil.copy2(p,out/p.name)
 shutil.copytree(root/'course-files',out/'course-files')
else:
 for name in ['index.html','CURATOR_PROMPT.md']:shutil.copy2(root/name,out/name)
 for name in ['plans','apps']:shutil.copytree(root/name,out/name)
files,errors=validate(out)
if errors:raise SystemExit('\n'.join(errors))
files=[row for row in files if not row['path'].endswith('.md')]
if os.environ.get('CI_COMMIT_REF_NAME') and os.environ['CI_COMMIT_REF_NAME']!='master':raise SystemExit('Only the existing default branch may publish')
commit=os.environ.get('CI_COMMIT_SHA') or subprocess.check_output(['git','rev-parse','HEAD'],text=True).strip()
with tarfile.open(root/'static-release.tar','w',format=tarfile.PAX_FORMAT) as t:
 for row in files:
  p=out/row['path'];info=t.gettarinfo(str(p),arcname=row['path']);info.uid=info.gid=0;info.uname=info.gname='';info.mtime=0;info.mode=0o644
  with p.open('rb') as stream:t.addfile(info,stream)
release={'schema':1,'sourceCommit':commit,'artifactSha256':hashlib.sha256((root/'static-release.tar').read_bytes()).hexdigest(),'previewBase':cfg['previewBase'],'files':files}
# An isolated preview avoids historic redirects on the canonical VIP routes.
preview=root/'release-preview';shutil.copytree(out,preview)
(preview/'release.json').write_text(json.dumps(release,ensure_ascii=False,indent=2)+'\n')
shutil.copy2(root/'static-release.tar',preview/'release.tar')
shutil.move(str(preview),out/'_release')
(root/'static-manifest.json').write_text(json.dumps(release,ensure_ascii=False,indent=2)+'\n')
if sum(p.stat().st_size for p in out.rglob('*') if p.is_file())>256*1024*1024:raise SystemExit('Pages bundle exceeds native 256 MiB limit')
print(json.dumps({'commit':commit,'files':len(files),'artifactSha256':release['artifactSha256']}))