1
0

Compare commits

...

54 Commits

Author SHA1 Message Date
jim[bot]
4a762b51bb fetch upstream mod changes (20251224_164347Z) 2025-12-24 17:43:47 +01:00
jim[bot]
cb9ee8ec86 fetch upstream mod changes (20251224_161355Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 26s
2025-12-24 17:13:55 +01:00
jim[bot]
84b0a62f26 fetch upstream mod changes (20251224_154354Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 37s
2025-12-24 16:43:54 +01:00
jim[bot]
ae3137cef1 fetch upstream mod changes (20251224_151352Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 34s
2025-12-24 16:13:52 +01:00
jim[bot]
6ef2df7891 fetch upstream mod changes (20251224_144350Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 34s
2025-12-24 15:43:50 +01:00
jim[bot]
446264ddf4 fetch upstream mod changes (20251224_141353Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 28s
2025-12-24 15:13:53 +01:00
jim[bot]
944b73fc9e fetch upstream mod changes (20251224_134348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 30s
2025-12-24 14:43:49 +01:00
jim[bot]
ddfb2f3a2e fetch upstream mod changes (20251224_131348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 26s
2025-12-24 14:13:48 +01:00
jim[bot]
e0348c089c fetch upstream mod changes (20251224_124348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 27s
2025-12-24 13:43:48 +01:00
jim[bot]
8def57cfd9 fetch upstream mod changes (20251224_121348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 26s
2025-12-24 13:13:49 +01:00
jim[bot]
904b99f0b9 fetch upstream mod changes (20251224_114349Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 26s
2025-12-24 12:43:49 +01:00
jim[bot]
07996c3952 fetch upstream mod changes (20251224_111349Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 27s
2025-12-24 12:13:49 +01:00
jim[bot]
643d5e9ea2 fetch upstream mod changes (20251224_104348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 27s
2025-12-24 11:43:48 +01:00
jim[bot]
5d9a8d0728 fetch upstream mod changes (20251224_101351Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 27s
2025-12-24 11:13:51 +01:00
jim[bot]
75d93ace0d fetch upstream mod changes (20251224_094349Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 31s
2025-12-24 10:43:49 +01:00
jim[bot]
86cc19928d fetch upstream mod changes (20251224_091348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 28s
2025-12-24 10:13:48 +01:00
jim[bot]
1a94942cf5 fetch upstream mod changes (20251224_084348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 25s
2025-12-24 09:43:48 +01:00
jim[bot]
e0e9106b14 fetch upstream mod changes (20251224_081346Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 25s
2025-12-24 09:13:47 +01:00
jim[bot]
ab8e03ce57 fetch upstream mod changes (20251224_074349Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 25s
2025-12-24 08:43:50 +01:00
jim[bot]
4de4a2fcb2 fetch upstream mod changes (20251224_071345Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 27s
2025-12-24 08:13:45 +01:00
jim[bot]
4719842ddb fetch upstream mod changes (20251224_064347Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 22s
2025-12-24 07:43:47 +01:00
jim[bot]
138c3d9c5c fetch upstream mod changes (20251224_061347Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 23s
2025-12-24 07:13:47 +01:00
jim[bot]
65071a5963 fetch upstream mod changes (20251224_054348Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 25s
2025-12-24 06:43:48 +01:00
jim[bot]
41cf13cf53 fetch upstream mod changes (20251224_051347Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 25s
2025-12-24 06:13:47 +01:00
jim[bot]
65b5f239f9 fetch upstream mod changes (20251224_045017Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 24s
2025-12-24 05:50:17 +01:00
jim[bot]
e4835460be fetch upstream mod changes (20251224_041415Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 32s
2025-12-24 05:14:15 +01:00
jim[bot]
962855dd70 fetch upstream mod changes (20251224_035728Z)
All checks were successful
fetch upstream mod changes / replace-mods (push) Successful in 25s
2025-12-24 04:57:28 +01:00
Ö. Efe D.
f5395bbd99 remove scripts 2025-12-24 04:49:50 +01:00
jim[bot]
b7e8694b42 fetch upstream mod changes (20251224_034719Z) 2025-12-24 04:47:19 +01:00
aeea64ac34 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:46:39 +00:00
jim[bot]
50c7b5cfb5 fetch upstream mod changes (20251224_034219Z)
Some checks failed
fetch upstream mod changes / replace-mods (push) Failing after 19s
2025-12-24 04:42:19 +01:00
9296535bc2 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:41:57 +00:00
1685214f56 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:41:16 +00:00
1134e33248 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:40:32 +00:00
9fddbfe53d Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:36:14 +00:00
3e34aa18ee Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:34:56 +00:00
605bd684ea Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:33:41 +00:00
936273edba add http port 2025-12-24 03:32:21 +00:00
5c7b766589 use token 2025-12-24 03:29:26 +00:00
fd7cc5fae8 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:15:52 +00:00
7c96d78c5f Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:14:28 +00:00
dfed9b9793 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:13:51 +00:00
a59331b191 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:12:11 +00:00
f00eeea001 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:10:21 +00:00
add398cf30 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:07:36 +00:00
1a6cdb7a46 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 03:02:38 +00:00
9d0f0dd20c remove ssh from git origin url 2025-12-24 02:58:53 +00:00
cbb2b200d9 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 02:50:24 +00:00
3aabfeb826 Update .github/workflows/fetch-upstream-mods.yml 2025-12-24 02:49:12 +00:00
Ö. Efe D.
a7d8a0ba0b remove temp upstream first when cloning
Some checks failed
fetch upstream mod changes / replace-mods (push) Failing after 18s
2025-12-24 03:08:23 +01:00
Ö. Efe D.
5923ab136c Remove install deps 2025-12-24 03:06:35 +01:00
Ö. Efe D.
9ebb8f16e6 Only use correct runners on Gitea 2025-12-24 02:57:10 +01:00
Ö. Efe D.
67f4d4ac62 Add upstream sync workflow (Gitea) 2025-12-24 02:49:33 +01:00
Ö. Efe D.
a0507b1723 Enable Git LFS for mods (Gitea only) 2025-12-24 02:48:37 +01:00
756 changed files with 1714 additions and 8104 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
mods/** filter=lfs diff=lfs merge=lfs -text

View File

@@ -1,5 +0,0 @@
certifi==2025.4.26
charset-normalizer==3.4.2
idna==3.10
requests==2.32.3
urllib3==2.4.0

View File

@@ -1 +0,0 @@
requests

View File

@@ -1,291 +0,0 @@
#!/usr/bin/env python3
import json
import os
import re
import sys
import time
from datetime import datetime
from enum import Enum
from pathlib import Path
import requests
# GitHub API rate limits are higher with authentication
GITHUB_TOKEN = os.environ.get('GITHUB_TOKEN')
HEADERS = {'Authorization': f'token {GITHUB_TOKEN}'} if GITHUB_TOKEN else {}
TIME_NOW = int(time.time())
def extract_repo_info(repo_url):
"""Extract owner and repo name from GitHub repo URL."""
match = re.search(r'github\.com/([^/]+)/([^/]+)', repo_url)
if match:
owner = match.group(1)
repo = match.group(2)
# Remove .git suffix if present
repo = repo.removesuffix('.git')
return owner, repo
return None, None
VersionSource = Enum("VersionSource", [
("LATEST_TAG", "release"),
("HEAD", "commit"),
("SPECIFIC_TAG", "specific_tag"),
])
def get_version_string(source: Enum, owner, repo, start_timestamp, n = 1, tag_data=None):
"""Get the version string from a given GitHub repo."""
if source is VersionSource.LATEST_TAG:
url = f'https://api.github.com/repos/{owner}/{repo}/releases/latest'
elif source is VersionSource.SPECIFIC_TAG:
if not tag_data:
print(f"ERROR: SPECIFIC_TAG source requires tag_name")
return None
tag_name = tag_data['name']
url = f'https://api.github.com/repos/{owner}/{repo}/releases/tags/{tag_name}'
else:
if not source is VersionSource.HEAD:
print(f"UNIMPLEMENTED(VersionSource): `{source}`,\nfalling back to `HEAD`")
source = VersionSource.HEAD
url = f'https://api.github.com/repos/{owner}/{repo}/commits'
try:
response = requests.get(url, headers=HEADERS)
api_rate_limit = int(response.headers.get('x-ratelimit-limit'))
api_rate_usage = int(response.headers.get('x-ratelimit-used'))
api_rate_remaining = int(response.headers.get('x-ratelimit-remaining'))
api_reset_timestamp = int(response.headers.get('x-ratelimit-reset'))
api_resource = response.headers.get('x-ratelimit-resource')
print(f"GitHub API ({api_resource}) calls: {api_rate_usage}/{api_rate_limit}")
if response.status_code == 404:
# Not found
return None
if response.status_code == 200:
data = response.json()
if source is VersionSource.LATEST_TAG:
# Return name of latest tag
return data.get('tag_name')
elif source is VersionSource.SPECIFIC_TAG:
assets = data.get('assets', [])
if not assets:
print(f"⚠️ No assets found in release {tag_name}")
return None
latest_created_at = ""
latest_asset = None
for asset in assets:
created_at = asset.get('created_at', '')
if created_at > latest_created_at:
latest_created_at = created_at
latest_asset = asset['name']
# Convert 2099-12-31T01:02:03Z to 20991231_010203
parts = latest_created_at.replace('Z', '').split('T')
date_part = parts[0].replace('-', '') # 20991231
time_part = parts[1].replace(':', '') # 010203
version = f"{date_part}_{time_part}" # 20991231_010203
tag_data['file'] = latest_asset
return version
if data and len(data) > 0:
# Return shortened commit hash (first 7 characters)
return data[0]['sha'][:7]
print(f"⚠️ Warning: unexpected response format for {source}s:\n{
json.dumps(data, indent=2, ensure_ascii=False)
}")
return
if api_rate_remaining == 0 or (
response.status_code == 403
and "rate limit exceeded" in response.text.lower()
):
print(f"GitHub API access is being rate limited!")
current_timestamp = int(time.time())
# Check if primary rate limit is okay
if api_rate_remaining > 0:
# Secondary rate limit hit, follow GitHub instructions
if 'retry-after' in response.headers:
wait_time = int(response.headers.get('retry-after')) + 5
print(f"Response retry-after {wait_time}s")
else:
# Start at 60 seconds and double wait time with each new attempt
print(f"Attempt {n}")
wait_time = 60 * pow(2, n - 1)
else:
api_reset_time = datetime.fromtimestamp(api_reset_timestamp).strftime('%H:%M:%S')
print(f"GitHub API rate limit resets at {api_reset_time}")
wait_time = api_reset_timestamp - current_timestamp + 5
# Wait only if the wait time would finish less than 1800 seconds (30 min) after program start time
if current_timestamp + wait_time - start_timestamp < 1800:
print(f"Waiting {wait_time} seconds until next attempt...")
time.sleep(wait_time)
n += 1
return get_version_string(source, owner, repo, start_timestamp, n, tag_data=tag_data) # Retry
else:
print(f"Next attempt in {wait_time} seconds, but Action run time would exceed 1800 seconds - Stopping...")
sys.exit(1)
else:
print(f"Error fetching {source}s: HTTP {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"Exception while fetching {source}s: {str(e)}")
return None
def process_mods(start_timestamp):
"""Process all mods and update versions where needed."""
mods_dir = Path('mods')
updated_mods = []
print(f"Scanning {mods_dir} for mods with automatic version control...")
# Find all mod directories
for mod_dir in (d for d in mods_dir.iterdir() if d.is_dir()):
meta_file = mod_dir / 'meta.json'
if not meta_file.exists():
continue
try:
if mod := process_mod(start_timestamp, mod_dir.name, mod_dir / 'meta.json'):
updated_mods.append(mod)
except Exception as e:
print(f"❌ Error processing {mod_dir.name}: {str(e)}")
return updated_mods
def process_mod(start_timestamp, name, meta_file):
if not meta_file.exists():
return
with open(meta_file, 'r', encoding='utf-8') as f:
meta = json.load(f)
# Skip mods without automatic version checking enabled
if not meta.get('automatic-version-check'):
return
print(f"Processing {name}...")
repo_url = meta.get('repo')
if not repo_url:
print(f"⚠️ Warning: Mod {name} has automatic-version-check but no repo URL")
return
owner, repo = extract_repo_info(repo_url)
if not owner or not repo:
print(f"⚠️ Warning: Could not extract repo info from {repo_url}")
return
print(f"Checking GitHub repo: `{owner}/{repo}`")
# If download url links to latest head, use version of latest commit hash
download_url = meta.get('downloadURL')
new_version = None
if "/archive/refs/heads/" in download_url:
print("Download URL links to HEAD, checking latest commit...")
source = VersionSource.HEAD
new_version = get_version_string(VersionSource.HEAD, owner, repo, start_timestamp)
elif (meta.get('fixed-release-tag-updates') == True) and "/releases/download/" in download_url:
source = VersionSource.SPECIFIC_TAG
tag_data = {}
# Pattern: /releases/download/{tag}/{file} - tag is second-to-last
print("Download URL links to specific release asset, checking that asset's tag...")
tag_name = download_url.split('/')[-2]
print(f"Checking release tag: {tag_name}")
tag_data['name'] = tag_name
new_version = get_version_string(
source, owner, repo, start_timestamp, tag_data=tag_data
)
else:
print("Checking releases for latest version tag...")
source = VersionSource.LATEST_TAG
new_version = get_version_string(source, owner, repo, start_timestamp)
if not new_version:
print("No releases found, falling back to latest commit instead...")
source = VersionSource.HEAD
new_version = get_version_string(source, owner, repo, start_timestamp)
if not new_version:
print(f"⚠️ Warning: Could not determine version for {name}")
return
current_version = meta.get('version')
# Update version if it changed
if current_version == new_version:
print(f" No version change for {name} (current: {current_version})")
return
print(
f"✅ Updating {name} from {current_version} to {new_version} ({source})"
)
meta['version'] = new_version
meta['last-updated'] = TIME_NOW
if "/archive/refs/tags/" in download_url:
meta['downloadURL'] = f"{repo_url}/archive/refs/tags/{meta['version']}.zip"
elif source == VersionSource.SPECIFIC_TAG:
meta['downloadURL'] = f"{repo_url}/releases/download/{tag_data['name']}/{tag_data['file']}"
with open(meta_file, 'w', encoding='utf-8') as f:
# Preserve formatting with indentation
json.dump(meta, f, indent=2, ensure_ascii=False)
f.write("\n") # Add newline at end of file
return {
'name': meta.get('title', name),
'old_version': current_version,
'new_version': meta['version'],
'source': source
}
def generate_commit_message(updated_mods):
"""Generate a detailed commit message listing all updated mods."""
if not updated_mods:
return "No mod versions updated"
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = f"Auto-update mod versions ({timestamp})\n\n"
message += "Updated mods:\n"
for mod in updated_mods:
old_ver = mod['old_version'] or 'none'
message += f"- {mod['name']}: {old_ver}{mod['new_version']} ({mod['source']})\n"
return message
if __name__ == "__main__":
start_timestamp = int(time.time())
start_datetime = datetime.fromtimestamp(start_timestamp).strftime('%H:%M:%S')
print(f"🔄 Starting automatic mod version update at {start_datetime}...")
updated_mods = process_mods(start_timestamp)
if updated_mods:
# Write commit message to a file that the GitHub Action can use
commit_message = generate_commit_message(updated_mods)
with open('commit_message.txt', 'w', encoding='utf-8') as f:
f.write(commit_message)
print(f"✅ Completed. Updated {len(updated_mods)} mod versions.")
else:
print(" Completed. No mod versions needed updating.")
# Exit with status code 0 even if no updates were made
sys.exit(0)

View File

@@ -1,151 +0,0 @@
name: Validate Balatro Mods
on:
pull_request:
paths:
- "mods/**"
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # Get full history for comparing changes
- name: Use ImageMagick from cache
uses: awalsh128/cache-apt-pkgs-action@v1
with:
packages: imagemagick
version: 8:6.9.12.98+dfsg1-5.2build2
- name: Identify Changed Mods
id: find-changed-mods
run: |
# Get the list of files changed in the PR using GitHub API
API_RESPONSE=$(curl -s -X GET \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files")
# Use fallback method if API fails
if echo "$API_RESPONSE" | jq -e 'if type=="array" then true else false end' > /dev/null; then
echo "Using GitHub API method to find changed files"
echo "$API_RESPONSE" | jq -r '.[] | .filename' | grep -E '^mods/[^/]+/' | cut -d'/' -f1-2 | sort | uniq > changed_mods.txt
else
echo "Using git diff method as fallback"
# Fetch the base branch of the PR
git fetch origin ${{ github.event.pull_request.base.ref }}
# Find all added or modified files in mods directory using git diff
git diff --name-only --diff-filter=AM origin/${{ github.event.pull_request.base.ref }}..HEAD | grep -E '^mods/[^/]+/' | cut -d'/' -f1-2 | sort | uniq > changed_mods.txt
fi
# Check if any mods were found
if [ ! -s changed_mods.txt ]; then
echo "No mods were added or modified in this PR."
echo "changed_mods_found=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "Changed mods found:"
cat changed_mods.txt
echo "changed_mods_found=true" >> $GITHUB_OUTPUT
# Create a newline-separated list for JSON schema validation
META_JSON_FILES=$(while read -r mod_path; do
[ -f "$mod_path/meta.json" ] && echo "$mod_path/meta.json"
done < changed_mods.txt)
echo "meta_json_files<<EOF" >> $GITHUB_OUTPUT
echo "$META_JSON_FILES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Check Required Files
if: steps.find-changed-mods.outputs.changed_mods_found == 'true'
run: |
while read -r mod_path; do
if [ -d "$mod_path" ]; then
MOD_DIR="$(basename "$mod_path")"
# Ensure description.md and meta.json exist
if [ ! -f "$mod_path/description.md" ]; then
echo "Error: Missing description.md in $MOD_DIR"
exit 1
fi
if [ ! -f "$mod_path/meta.json" ]; then
echo "Error: Missing meta.json in $MOD_DIR"
exit 1
fi
fi
done < changed_mods.txt
- name: Check Thumbnail Dimensions
if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
run: |
while read -r mod_path; do
if [ -d "$mod_path" ]; then
MOD_DIR="$(basename "$mod_path")"
THUMBNAIL="$mod_path/thumbnail.jpg"
if [ -f "$THUMBNAIL" ]; then
# Extract width and height using ImageMagick identify
# Using identify-im6.q16 directly as identify is a symlink that is not created by the cache restoration
DIMENSIONS=$(/usr/bin/identify-im6.q16 -format "%wx%h" "$THUMBNAIL")
WIDTH=$(echo "$DIMENSIONS" | cut -dx -f1)
HEIGHT=$(echo "$DIMENSIONS" | cut -dx -f2)
# Check if dimensions exceed 1920x1080
if [ "$WIDTH" -gt 1920 ] || [ "$HEIGHT" -gt 1080 ]; then
echo "Error: Thumbnail in $MOD_DIR exceeds the recommended size of 1920×1080."
exit 1
fi
fi
fi
done < changed_mods.txt
- name: Validate JSON Format
if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
run: |
# Use jq to validate each JSON file
while read -r mod_path; do
if [ -f "$mod_path/meta.json" ]; then
if ! jq empty "$mod_path/meta.json" 2>/dev/null; then
echo "Error: Invalid JSON format in $mod_path/meta.json"
exit 1
fi
fi
done < changed_mods.txt
- name: Validate meta.json Against Schema
if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
uses: dsanders11/json-schema-validate-action@v1.4.0
with:
schema: "./schema/meta.schema.json"
files: ${{ steps.find-changed-mods.outputs.meta_json_files }}
custom-errors: true
- name: Validate Download URLs
if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
run: |
while read -r mod_path; do
if [ -d "$mod_path" ]; then
MOD_DIR="$(basename "$mod_path")"
META_JSON="$mod_path/meta.json"
# Check if downloadURL exists and is not empty
DOWNLOAD_URL=$(jq -r '.downloadURL // empty' "$META_JSON")
if [ -z "$DOWNLOAD_URL" ]; then
echo "Error: Missing or empty downloadURL in $MOD_DIR/meta.json"
exit 1
fi
# Optional: Check if URL is accessible
if ! curl --output /dev/null --silent --head --fail "$DOWNLOAD_URL"; then
echo "Error: downloadURL in $MOD_DIR/meta.json is not accessible"
exit 1
fi
fi
done < changed_mods.txt

View File

@@ -0,0 +1,69 @@
name: fetch upstream mod changes
on:
schedule:
- cron: "13,43 * * * *"
workflow_dispatch:
jobs:
replace-mods:
runs-on: ubuntu-latest
steps:
- name: Clone Gitea repo (skip LFS smudge)
run: |
rm -rf repo /tmp/upstream
GIT_LFS_SKIP_SMUDGE=1 \
git clone ssh://git@smallgit.dasguney.com:2222/skyline/balatro-mod-index.git repo
- name: Configure LFS and fetch objects
env:
GITEA_TOKEN: ${{ secrets.GT_TOKEN }}
run: |
cd repo
# Auth for Git + LFS
printf "machine smallgit.dasguney.com\nlogin skyline\npassword %s\n" "$GITEA_TOKEN" > ~/.netrc
chmod 600 ~/.netrc
# Force LFS to use direct Gitea endpoint (no nginx)
git config lfs.url "http://smallgit.dasguney.com:3000/skyline/balatro-mod-index.git/info/lfs"
git config lfs."http://smallgit.dasguney.com:3000/skyline/balatro-mod-index.git/info/lfs".locksverify false
# Install hooks and explicitly fetch LFS data
git lfs install --local
git lfs fetch origin
git lfs checkout
- name: Clone upstream GitHub repo
run: |
git clone https://github.com/skyline69/balatro-mod-index.git /tmp/upstream
- name: Replace mods directory
run: |
cd repo
rm -rf mods
cp -a /tmp/upstream/mods ./mods
- name: Append last-updated timestamp
run: |
cd repo
TIME_NOW=$(date +"%s")
git diff -z --name-only | grep -z meta.json | while IFS='' read -r -d '' file; do
jq --indent 2 '."last-updated" |= (. // '"$TIME_NOW"')' "$file" | sponge "$file"
done
- name: Commit and push
run: |
cd repo
git config user.name "jim[bot]"
git config user.email "jim[bot]@users.noreply.github.com"
# Use direct Gitea HTTP endpoint for push
git remote set-url origin http://smallgit.dasguney.com:3000/skyline/balatro-mod-index.git
git add mods
if git commit -m "fetch upstream mod changes ($(date --utc +%Y%m%d_%H%M%SZ))"; then
git push origin main
fi

View File

@@ -1,51 +0,0 @@
name: Update Mod Versions
on:
schedule:
- cron: '0 * * * *' # Run every hour
workflow_dispatch: # Allow manual triggers
jobs:
update-versions:
runs-on: ubuntu-latest
if: github.repository == 'skyline69/balatro-mod-index'
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
token: ${{ secrets.PAT_TOKEN }} # Use PAT for checkout
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
cache: 'pip' # This enables pip caching
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r .github/scripts/requirements.lock
- name: Update mod versions
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
python .github/scripts/update_mod_versions.py
- name: Commit and push changes
run: |
git config --global user.name 'Version Update Bot'
git config --global user.email 'bot@noreply.github.com'
if [[ $(git status --porcelain) ]]; then
COMMIT_MSG="Auto-update mod versions"
if [ -f commit_message.txt ]; then
COMMIT_MSG=$(cat commit_message.txt)
fi
git add mods/*/meta.json
git commit -m "$COMMIT_MSG"
git push
else
echo "No changes to commit"
fi

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 131 B

Some files were not shown because too many files have changed in this diff Show More