Implement CDN uploading (#34)
This commit is contained in:
committed by
GitHub
parent
4ab2377970
commit
71bf2631f4
@@ -0,0 +1,21 @@
|
||||
name: Publish Apps
|
||||
|
||||
inputs:
|
||||
sdk_version:
|
||||
description: The SDK version that determines the path on the CDN
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: 'Download cdn-files'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: 'cdn-files'
|
||||
path: cdn_files
|
||||
- name: 'Install boto3'
|
||||
shell: bash
|
||||
run: pip install boto3
|
||||
- name: 'Upload files'
|
||||
shell: bash
|
||||
run: python Buildscripts/CDN/upload-app-files.py cdn_files ${{ inputs.sdk_version }} ${{ env.CDN_ID }} ${{ env.CDN_TOKEN_NAME }} ${{ env.CDN_TOKEN_VALUE }}
|
||||
@@ -1,5 +1,10 @@
|
||||
name: Release Apps
|
||||
|
||||
outputs:
|
||||
sdk_version:
|
||||
description: 'Common SDK version shared by all bundled apps'
|
||||
value: ${{ steps.release.outputs.sdk_version }}
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
@@ -11,8 +16,11 @@ runs:
|
||||
run: rsync -av downloaded_apps/*/*.app cdn_files/
|
||||
shell: bash
|
||||
- name: 'Create CDN release files'
|
||||
run: python release.py cdn_files/
|
||||
id: release
|
||||
shell: bash
|
||||
run: |
|
||||
python release.py cdn_files/
|
||||
echo "sdk_version=$(cat sdk_version.txt)" >> "$GITHUB_OUTPUT"
|
||||
- name: 'Upload Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
@@ -16,6 +16,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: "Build"
|
||||
uses: ./.github/actions/build-app
|
||||
with:
|
||||
@@ -23,7 +25,26 @@ jobs:
|
||||
Bundle:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [Build]
|
||||
outputs:
|
||||
sdk_version: ${{ steps.release.outputs.sdk_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Build"
|
||||
id: release
|
||||
uses: ./.github/actions/release-apps
|
||||
PublishApps:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [Bundle]
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: "Publish Apps"
|
||||
env:
|
||||
CDN_ID: ${{ secrets.CDN_ID }}
|
||||
CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }}
|
||||
CDN_TOKEN_VALUE: ${{ secrets.CDN_TOKEN_VALUE }}
|
||||
uses: ./.github/actions/publish-apps
|
||||
with:
|
||||
sdk_version: ${{ needs.Bundle.outputs.sdk_version }}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import os
|
||||
import sys
|
||||
import boto3
|
||||
|
||||
SHELL_COLOR_RED = "\033[91m"
|
||||
SHELL_COLOR_ORANGE = "\033[93m"
|
||||
SHELL_COLOR_RESET = "\033[m"
|
||||
|
||||
def print_warning(message):
|
||||
print(f"{SHELL_COLOR_ORANGE}WARNING: {message}{SHELL_COLOR_RESET}")
|
||||
|
||||
def print_error(message):
|
||||
print(f"{SHELL_COLOR_RED}ERROR: {message}{SHELL_COLOR_RESET}")
|
||||
|
||||
def print_help():
|
||||
print("Usage: python upload-app-files.py [path] [sdkVersion] [cloudflareAccountId] [cloudflareTokenName] [cloudflareTokenValue]")
|
||||
print("")
|
||||
print("Options:")
|
||||
print(" --index-only Upload only apps.json")
|
||||
|
||||
def exit_with_error(message):
|
||||
print_error(message)
|
||||
sys.exit(1)
|
||||
|
||||
def main(path: str, sdk_version: str, cloudflare_account_id, cloudflare_token_name: str, cloudflare_token_value: str, index_only: bool):
|
||||
if not os.path.exists(path):
|
||||
exit_with_error(f"Path not found: {path}")
|
||||
s3 = boto3.client(
|
||||
service_name="s3",
|
||||
endpoint_url=f"https://{cloudflare_account_id}.r2.cloudflarestorage.com",
|
||||
aws_access_key_id=cloudflare_token_name,
|
||||
aws_secret_access_key=cloudflare_token_value,
|
||||
region_name="auto"
|
||||
)
|
||||
files_to_upload = os.listdir(path)
|
||||
if index_only:
|
||||
files_to_upload = [f for f in files_to_upload if f == 'apps.json']
|
||||
else:
|
||||
# Ensure apps.json is uploaded last so it never references files that
|
||||
# haven't finished uploading yet.
|
||||
files_to_upload.sort(key=lambda f: f == 'apps.json')
|
||||
counter = 1
|
||||
total = len(files_to_upload)
|
||||
for file_name in files_to_upload:
|
||||
object_path = f"apps/{sdk_version}/{file_name}"
|
||||
print(f"[{counter}/{total}] Uploading {file_name} to {object_path}")
|
||||
file_path = os.path.join(path, file_name)
|
||||
try:
|
||||
s3.upload_file(file_path, "tactility", object_path)
|
||||
except Exception as e:
|
||||
exit_with_error(f"Failed to upload {file_name}: {str(e)}")
|
||||
counter += 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Tactility CDN Apps Uploader")
|
||||
if "--help" in sys.argv:
|
||||
print_help()
|
||||
sys.exit()
|
||||
# Argument validation
|
||||
if len(sys.argv) < 6:
|
||||
print_help()
|
||||
sys.exit(1)
|
||||
main(
|
||||
path=sys.argv[1],
|
||||
sdk_version=sys.argv[2],
|
||||
cloudflare_account_id=sys.argv[3],
|
||||
cloudflare_token_name=sys.argv[4],
|
||||
cloudflare_token_value=sys.argv[5],
|
||||
index_only="--index-only" in sys.argv
|
||||
)
|
||||
+25
-4
@@ -1,8 +1,10 @@
|
||||
import json
|
||||
import subprocess
|
||||
import tarfile
|
||||
import os
|
||||
import tempfile
|
||||
import sys
|
||||
from datetime import datetime, UTC
|
||||
|
||||
def read_properties_file(path):
|
||||
properties = {}
|
||||
@@ -81,6 +83,17 @@ def get_os_version(manifest):
|
||||
else:
|
||||
return sdk
|
||||
|
||||
def check_and_get_sdk_version(manifest_map):
|
||||
"""Ensure all apps target the same (simplified) SDK version and return it."""
|
||||
versions = {get_os_version(manifest) for manifest in manifest_map.values()}
|
||||
if len(versions) != 1:
|
||||
print(f"ERROR: Apps target multiple SDK versions: {sorted(versions)}. All apps must target the same SDK version.")
|
||||
sys.exit(1)
|
||||
return next(iter(versions))
|
||||
|
||||
def get_git_commit_hash():
|
||||
return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('ascii').strip()
|
||||
|
||||
def manifest_config_to_flat_json(manifest):
|
||||
"""Convert a flat (V2) manifest dict into a flat JSON-like dict.
|
||||
|
||||
@@ -136,15 +149,23 @@ if __name__ == "__main__":
|
||||
sys.exit()
|
||||
app_directory = sys.argv[1]
|
||||
manifest_map = {}
|
||||
output_json = {
|
||||
"apps": []
|
||||
}
|
||||
any_manifest = None
|
||||
if os.path.exists(app_directory):
|
||||
for file in os.listdir(app_directory):
|
||||
if file.endswith(".app"):
|
||||
file_path = os.path.join(app_directory, file)
|
||||
manifest_map[file_path] = get_manifest(file_path)
|
||||
# All bundled apps must target the same SDK version; this becomes the CDN path segment
|
||||
sdk_version = check_and_get_sdk_version(manifest_map)
|
||||
with open("sdk_version.txt", "w") as f:
|
||||
f.write(sdk_version)
|
||||
print(f"SDK version: {sdk_version}")
|
||||
output_json = {
|
||||
"sdkVersion": sdk_version,
|
||||
"created": datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%SZ'),
|
||||
"gitCommit": get_git_commit_hash(),
|
||||
"apps": []
|
||||
}
|
||||
# Rename files and collect manifest data into output json object
|
||||
for file_path in manifest_map.keys():
|
||||
print(f"Processing {file_path}: {manifest_map[file_path]}")
|
||||
@@ -158,4 +179,4 @@ if __name__ == "__main__":
|
||||
any_manifest = manifest
|
||||
# Write JSON
|
||||
output_json_path = os.path.join(app_directory, "apps.json")
|
||||
write_json(output_json_path, output_json)
|
||||
write_json(output_json_path, output_json)
|
||||
|
||||
Reference in New Issue
Block a user