diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..00c2c89 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,52 @@ +name: Release + +# Push a tag vX.Y.Z on main → build the Windows portable exe and publish the +# GitHub release with the matching CHANGELOG.md section as its notes. +on: + push: + tags: ['v*'] + +permissions: + contents: write + +jobs: + release: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + - name: Tag matches package.json + shell: bash + run: | + expected="v$(node -p "require('./package.json').version")" + if [ "$expected" != "$GITHUB_REF_NAME" ]; then + echo "::error::tag $GITHUB_REF_NAME does not match package.json ($expected)"; exit 1 + fi + - run: npm ci + - run: npm run lint + - name: Tests + shell: bash + run: | + node scripts/verify-catalog.cjs --no-links + node scripts/smoke.cjs + node scripts/test-download.cjs + node scripts/test-resilience.cjs + node scripts/test-app-full.cjs + - run: npm run build + - name: Package portable exe + run: npx electron-builder --win portable --publish never + - name: Release notes + id: notes + shell: bash + run: | + node scripts/release-notes.cjs "$GITHUB_REF_NAME" > release-notes.md + echo "name=GetBox ${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + - uses: softprops/action-gh-release@v2 + with: + name: ${{ steps.notes.outputs.name }} + body_path: release-notes.md + files: release/GetBox-*-portable.exe + fail_on_unmatched_files: true diff --git a/README.md b/README.md index 6a59b9b..dd38ac3 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,12 @@ npm run dist Пока у пользователя ничего нет, лента показывает выбор редакции. В карточке программы — блоки «Часто ставят вместе» и «Альтернативы». +### Выпуск релиза + +1. Поднимите `version` в `package.json` и добавьте раздел `## X.Y.Z` в `CHANGELOG.md`. +2. После слияния в `main` поставьте тег: `git tag vX.Y.Z && git push origin vX.Y.Z`. +3. Workflow `release.yml` на `windows-latest` прогонит проверки, соберёт `GetBox-X.Y.Z-portable.exe` и опубликует релиз «GetBox X.Y.Z» с разделом из `CHANGELOG.md`. + ## Структура репозитория ```text diff --git a/scripts/release-notes.cjs b/scripts/release-notes.cjs new file mode 100644 index 0000000..c169709 --- /dev/null +++ b/scripts/release-notes.cjs @@ -0,0 +1,23 @@ +/** + * Print the CHANGELOG.md section for one version — the body of its GitHub release. + * + * Run: node scripts/release-notes.cjs 1.2.5 (a leading "v" is accepted) + */ +const fs = require('node:fs'); +const path = require('node:path'); + +const version = (process.argv[2] ?? '').replace(/^v/, ''); +if (!version) { + console.error('usage: node scripts/release-notes.cjs '); + process.exit(1); +} + +const changelog = fs.readFileSync(path.join(__dirname, '..', 'CHANGELOG.md'), 'utf-8'); +const lines = changelog.split('\n'); +const start = lines.findIndex((l) => l.trim() === `## ${version}`); +if (start < 0) { + console.error(`CHANGELOG.md has no "## ${version}" section`); + process.exit(1); +} +const end = lines.findIndex((l, i) => i > start && l.startsWith('## ')); +console.log(lines.slice(start + 1, end < 0 ? undefined : end).join('\n').trim());