fix(release): public links in release notes and a cancelled status
The job reaches the Gitea API at its internal address, so html_url in the response pointed at http://10.10.1.129:3000 and every link in the notes was unreachable from outside. Build links from PUBLIC_URL (repo variable, defaults to https://gitea.hsrv.site). A cancelled Android build now shows "cancelled" instead of staying at "building". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
718125b719
commit
a239650075
4 files changed
+29
-4
No files matched your search
@@ -5,6 +5,8 @@
|
||||
#
|
||||
# Секреты (Settings → Actions → Secrets):
|
||||
# RELEASE_TOKEN (необязательно) — токен для релиза; без него — встроенный токен job (права на запись в репозиторий)
|
||||
# Переменные (Settings → Actions → Variables):
|
||||
# PUBLIC_URL (необязательно) — внешний адрес Gitea для ссылок в тексте релиза; по умолчанию https://gitea.hsrv.site
|
||||
# ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD — подпись APK
|
||||
name: release
|
||||
|
||||
@@ -37,6 +39,7 @@ jobs:
|
||||
env:
|
||||
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
PUBLIC_URL: ${{ vars.PUBLIC_URL || 'https://gitea.hsrv.site' }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
VERSION: ${{ steps.v.outputs.PIPU_VERSION }}
|
||||
PRERELEASE: ${{ steps.v.outputs.PIPU_PRERELEASE }}
|
||||
@@ -60,6 +63,7 @@ jobs:
|
||||
# для scripts/release.mjs
|
||||
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
PUBLIC_URL: ${{ vars.PUBLIC_URL || 'https://gitea.hsrv.site' }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
VERSION: ${{ needs.release.outputs.version }}
|
||||
VERSION_CODE: ${{ needs.release.outputs.version_code }}
|
||||
@@ -141,3 +145,8 @@ jobs:
|
||||
- name: Статус в релизе — сборка не удалась
|
||||
if: failure()
|
||||
run: node scripts/release.mjs android failure
|
||||
|
||||
# срабатывает при отмене из интерфейса; если раннер убит целиком, статус обновит следующий запуск
|
||||
- name: Статус в релизе — сборка отменена
|
||||
if: cancelled()
|
||||
run: node scripts/release.mjs android cancelled
|
||||
@@ -106,6 +106,10 @@ container:
|
||||
| `RELEASE_TOKEN` | Необязательно. Создание и редактирование релиза, загрузка ассетов (scope `write:repository`). Без него используется встроенный токен job (`GITHUB_TOKEN`), у которого есть права на запись в этот репозиторий |
|
||||
| `ANDROID_KEYSTORE_BASE64`, `ANDROID_KEYSTORE_PASSWORD`, `ANDROID_KEY_ALIAS`, `ANDROID_KEY_PASSWORD` | Подпись APK. **Ключ один на всю жизнь приложения** — хранить резервную копию вне Gitea. Без них финальный релиз падает; `-rc` собирается с отладочной подписью. |
|
||||
|
||||
Переменная репозитория `PUBLIC_URL` (Settings → Actions → Variables) — внешний адрес Gitea для ссылок
|
||||
в тексте релиза, по умолчанию `https://gitea.hsrv.site`. Нужна потому, что job обращается к API по внутреннему
|
||||
адресу, и ссылки из ответа API ведут туда же.
|
||||
|
||||
## Деплой
|
||||
|
||||
Автодеплой не обязателен. На сервере в клоне репозитория: `deploy/update.sh [vX.Y.Z]` — checkout тега,
|
||||
|
||||
+15
-4
@@ -2,10 +2,12 @@
|
||||
// Релиз в Gitea (docs/ci-cd.md#релиз): сначала создаётся релиз с заметками, потом сборка Android
|
||||
// докладывает в него APK и переписывает блок статуса в тексте.
|
||||
// node scripts/release.mjs create — создать релиз по тегу (при перезапуске — обновить)
|
||||
// node scripts/release.mjs android building|failure — статус сборки APK в тексте релиза
|
||||
// node scripts/release.mjs android building|failure|cancelled — статус сборки APK в тексте релиза
|
||||
// node scripts/release.mjs android success <file.apk> — приложить APK и .sha256, статус «собран»
|
||||
// Окружение: GITEA_API (<server>/api/v1/repos/<owner>/<repo>), GITEA_TOKEN, TAG, VERSION, VERSION_CODE,
|
||||
// PRERELEASE (true|false), GITHUB_RUN_ID; для success — SIGNING (release|debug).
|
||||
// PUBLIC_URL — внешний адрес Gitea для ссылок в тексте (job ходит в API по внутреннему адресу, и html_url
|
||||
// из ответа указывает на него же).
|
||||
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { createHash } from 'node:crypto';
|
||||
@@ -57,6 +59,11 @@ export function renderAndroidStatus({ status, runUrl, versionCode, apk, signing
|
||||
? ['⚠️ Подписан отладочным ключом: не установится поверх версии с релизной подписью.']
|
||||
: []),
|
||||
]
|
||||
: status === 'cancelled'
|
||||
? [
|
||||
`⏹ **Android:** сборка APK отменена — [лог сборки](${runUrl}).`,
|
||||
'APK появится здесь после перезапуска сборки.',
|
||||
]
|
||||
: status === 'failure'
|
||||
? [
|
||||
`❌ **Android:** сборка APK не удалась — [лог сборки](${runUrl}).`,
|
||||
@@ -182,9 +189,11 @@ function commitsBetween(prevTag, tag) {
|
||||
|
||||
async function context() {
|
||||
const repo = await api('GET', '');
|
||||
const publicUrl = process.env.PUBLIC_URL?.replace(/\/+$/, '');
|
||||
const repoUrl = publicUrl ? `${publicUrl}/${repo.full_name}` : repo.html_url;
|
||||
const tag = env('TAG');
|
||||
const release = await api('GET', `/releases/tags/${encodeURIComponent(tag)}`);
|
||||
return { repoUrl: repo.html_url, tag, release, runUrl: `${repo.html_url}/actions/runs/${env('GITHUB_RUN_ID')}` };
|
||||
return { repoUrl, tag, release, runUrl: `${repoUrl}/actions/runs/${env('GITHUB_RUN_ID')}` };
|
||||
}
|
||||
|
||||
async function create() {
|
||||
@@ -242,8 +251,10 @@ async function android(status, apkPath) {
|
||||
async function main() {
|
||||
const [cmd, ...args] = process.argv.slice(2);
|
||||
if (cmd === 'create') return create();
|
||||
if (cmd === 'android' && ['building', 'success', 'failure'].includes(args[0])) return android(args[0], args[1]);
|
||||
throw new Error('использование: release.mjs create | android building|failure | android success <file.apk>');
|
||||
if (cmd === 'android' && ['building', 'success', 'failure', 'cancelled'].includes(args[0])) {
|
||||
return android(args[0], args[1]);
|
||||
}
|
||||
throw new Error('использование: release.mjs create | android building|failure|cancelled | android success <file.apk>');
|
||||
}
|
||||
|
||||
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
||||
|
||||
@@ -59,6 +59,7 @@ test('android status blocks', () => {
|
||||
assert.match(debug, /отладочным ключом/);
|
||||
|
||||
assert.match(renderAndroidStatus({ status: 'failure', runUrl: 'https://run' }), /не удалась — \[лог сборки\]/);
|
||||
assert.match(renderAndroidStatus({ status: 'cancelled', runUrl: 'https://run' }), /отменена — \[лог сборки\]/);
|
||||
});
|
||||
|
||||
test('replaces only the status block and is idempotent', () => {
|
||||
|
||||
Reference in new issue
Block a user