diff --git a/.github/workflows/auto-cl-update-atd.yml b/.github/workflows/auto-cl-update-atd.yml index 22b330c4b88..ae590f799da 100644 --- a/.github/workflows/auto-cl-update-atd.yml +++ b/.github/workflows/auto-cl-update-atd.yml @@ -34,7 +34,7 @@ jobs: - name: Run post-merge script env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: python Tools/ATD/auto_cl.py "${{ env.GITHUB_TOKEN }}" "${{ github.repository }}" + run: python Tools/ADT/auto_cl.py "${{ env.GITHUB_TOKEN }}" "${{ github.repository }}" - name: Configure Git run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3281b6ce926..305e95715ab 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,15 +6,19 @@ name: Publish on: workflow_dispatch: schedule: - - cron: '0 1 * * *' + - cron: '0 6 * * *' + workflow_run: + workflows: [Build & Test Release] + types: [completed] jobs: build: + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} runs-on: ubuntu-latest steps: -# - name: Install dependencies -# run: sudo apt-get install -y python3-paramiko python3-lxml + - name: Install dependencies + run: sudo apt-get install -y python3-paramiko python3-lxml - uses: actions/checkout@v3.6.0 with: @@ -36,27 +40,62 @@ jobs: run: dotnet build Content.Packaging --configuration Release --no-restore /m - name: Package server - run: dotnet run --project Content.Packaging server --platform win-x64 --platform linux-x64 --platform osx-x64 --platform linux-arm64 + run: dotnet run --project Content.Packaging server --platform linux-x64 - name: Package client run: dotnet run --project Content.Packaging client --no-wipe-release + + - name: Update Build Info + run: | + chmod +x Tools/gen_build_info.py + Tools/gen_build_info.py - - name: Upload build artifact - id: artifact-upload-step - uses: actions/upload-artifact@v4 + - name: Shuffle files around + run: | + mkdir "release/${{ github.sha }}" + mv release/*.zip "release/${{ github.sha }}" + + - name: Upload files to mothership + uses: burnett01/rsync-deployments@7.0.0 with: - name: build - path: release/*.zip - compression-level: 0 - retention-days: 0 - - - name: Publish version - run: Tools/publish_github_artifact.py - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} - ARTIFACT_ID: ${{ steps.artifact-upload-step.outputs.artifact-id }} - GITHUB_REPOSITORY: ${{ vars.GITHUB_REPOSITORY }} + switches: -avzr --ignore-existing + path: "release/${{ github.sha }}" + remote_path: ${{ secrets.BUILDS_PATH }} + remote_host: ${{ secrets.BUILDS_HOST }} + remote_port: ${{ secrets.BUILDS_PORT }} + remote_user: ${{ secrets.BUILDS_USERNAME }} + remote_key: ${{ secrets.BUILDS_SSH_KEY }} + + - name: Update manifest JSON + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.BUILDS_HOST }} + username: ${{ secrets.BUILDS_USERNAME }} + key: ${{ secrets.BUILDS_SSH_KEY }} + port: ${{ secrets.BUILDS_PORT }} + script: python3 ~/manifest.py --version ${{ github.sha }} + + - name: Update CDN repository + run: | + curl -X POST -d "" -H 'Authorization: Bearer ${{ secrets.BUILDS_TOKEN }}' "http://${{ secrets.BUILDS_HOST }}:27690/control/update" + + + #- name: Upload build artifact + # id: artifact-upload-step + # uses: actions/upload-artifact@v4 + # with: + # name: build + # path: release/*.zip + # compression-level: 0 + # retention-days: 0 + + #- name: Publish version + # run: Tools/publish_github_artifact.py + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} + # ARTIFACT_ID: ${{ steps.artifact-upload-step.outputs.artifact-id }} + # GITHUB_REPOSITORY: ${{ vars.GITHUB_REPOSITORY }} # - name: Publish changelog (Discord) # run: Tools/actions_changelogs_since_last_run.py @@ -69,7 +108,7 @@ jobs: # env: # CHANGELOG_RSS_KEY: ${{ secrets.CHANGELOG_RSS_KEY }} - - uses: geekyeggo/delete-artifact@v5 - if: always() - with: - name: build + #- uses: geekyeggo/delete-artifact@v5 + # if: always() + # with: + # name: build diff --git a/Resources/Changelog/ChangelogADT.yml b/Resources/Changelog/ChangelogADT.yml index 8cfa4770612..b33040568ce 100644 --- a/Resources/Changelog/ChangelogADT.yml +++ b/Resources/Changelog/ChangelogADT.yml @@ -2051,3 +2051,37 @@ Entries: - {message: 'Upstream 27.06.24, подтянуты коммиты с корвакса.', type: Tweak} time: '2024-06-27T17:32:38Z' id: 214 + - author: Darki255 + changes: + - {message: Добавлен немецкий акцент, type: Add} + time: '2024-07-09T18:58:31Z' + id: 215 + - author: Ratyyy + changes: + - {message: Изменены многие спрайты., type: Tweak} + time: '2024-07-14T08:59:33Z' + id: 216 + - author: Шрёдька + changes: + - {message: 'Upstream 12.07.24, подтянуты коммиты с корвакса.', type: Tweak} + time: '2024-07-15T13:36:26Z' + id: 217 + - author: Крыска + changes: + - {message: НТ начало поставлять новое снаряжение для ОБР., type: Add} + - {message: 'После собрания акционеров, было принято решение сформировать отдельные + отряды для борьбы с бунтами.', type: Add} + - {message: 'Величайшие умы НТ пришли к выводу, что в m-90 можно заряжать гранаты + в подствольный гранатомёт!', type: Add} + time: '2024-07-25T10:57:24Z' + id: 218 + - author: Шрёдька + changes: + - {message: 'Подтянуты изменения с корвакса, 21.07.24.', type: Tweak} + time: '2024-07-26T23:39:11Z' + id: 219 + - author: Шрёдька + changes: + - {message: 'Подтянуты коммиты с корвакса, 27.07.24', type: Tweak} + time: '2024-07-27T16:15:51Z' + id: 220 diff --git a/Tools/ATD/auto_cl.py b/Tools/ADT/auto_cl.py similarity index 100% rename from Tools/ATD/auto_cl.py rename to Tools/ADT/auto_cl.py diff --git a/Tools/ATD/cl_old.yml b/Tools/ADT/cl_old.yml similarity index 100% rename from Tools/ATD/cl_old.yml rename to Tools/ADT/cl_old.yml diff --git a/Tools/gen_build_info.py b/Tools/gen_build_info.py new file mode 100644 index 00000000000..0ab1b9169dd --- /dev/null +++ b/Tools/gen_build_info.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +# Generates build info and injects it into the server zip files. + +import codecs +import hashlib +import io +import json +import os +import subprocess +from zipfile import ZipFile, ZIP_DEFLATED + +FILE = "SS14.Client.zip" + +SERVER_FILES = [ + "SS14.Server_linux-x64.zip", + "SS14.Server_win-x64.zip" +] + +VERSION = os.environ['GITHUB_SHA'] +print(VERSION) +FORK_ID = "ADT" +BUILD_URL = f"http://builds.adventurestation.space/builds/{{FORK_VERSION}}/{FILE}" +MANIFEST_URL = f"http://builds.adventurestation.space/version/{{FORK_VERSION}}/manifest" +MANIFEST_DOWNLOAD_URL = f"http://builds.adventurestation.space/version/{{FORK_VERSION}}/download" + +def main() -> None: + client_file = os.path.join("release", FILE) + manifest = generate_build_json(client_file) + + for server in SERVER_FILES: + inject_manifest(os.path.join("release", server), manifest) + + +def inject_manifest(zip_path: str, manifest: str) -> None: + with ZipFile(zip_path, "a", compression=ZIP_DEFLATED) as z: + print(manifest) + z.writestr("build.json", manifest) + + +def generate_build_json(file: str) -> str: + # Env variables set by Jenkins. + + hash = sha256_file(file) + engine_version = get_engine_version() + manifest_hash = generate_manifest_hash(file) + + return json.dumps({ + "download": BUILD_URL, + "hash": hash, + "version": VERSION, + "fork_id": FORK_ID, + "engine_version": engine_version, + "manifest_url": MANIFEST_URL, + "manifest_download_url": MANIFEST_DOWNLOAD_URL, + "manifest_hash": manifest_hash + }) + +def generate_manifest_hash(file: str) -> str: + zip = ZipFile(file) + infos = zip.infolist() + infos.sort(key=lambda i: i.filename) + + bytesIO = io.BytesIO() + writer = codecs.getwriter("UTF-8")(bytesIO) + writer.write("Robust Content Manifest 1\n") + + for info in infos: + if info.filename[-1] == "/": + continue + + bytes = zip.read(info) + hash = hashlib.blake2b(bytes, digest_size=32).hexdigest().upper() + writer.write(f"{hash} {info.filename}\n") + + manifestHash = hashlib.blake2b(bytesIO.getbuffer(), digest_size=32) + + return manifestHash.hexdigest().upper() + +def get_engine_version() -> str: + proc = subprocess.run(["git", "describe","--tags", "--abbrev=0"], stdout=subprocess.PIPE, cwd="RobustToolbox", check=True, encoding="UTF-8") + tag = proc.stdout.strip() + assert tag.startswith("v") + return tag[1:] # Cut off v prefix. + + +def sha256_file(path: str) -> str: + with open(path, "rb") as f: + h = hashlib.sha256() + for b in iter(lambda: f.read(4096), b""): + h.update(b) + + return h.hexdigest() + +if __name__ == '__main__': + main()