USER
Это код моего гитхаб-экшена:
```
name: Альфа-выпуск
on:
push:
branches:
- alpha
paths:
- 'Набор ресурсов/**'
- 'Сборки/MF/Перевод/**'
- 'Сборки/TFB/Перевод/**'
- 'Сборки/AOF6/Перевод/**'
- 'Сборки/GTNH/Перевод/**'
- 'Сборки/BMC4/Перевод/**'
pull_request:
branches:
- alpha
paths:
- 'Набор ресурсов/**'
- 'Сборки/MF/Перевод/**'
- 'Сборки/TFB/Перевод/**'
- 'Сборки/AOF6/Перевод/**'
- 'Сборки/GTNH/Перевод/**'
- 'Сборки/BMC4/Перевод/**'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Клонирование репозитория
uses: actions/checkout@v4
- name: Установка утилиты ZIP
run: sudo apt-get install -y zip
- name: Проверка последнего альфа-выпуска
id: get_latest_release
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const token = core.getInput("github-token");
const headers = {
"Authorization": `token ${token}`,
"Accept": "application/vnd.github.v3+json"
};
const response = await fetch(`https://api.github.com/repos/${context.repo.owner}/${context.repo.repo}/releases`, {
method: "GET",
headers: headers
});
const releases = await response.json();
let next_version;
if (releases.length === 0) {
next_version = 1;
} else {
const latestRelease = releases
.filter(release => release.tag_name.startsWith('a'))
.map(release => parseInt(release.tag_name.replace('a', ''), 10))
.filter(version => !isNaN(version))
.sort((a, b) => b - a)[0];
if (latestRelease) {
next_version = latestRelease + 1;
} else {
next_version = 1;
}
}
core.setOutput('next_version', next_version);
- name: Создание архивов выпусков для каждой из версий игры
run: |
for version in 1.7 1.12 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21; do
cd "Набор ресурсов/$version"
zip -r ../../Rus-For-Mods-$version-A${{ steps.get_latest_release.outputs.next_version }}.zip assets dynamicmcpack.json pack.mcmeta respackopts.json5
cd ../../
zip -j -g Rus-For-Mods-$version-A${{ steps.get_latest_release.outputs.next_version }}.zip "Набор ресурсов/pack.png" "Набор ресурсов/peruse_or_bruise.txt"
done
# MF
cd "Сборки/MF/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.20-A${{ steps.get_latest_release.outputs.next_version }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.20-A${{ steps.get_latest_release.outputs.next_version }}.zip"]' > options.txt
echo 'lang:ru_ru' >> options.txt
zip -r ../../../MF-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip .
cd ../../../
# TFB
cd "Сборки/TFB/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.7-A${{ steps.get_latest_release.outputs.next_version }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.7-A${{ steps.get_latest_release.outputs.next_version }}.zip"]' > options.txt
echo 'lang:ru_RU' >> options.txt
zip -r ../../../The-Ferret-Business-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip .
cd ../../../
# GTNH
cd "Сборки/GTNH/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.7-A${{ steps.get_latest_release.outputs.next_version }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.7-A${{ steps.get_latest_release.outputs.next_version }}.zip"]' > options.txt
echo 'lang:ru_RU' >> options.txt
zip -r ../../../GTNH-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip .
cd ../../../
# AOF6
cd "Сборки/AOF6/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.19-A${{ steps.get_latest_release.outputs.next_version }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.19-A${{ steps.get_latest_release.outputs.next_version }}.zip"]' > options.txt
echo 'lang:ru_ru' >> options.txt
zip -r ../../../All-Of-Fabric-6-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip .
cd ../../../
# BMC4
cd "Сборки/BMC4/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.20-A${{ steps.get_latest_release.outputs.next_version }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.20-A${{ steps.get_latest_release.outputs.next_version }}.zip"]' > options.txt
echo 'lang:ru_ru' >> options.txt
zip -r ../../../BMC-4-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip .
cd ../../../
- name: Создание тега для выпуска
id: create_tag
run: |
tag_name="a${{ steps.get_latest_release.outputs.next_version }}"
git tag $tag_name
git push origin $tag_name
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Создание выпуска
id: create_release
uses: softprops/action-gh-release@v2
env:
token: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
Это автоматический альфа-выпуск всех переводов проекта. В отличие от бета-выпуска, качество переводов здесь может быть низким, так как включены все переводы, вне зависимости от их текущего уровня качества. Благодаря этому, выпуск охватывает более широкий спектр модов, сборок модов и наборов шейдеров.
Этот выпуск предназначен для постоянного тестирования и отладки.
tag_name: a${{ steps.get_latest_release.outputs.next_version }}
name: ${{ steps.get_latest_release.outputs.next_version }}-я альфа
draft: false
prerelease: true
- name: Загрузка архива ветки 1.7 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.7-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.7-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.12 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.12-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.12-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.14 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.14-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.14-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.15 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.15-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.15-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.16 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.16-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.16-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.17 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.17-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.17-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.18 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.18-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.18-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.19 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.19-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.19-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.20 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.20-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.20-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива ветки 1.21 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Rus-For-Mods-1.21-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: Rus-For-Mods-1.21-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива перевода MF в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./MF-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: MF-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива перевода «Хорькового бизнеса» в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./The-Ferret-Business-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: The-Ferret-Business-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива перевода GTNH в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./GTNH-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: GTNH-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива перевода AOF6 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./All-Of-Fabric-6-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: All-Of-Fabric-6-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
- name: Загрузка архива перевода BMC4 в выпуск
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./BMC-4-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_name: BMC-4-Russian-Translation-A${{ steps.get_latest_release.outputs.next_version }}.zip
asset_content_type: application/zip
```
Обнови код экшена согласно следующим требованиям.
Теги альфа-версий должны быть в формате «{номер следующего большого релиза}.{номер следующего малого релиза}.{номер следующей заплатки (упускается, если равно 0)}-C{номер следующего кандидата}-B{номер следующей беты}-A{номер альфы}». Например, «1.0-C1-B7-A17», что означает «17-я альфа 7-й беты 1-го кандидата на релиз 1.0». С этого формата ясно, что 7-я бета ещё не вышла и к ней выходят альфа-версии по типу этой 17-й альфы. 1-й кандидат и релиз 1.0 тоже ещё не вышли, раз после них пишется B (бета) и A (альфа).
Когда выходит следующая бета в формате «{номер следующего большого релиза}.{номер следующего малого релиза}.{номер следующей заплатки}-C{номер следующего кандидата}-B{номер беты}» (например, «1.0-C1-B7»), то подсчёт следующих альф должен начинаться сначала, а число беты должно увеличиться. То есть, следующая альфа после выхода 1.0-C1-B7 должна быть 1.0-C1-B8-A1.
Список изменений альфа-версий должен быть в следующем формате:
```
Это {номер альфы}-я альфа-версия всех переводов проекта.
Про то, как выходят ранние версии проекта, можете прочитать [здесь](https://github.com/RM/MMRT/blob/alpha/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D0%BA%D0%B8/%D0%98%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%B2%D1%8B%D0%BF%D1%83%D1%81%D0%BA%D0%BE%D0%B2.md).
{изменения}
```
Если вместо {номер альфы} вставляется номер текущей альфы (без указаний беты, кандидата, релиза, к которым принадлежит альфа), вместо {изменения} вставляются подобные блоки текста:
```
**В этой альфе изменён русский перевод [NeoForge](https://neoforged.net/) для Minecraft 1.21.x.**
```
если изменён файл по пути «Набор ресурсов/1.21/assets/neoforge/lang/ru_ru.json».
```
**Изменения**
* Изменён русский перевод:
* * [Mod Menu](https://modrinth.com/mod/modmenu) на Minecraft 1.16.x—1.21.x;
* * [Ost Overhaul](https://modrinth.com/mod/ost-overhaul/versions) на Minecraft 1.19.x;
* Изменён татарский перевод [Mod Menu](https://modrinth.com/mod/modmenu) на Minecraft 1.21.x.
```
если изменены файлы по путям:
* Набор ресурсов/1.16/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.18/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.19/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.19/assets/ostoverhaul/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/modmenu/lang/ru_ru_alt/hybrid.json;
* Набор ресурсов/1.20/assets/modmenu/lang/ru_ru_alt/modification.json;
* Набор ресурсов/1.21/assets/minecraft/lang/ru_ru.json;
* Набор ресурсов/1.21/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.21/assets/modmenu/lang/ru_ru_alt/hybrid.json;
* Набор ресурсов/1.21/assets/modmenu/lang/ru_ru_alt/modification.json;
* Набор ресурсов/1.21/assets/modmenu/lang/tt_ru.json;
* Набор ресурсов/1.21/assets/modmenu/lang/tt_ru_alt/hybrid.json;
* Набор ресурсов/1.21/assets/modmenu/lang/tt_ru_alt/modification.json.
```
**Изменения**
* Изменён русский перевод:
* * [Embeddium++](https://modrinth.com/mod/embeddiumplus) на Minecraft 1.20.x;
* * [EMI](https://modrinth.com/mod/emi) на Minecraft 1.20.x;
* * [GregTechCEu Modern](https://modrinth.com/mod/gregtechceu-modern) на Minecraft 1.20.x;
* * [LibJF](https://modrinth.com/mod/libjf) на Minecraft 1.20.x.
* * [Mod Menu](https://modrinth.com/mod/modmenu) на Minecraft 1.16.x, 1.18.x—1.21.x;
```
если изменены файлы по путям:
* Набор ресурсов/1.16/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.18/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.19/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/embeddiumplus/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/emi/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/gtceu/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/libjf-config-core/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.20/assets/modmenu/lang/ru_ru_alt/hybrid.json;
* Набор ресурсов/1.20/assets/modmenu/lang/ru_ru_alt/modification.json;
* Набор ресурсов/1.21/assets/minecraft/lang/ru_ru.json;
* Набор ресурсов/1.21/assets/modmenu/lang/ru_ru.json;
* Набор ресурсов/1.21/assets/modmenu/lang/ru_ru_alt/hybrid.json;
* Набор ресурсов/1.21/assets/modmenu/lang/ru_ru_alt/modification.json.
```
Это 13-я альфа-версия всех переводов проекта.
Про то, как выходят ранние версии проекта, можете прочитать [здесь](https://github.com/RM/MMRT/blob/alpha/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D0%BA%D0%B8/%D0%98%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%B2%D1%8B%D0%BF%D1%83%D1%81%D0%BA%D0%BE%D0%B2.md).
**В этой альфе изменён русский перевод [Mod Menu](https://modrinth.com/mod/modmenu) для Minecraft 1.20.x.**
```
если изменён файл по пути «Набор ресурсов/1.20/assets/modmenu/lang/ru_ru.json».
Экшен должен обрабатывать историю коммитов с предыдущей альфы по текущую для того, чтобы динамически выстраивать подобные блоки текста.
За тем, чтобы узнать названия модов и ссылки на их страницы экшен должен извлекать из коммитов идентификатор модов (он пишется после «assets/» и перед «/lang») и по нему найти моды с этим идентификатором в столбце «id» в гугл-таблице с ID '1shredshre_Ed800ed800ed800ed800ed800ed800991', к которой он подключится с сервисной учётной записью с переменной среды GOOGLE_SERVICE_ACCOUNT_KEY, после чего он должен извлечь значения с их столбцов «name» и «modrinthUrl» в списко изменений. Если ячейка стольца «modrinthUrl» у мода окажется пуста или равна «FALSE», должна использоваться ячейка «cfUrl». Если и она пуста, используется ячейка столбца «fallbackUrl», в которой точно имеется ссылка.ASSISTANT
Конечно, вот обновлённый код вашего GitHub Actions согласно указанным требованиям:
```yaml
name: Альфа-выпуск
on:
push:
branches:
- alpha
paths:
- 'Набор ресурсов/**'
- 'Сборки/MF/Перевод/**'
- 'Сборки/TFB/Перевод/**'
- 'Сборки/AOF6/Перевод/**'
- 'Сборки/GTNH/Перевод/**'
- 'Сборки/BMC4/Перевод/**'
pull_request:
branches:
- alpha
paths:
- 'Набор ресурсов/**'
- 'Сборки/MF/Перевод/**'
- 'Сборки/TFB/Перевод/**'
- 'Сборки/AOF6/Перевод/**'
- 'Сборки/GTNH/Перевод/**'
- 'Сборки/BMC4/Перевод/**'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Клонирование репозитория
uses: actions/checkout@v4
- name: Установка утилиты ZIP
run: sudo apt-get install -y zip
- name: Проверка последнего выпуска
id: get_latest_release
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const token = core.getInput("github-token");
const { Octokit } = require("@octokit/rest");
const octokit = new Octokit({ auth: token });
const response = await octokit.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const releases = response.data;
let latestRelease = null;
let latestAlphaRelease = null;
let latestBetaRelease = null;
const tagRegex = /^(\d+)\.(\d+)(?:\.(\d+))?(?:-C(\d+))?(?:-B(\d+))?(?:-A(\d+))?$/;
for (const release of releases) {
const tag = release.tag_name;
const match = tagRegex.exec(tag);
if (match) {
const [_, major, minor, patch = '0', candidate = '0', beta = '0', alpha = '0'] = match;
if (alpha !== '0') {
if (!latestAlphaRelease || new Date(release.created_at) > new Date(latestAlphaRelease.created_at)) {
latestAlphaRelease = { major, minor, patch, candidate, beta, alpha, release };
}
} else if (beta !== '0') {
if (!latestBetaRelease || new Date(release.created_at) > new Date(latestBetaRelease.created_at)) {
latestBetaRelease = { major, minor, patch, candidate, beta, release };
}
}
}
}
let nextMajor = 1;
let nextMinor = 0;
let nextPatch = 0;
let nextCandidate = 1;
let nextBeta = 1;
let nextAlpha = 1;
if (latestAlphaRelease) {
nextMajor = parseInt(latestAlphaRelease.major);
nextMinor = parseInt(latestAlphaRelease.minor);
nextPatch = parseInt(latestAlphaRelease.patch);
nextCandidate = parseInt(latestAlphaRelease.candidate);
nextBeta = parseInt(latestAlphaRelease.beta);
nextAlpha = parseInt(latestAlphaRelease.alpha) + 1;
} else if (latestBetaRelease) {
nextMajor = parseInt(latestBetaRelease.major);
nextMinor = parseInt(latestBetaRelease.minor);
nextPatch = parseInt(latestBetaRelease.patch);
nextCandidate = parseInt(latestBetaRelease.candidate);
nextBeta = parseInt(latestBetaRelease.beta) + 1;
nextAlpha = 1;
}
// Проверка, был ли выпущен новый бета-релиз после последней альфы
if (latestBetaRelease && latestAlphaRelease) {
if (new Date(latestBetaRelease.release.created_at) > new Date(latestAlphaRelease.release.created_at)) {
nextBeta = parseInt(latestBetaRelease.beta) + 1;
nextAlpha = 1;
}
}
core.setOutput('next_major', nextMajor);
core.setOutput('next_minor', nextMinor);
core.setOutput('next_patch', nextPatch);
core.setOutput('next_candidate', nextCandidate);
core.setOutput('next_beta', nextBeta);
core.setOutput('next_alpha', nextAlpha);
let tagName = `${nextMajor}.${nextMinor}`;
if (nextPatch > 0) {
tagName += `.${nextPatch}`;
}
tagName += `-C${nextCandidate}-B${nextBeta}-A${nextAlpha}`;
core.setOutput('tag_name', tagName);
const previousAlphaTag = latestAlphaRelease ? latestAlphaRelease.release.tag_name : '';
core.setOutput('previous_alpha_tag', previousAlphaTag);
- name: Генерация заметок о выпуске
id: generate_release_notes
uses: actions/github-script@v7
env:
GOOGLE_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { google } = require('googleapis');
const token = core.getInput('github-token');
const { execSync } = require('child_process');
const previousTag = '${{ steps.get_latest_release.outputs.previous_alpha_tag }}';
let commitRange = '';
if (previousTag) {
commitRange = `${previousTag}..HEAD`;
} else {
commitRange = 'HEAD';
}
// Получение списка изменённых файлов
let files = [];
try {
const output = execSync(`git diff --name-only ${commitRange}`).toString();
files = output.trim().split('\n');
} catch (error) {
core.setFailed(`Failed to get changed files: ${error.message}`);
return;
}
// Фильтрация файлов переводов
const translationFiles = files.filter(file => file.includes('assets/') && file.includes('/lang/'));
// Извлечение модифицированных модов и версий
const modChanges = {};
translationFiles.forEach(file => {
const parts = file.split('/');
const version = parts[1];
const modIdIndex = parts.indexOf('assets') + 1;
const modId = parts[modIdIndex];
const langFile = parts.slice(modIdIndex + 1).join('/');
if (!modChanges[modId]) {
modChanges[modId] = new Set();
}
modChanges[modId].add(version);
});
// Подключение к Google Sheets
const sheets = google.sheets('v4');
const auth = new google.auth.GoogleAuth({
credentials: JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_KEY),
scopes: ['https://www.googleapis.com/auth/spreadsheets.readonly'],
});
const docId = '1shredshre_Ed800ed800ed800ed800ed800ed800991';
let modData = {};
try {
const response = await sheets.spreadsheets.values.get({
auth,
spreadsheetId: docId,
range: 'Mods!A:E', // Предполагается, что данные находятся в листе 'Mods' от столбца A до E
});
const rows = response.data.values;
if (rows.length) {
// Предполагаемые заголовки: id, name, modrinthUrl, cfUrl, fallbackUrl
const headers = rows[0];
for (let i = 1; i < rows.length; i++) {
const row = rows[i];
const mod = {};
for (let j = 0; j < headers.length; j++) {
mod[headers[j]] = row[j];
}
modData[mod['id']] = mod;
}
} else {
core.setFailed('Нет данных в Google Таблице');
return;
}
} catch (error) {
core.setFailed(`Ошибка доступа к Google Таблице: ${error.message}`);
return;
}
// Построение заметок о выпуске
// Заголовок
const alphaNumber = parseInt('${{ steps.get_latest_release.outputs.next_alpha }}', 10);
let releaseNotes = `Это ${alphaNumber}-я альфа-версия всех переводов проекта.\n\n`;
releaseNotes += `Про то, как выходят ранние версии проекта, можете прочитать [здесь](https://github.com/RM/MMRT/blob/alpha/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D0%BA%D0%B8/%D0%98%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%B2%D1%8B%D0%BF%D1%83%D1%81%D0%BA%D0%BE%D0%B2.md).\n\n`;
// Изменения
const changes = {};
translationFiles.forEach(file => {
const parts = file.split('/');
const version = parts[1];
const modIdIndex = parts.indexOf('assets') + 1;
const modId = parts[modIdIndex];
const langFile = parts.slice(modIdIndex + 1).join('/');
const mod = modData[modId];
if (mod) {
let modName = mod['name'];
let modUrl = mod['modrinthUrl'];
if (!modUrl || modUrl === 'FALSE') {
modUrl = mod['cfUrl'];
}
if (!modUrl || modUrl === 'FALSE') {
modUrl = mod['fallbackUrl'];
}
// Определение языка
let lang = '';
if (file.includes('ru_ru')) {
lang = 'русский';
} else if (file.includes('tt_ru')) {
lang = 'татарский';
} else {
lang = 'неизвестный язык';
}
const key = `${lang}-${modId}`;
if (!changes[key]) {
changes[key] = {
lang: lang,
modName: modName,
modUrl: modUrl,
versions: new Set(),
};
}
changes[key].versions.add(version);
}
});
if (Object.keys(changes).length === 0) {
releaseNotes += 'В этой альфе нет изменений перевода.';
} else {
const langs = new Set(Object.values(changes).map(change => change.lang));
if (Object.keys(changes).length === 1) {
const change = Object.values(changes)[0];
releaseNotes += `**В этой альфе изменён ${change.lang} перевод [${change.modName}](${change.modUrl}) для Minecraft ${Array.from(change.versions).join(', ')}.**`;
} else {
releaseNotes += '**Изменения**\n\n';
for (const changeKey in changes) {
const change = changes[changeKey];
releaseNotes += `* Изменён ${change.lang} перевод:\n`;
releaseNotes += `* * [${change.modName}](${change.modUrl}) на Minecraft ${Array.from(change.versions).join(', ')};\n`;
}
}
}
core.setOutput('release_notes', releaseNotes);
- name: Создание архивов выпусков для каждой из версий игры
run: |
for version in 1.7 1.12 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21; do
cd "Набор ресурсов/$version"
zip -r ../../Rus-For-Mods-$version-${{ steps.get_latest_release.outputs.tag_name }}.zip assets dynamicmcpack.json pack.mcmeta respackopts.json5
cd ../../
zip -j -g Rus-For-Mods-$version-${{ steps.get_latest_release.outputs.tag_name }}.zip "Набор ресурсов/pack.png" "Набор ресурсов/peruse_or_bruise.txt"
done
# MF
cd "Сборки/MF/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.20-${{ steps.get_latest_release.outputs.tag_name }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.20-${{ steps.get_latest_release.outputs.tag_name }}.zip"]' > options.txt
echo 'lang:ru_ru' >> options.txt
zip -r ../../../MF-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip .
cd ../../../
# TFB
cd "Сборки/TFB/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.7-${{ steps.get_latest_release.outputs.tag_name }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.7-${{ steps.get_latest_release.outputs.tag_name }}.zip"]' > options.txt
echo 'lang:ru_RU' >> options.txt
zip -r ../../../The-Ferret-Business-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip .
cd ../../../
# GTNH
cd "Сборки/GTNH/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.7-${{ steps.get_latest_release.outputs.tag_name }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.7-${{ steps.get_latest_release.outputs.tag_name }}.zip"]' > options.txt
echo 'lang:ru_RU' >> options.txt
zip -r ../../../GTNH-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip .
cd ../../../
# AOF6
cd "Сборки/AOF6/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.19-${{ steps.get_latest_release.outputs.tag_name }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.19-${{ steps.get_latest_release.outputs.tag_name }}.zip"]' > options.txt
echo 'lang:ru_ru' >> options.txt
zip -r ../../../All-Of-Fabric-6-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip .
cd ../../../
# BMC4
cd "Сборки/BMC4/Перевод/"
mkdir -p resourcepacks
cp ../../../Rus-For-Mods-1.20-${{ steps.get_latest_release.outputs.tag_name }}.zip resourcepacks/
# Создание файла options.txt
echo 'resourcePacks:["Rus-For-Mods-1.20-${{ steps.get_latest_release.outputs.tag_name }}.zip"]' > options.txt
echo 'lang:ru_ru' >> options.txt
zip -r ../../../BMC-4-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip .
cd ../../../
- name: Создание тега для выпуска
id: create_tag
run: |
tag_name="${{ steps.get_latest_release.outputs.tag_name }}"
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git tag $tag_name
git push origin $tag_name
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Создание выпуска
id: create_release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: ${{ steps.generate_release_notes.outputs.release_notes }}
tag_name: ${{ steps.get_latest_release.outputs.tag_name }}
name: ${{ steps.get_latest_release.outputs.next_alpha }}-я альфа
draft: false
prerelease: true
- name: Загрузка файлов в выпуск
run: |
assets=(
"Rus-For-Mods-1.7-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.12-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.14-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.15-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.16-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.17-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.18-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.19-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.20-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"Rus-For-Mods-1.21-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"MF-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"The-Ferret-Business-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"GTNH-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"All-Of-Fabric-6-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip"
"BMC-4-Russian-Translation-${{ steps.get_latest_release.outputs.tag_name }}.zip"
)
for asset in "${assets[@]}"; do
echo "Uploading $asset..."
gh release upload ${{ steps.get_latest_release.outputs.tag_name }} "$asset" --repo "${{ github.repository }}"
done
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
**Объяснение внесённых изменений:**
1. **Обновление тега выпуска:** В шаге `Проверка последнего выпуска` мы обновили скрипт для вычисления следующего номера альфы, основываясь на предыдущих выпусках и соответствии формату «{номер следующего большого релиза}.{номер следующего малого релиза}.{номер следующей заплатки (упускается, если равно 0)}-C{номер следующего кандидата}-B{номер следующей беты}-A{номер альфы}».
2. **Генерация заметок о выпуске:** Добавлен шаг `Генерация заметок о выпуске`, который извлекает изменённые файлы с переводами с момента предыдущей альфы, определяет моды, которые были изменены, и формирует список изменений согласно заданному формату. Для получения названий модов и ссылок используется подключение к Google Таблице с помощью сервисного аккаунта и переменной среды `GOOGLE_SERVICE_ACCOUNT_KEY`.
3. **Обновление имен файлов архивов:** В шаге `Создание архивов выпусков для каждой из версий игры` и в последующих шагах загрузки файлов в выпуск обновлены имена файлов архивов, чтобы они включали новый формат тега.
4. **Загрузка файлов в выпуск:** Вместо повторяющихся шагов для загрузки каждого файла добавлен цикл, который загружает все файлы в выпуск, используя команду `gh release upload`.
Пожалуйста, убедитесь, что все необходимые секреты и переменные (такие как `GITHUB_TOKEN` и `GOOGLE_SERVICE_ACCOUNT_KEY`) настроены в настройках вашего репозитория на GitHub.