forked from Conjure-Tools/unity-runner
updated readme
This commit is contained in:
parent
19a241cf70
commit
5299db116d
@ -17,11 +17,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.10'
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install docker
|
|
||||||
|
|
||||||
- name: Log in to Docker Registry
|
- name: Log in to Docker Registry
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
@ -30,10 +25,11 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
- name: Generate Docker Images Table
|
- name: Generate Docker Images Table
|
||||||
run: python scripts/build-readme.py
|
run: python scripts/update-readme.py
|
||||||
env:
|
env:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
DOCKER_REGISTRY: docker.lakes.house
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
- name: Commit changes if README was updated
|
- name: Commit changes if README was updated
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
10
README.md
10
README.md
@ -1,3 +1,9 @@
|
|||||||
# unity-editor
|
# Unity Docker Images
|
||||||
|
|
||||||
Docker images for the unity editor to be used in CI
|
A table of available Docker images for Unity CI/CD:
|
||||||
|
|
||||||
|
<!-- table -->
|
||||||
|
| unity | android | webgl |
|
||||||
|
|---------|----------|----------|
|
||||||
|
| 6000.0.35f1 | ubuntu-6000.0.35f1-android-runner | ubuntu-6000.0.35f1-webgl-runner |
|
||||||
|
<!-- /table -->
|
||||||
|
|||||||
@ -1,83 +0,0 @@
|
|||||||
import docker
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
# Connect to Docker registry
|
|
||||||
client = docker.from_env()
|
|
||||||
client.login(
|
|
||||||
username=os.environ["DOCKER_USERNAME"],
|
|
||||||
password=os.environ["DOCKER_PASSWORD"],
|
|
||||||
registry="docker.lakes.house"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Define the base repository
|
|
||||||
base_repo = "docker.lakes.house/unityci/editor"
|
|
||||||
|
|
||||||
# Get all images
|
|
||||||
images = []
|
|
||||||
try:
|
|
||||||
# For a real registry we would use the client.images.search, but for private registry
|
|
||||||
# we need to list tags for the repository
|
|
||||||
# This might require API calls specific to your registry
|
|
||||||
# For this example, we assume we can get a list of tags
|
|
||||||
response = client.api.get_registry_data(base_repo)
|
|
||||||
for tag in response.get("tags", []):
|
|
||||||
images.append(f"{base_repo}:{tag}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error listing images: {e}")
|
|
||||||
# Fallback approach or error handling
|
|
||||||
|
|
||||||
# Process images to extract Unity versions and platforms
|
|
||||||
unity_platforms = defaultdict(set)
|
|
||||||
image_map = defaultdict(dict)
|
|
||||||
|
|
||||||
pattern = re.compile(r"ubuntu-(\d+\.\d+\.\d+\w*)-(\w+)-runner")
|
|
||||||
|
|
||||||
for image in images:
|
|
||||||
match = pattern.search(image)
|
|
||||||
if match:
|
|
||||||
unity_version = match.group(1)
|
|
||||||
platform = match.group(2)
|
|
||||||
unity_platforms[unity_version].add(platform)
|
|
||||||
image_map[unity_version][platform] = image
|
|
||||||
|
|
||||||
# Get all unique platforms
|
|
||||||
all_platforms = set()
|
|
||||||
for platforms in unity_platforms.values():
|
|
||||||
all_platforms.update(platforms)
|
|
||||||
all_platforms = sorted(list(all_platforms))
|
|
||||||
|
|
||||||
# Generate markdown table
|
|
||||||
markdown = "# Unity Docker Images\n\n"
|
|
||||||
markdown += "A table of available Docker images for Unity CI/CD:\n\n"
|
|
||||||
markdown += "| Unity Version |"
|
|
||||||
|
|
||||||
# Add platform headers
|
|
||||||
for platform in all_platforms:
|
|
||||||
markdown += f" {platform} |"
|
|
||||||
markdown += "\n|"
|
|
||||||
|
|
||||||
# Add separator row
|
|
||||||
for _ in range(len(all_platforms) + 1):
|
|
||||||
markdown += " --- |"
|
|
||||||
markdown += "\n"
|
|
||||||
|
|
||||||
# Add rows for each Unity version
|
|
||||||
for unity_version in sorted(unity_platforms.keys()):
|
|
||||||
markdown += f"| {unity_version} |"
|
|
||||||
|
|
||||||
for platform in all_platforms:
|
|
||||||
if platform in image_map[unity_version]:
|
|
||||||
image_name = image_map[unity_version][platform].split("/")[-1]
|
|
||||||
markdown += f" `{image_name}` |"
|
|
||||||
else:
|
|
||||||
markdown += " - |"
|
|
||||||
|
|
||||||
markdown += "\n"
|
|
||||||
|
|
||||||
# Write to README.md
|
|
||||||
with open("README.md", "w") as f:
|
|
||||||
f.write(markdown)
|
|
||||||
|
|
||||||
print("README updated successfully!")
|
|
||||||
172
scripts/update-readme.py
Normal file
172
scripts/update-readme.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
|
||||||
|
def get_docker_hub_tags(repository, limit=1000):
|
||||||
|
"""
|
||||||
|
Get tags for a Docker Hub repository
|
||||||
|
"""
|
||||||
|
url = f"https://hub.docker.com/v2/repositories/{repository}/tags"
|
||||||
|
params = {"page_size": limit}
|
||||||
|
|
||||||
|
# Check for Docker Hub credentials in environment variables
|
||||||
|
username = os.getenv('DOCKER_USERNAME')
|
||||||
|
password = os.getenv('DOCKER_PASSWORD')
|
||||||
|
|
||||||
|
# Create session for potential authentication
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
# Authenticate if credentials are provided
|
||||||
|
if username and password:
|
||||||
|
auth_url = "https://hub.docker.com/v2/users/login/"
|
||||||
|
auth_data = {"username": username, "password": password}
|
||||||
|
|
||||||
|
try:
|
||||||
|
auth_response = session.post(auth_url, json=auth_data)
|
||||||
|
auth_response.raise_for_status()
|
||||||
|
# Token is automatically stored in the session cookies
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Warning: Docker Hub authentication failed: {e}")
|
||||||
|
# Continue without authentication
|
||||||
|
|
||||||
|
all_tags = []
|
||||||
|
|
||||||
|
while url:
|
||||||
|
response = session.get(url, params=params)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"Error: Unable to fetch tags. Status code: {response.status_code}")
|
||||||
|
print(f"Response: {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
all_tags.extend([tag["name"] for tag in data["results"]])
|
||||||
|
|
||||||
|
# Get next page URL if it exists
|
||||||
|
url = data.get("next")
|
||||||
|
# Clear params since the next URL already includes them
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
return all_tags
|
||||||
|
|
||||||
|
def get_private_registry_tags(registry, repository):
|
||||||
|
"""
|
||||||
|
Get tags for a repository in a private registry
|
||||||
|
"""
|
||||||
|
# Check for registry credentials in environment variables
|
||||||
|
username = os.getenv('DOCKER_USERNAME')
|
||||||
|
password = os.getenv('DOCKER_PASSWORD')
|
||||||
|
|
||||||
|
# Ensure registry URL starts with https://
|
||||||
|
registry_url = registry if registry.startswith(('http://', 'https://')) else f'https://{registry}'
|
||||||
|
|
||||||
|
# Try to get an auth token first (token-based auth)
|
||||||
|
headers = {}
|
||||||
|
url = f"{registry_url}/v2/{repository}/tags/list"
|
||||||
|
|
||||||
|
# Make the request with appropriate authentication
|
||||||
|
if username and password:
|
||||||
|
# Use basic auth if we have credentials but no token
|
||||||
|
response = requests.get(url, headers=headers, auth=(username, password))
|
||||||
|
else:
|
||||||
|
# Use token auth or no auth
|
||||||
|
response = requests.get(url, headers=headers)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"Error: Unable to fetch tags. Status code: {response.status_code}")
|
||||||
|
print(f"Response: {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
return data.get("tags", [])
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Get all tags for a Docker image")
|
||||||
|
parser.add_argument("image", help="Docker image name (e.g., 'library/ubuntu' or 'nginx')")
|
||||||
|
parser.add_argument("--registry", help="Registry URL for private registry (can also set DOCKER_REGISTRY env var)", default=None)
|
||||||
|
parser.add_argument("--limit", type=int, help="Maximum number of tags to retrieve (Docker Hub only)", default=1000)
|
||||||
|
parser.add_argument("--output", help="Output file path (default: stdout)")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Check for registry in environment variable if not specified in args
|
||||||
|
registry = args.registry or os.getenv('DOCKER_REGISTRY')
|
||||||
|
repository = args.image
|
||||||
|
|
||||||
|
if registry:
|
||||||
|
print(f"Fetching tags for {repository} from {registry}...")
|
||||||
|
tags = get_private_registry_tags(registry, repository)
|
||||||
|
else:
|
||||||
|
print(f"Fetching tags for {repository} from Docker Hub...")
|
||||||
|
tags = get_docker_hub_tags(repository, args.limit)
|
||||||
|
|
||||||
|
# Sort tags
|
||||||
|
tags.sort()
|
||||||
|
|
||||||
|
versions={}
|
||||||
|
|
||||||
|
pattern = re.compile(r"(\w+)-(\d+\.\d+\.\d+\w*)-(\w+)-runner")
|
||||||
|
for tag in tags:
|
||||||
|
matches = pattern.match(tag)
|
||||||
|
if matches:
|
||||||
|
[ image_os, version, component ] = matches.groups()
|
||||||
|
if version not in versions:
|
||||||
|
versions[version] = {}
|
||||||
|
versions[version][component] = tag
|
||||||
|
|
||||||
|
# Get all unique components across all versions
|
||||||
|
print(versions)
|
||||||
|
all_components = set()
|
||||||
|
for version_components in versions.values():
|
||||||
|
all_components.update(version_components.keys())
|
||||||
|
all_components = sorted(list(all_components))
|
||||||
|
|
||||||
|
# Create markdown table header with components as columns
|
||||||
|
markdown = "| unity |"
|
||||||
|
for component in all_components:
|
||||||
|
markdown += f" {component} |"
|
||||||
|
markdown += "\n|---------|" + "----------|" * len(all_components) + "\n"
|
||||||
|
|
||||||
|
for version in sorted(versions.keys()):
|
||||||
|
markdown += f"| {version} |"
|
||||||
|
for component in all_components:
|
||||||
|
tag = versions[version].get(component, "")
|
||||||
|
markdown += f" {tag} |"
|
||||||
|
markdown += "\n"
|
||||||
|
|
||||||
|
# Read existing README.md
|
||||||
|
print("Updating README")
|
||||||
|
readme_path = "README.md"
|
||||||
|
if os.path.exists(readme_path):
|
||||||
|
with open(readme_path, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Replace content between markers
|
||||||
|
pattern = r'(<!-- table -->).*(<!-- /table -->)'
|
||||||
|
new_content = re.sub(pattern, r'\1\n' + markdown + r'\2', content, flags=re.DOTALL)
|
||||||
|
|
||||||
|
# Write back to README.md
|
||||||
|
with open(readme_path, 'w') as f:
|
||||||
|
f.write(new_content)
|
||||||
|
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Print environment variable usage information
|
||||||
|
if len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] in ['-h', '--help']):
|
||||||
|
print("\nEnvironment Variables:")
|
||||||
|
print(" DOCKER_REGISTRY - URL of private Docker registry")
|
||||||
|
print(" DOCKER_USERNAME - Username")
|
||||||
|
print(" DOCKER_PASSWORD - Password")
|
||||||
|
print("\nExample:")
|
||||||
|
print(" export DOCKER_REGISTRY=https://registry.example.com")
|
||||||
|
print(" export DOCKER_USERNAME=username")
|
||||||
|
print(" export DOCKER_PASSWORD=password")
|
||||||
|
print(" python docker_image_tags.py myproject/api\n")
|
||||||
|
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user