mirror of
https://github.com/xfl03/MCCustomSkinLoader.git
synced 2026-11-14 01:24:02 +00:00
Fix actions
This commit is contained in:
1 parent
8b5d440ed7
commit
756336e533
22 files changed
+334
-829
No files matched your search
@@ -0,0 +1,54 @@
|
||||
# Composite action: upload jars to R2/COS, generate and upload JSON metadata
|
||||
name: Publish
|
||||
description: Upload built artifacts to object storage and publish JSON metadata
|
||||
|
||||
inputs:
|
||||
artifact-dir:
|
||||
description: Directory containing built artifacts (relative to workspace)
|
||||
required: true
|
||||
type:
|
||||
description: Release type - 'beta' or 'release'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false # preserve artifact files already downloaded before this action
|
||||
|
||||
# Upload jars to R2 (S3-compatible, mods/ prefix)
|
||||
- uses: michaelliao/sync-s3-compatible-action@v1
|
||||
with:
|
||||
SYNC_DIR: ${{ inputs.artifact-dir }}
|
||||
BUCKET_URL: ${{ env.R2_BASE_URL }}
|
||||
BUCKET_NAME: ${{ env.R2_BUCKET }}
|
||||
AWS_ACCESS_KEY_ID: ${{ env.R2_SECRET_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ env.R2_SECRET_KEY }}
|
||||
TARGET_PATH: mods/
|
||||
|
||||
# Upload jars to COS (qcloud mode, mods/ prefix)
|
||||
- uses: michaelliao/sync-s3-compatible-action@v1
|
||||
with:
|
||||
SYNC_TYPE: qcloud
|
||||
SYNC_DIR: ${{ inputs.artifact-dir }}
|
||||
BUCKET_NAME: ${{ env.COS_BUCKET }}
|
||||
AWS_ACCESS_KEY_ID: ${{ env.COS_SECRET_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ env.COS_SECRET_KEY }}
|
||||
BUCKET_REGION: ap-shanghai
|
||||
TARGET_PATH: mods/
|
||||
|
||||
# Generate JSON metadata, upload to R2/COS root, and output CDN URLs
|
||||
- name: Generate and upload JSON metadata
|
||||
id: publish-json
|
||||
shell: pwsh
|
||||
run: .github/scripts/Publish-Json.ps1 -ArtifactDir '${{ inputs.artifact-dir }}' -Type '${{ inputs.type }}'
|
||||
|
||||
# Refresh Tencent Cloud CDN cache for the JSON files
|
||||
- name: Refresh CDN
|
||||
uses: tencentcloud/cdn-refresh-action@v1
|
||||
with:
|
||||
urls: ${{ steps.publish-json.outputs.cdn-urls }}
|
||||
secret-id: ${{ env.COS_SECRET_ID }}
|
||||
secret-key: ${{ env.COS_SECRET_KEY }}
|
||||
continue-on-error: true
|
||||
@@ -0,0 +1,29 @@
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$props = Get-Content "gradle.properties"
|
||||
|
||||
function Get-Prop($key) {
|
||||
($props | Select-String "^$key=") -replace "^.*=", "" | ForEach-Object { $_.Trim() }
|
||||
}
|
||||
|
||||
function Set-MultilineOutput($name, $value) {
|
||||
"$name<<EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||||
$value | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||||
"EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||||
}
|
||||
|
||||
$loaders = Get-Prop "loaders"
|
||||
$gameVersions = Get-Prop "game_versions"
|
||||
$java = Get-Prop "java"
|
||||
$version = Get-Prop "mod_version"
|
||||
|
||||
$loadersList = $loaders -split "," | ForEach-Object { $_.Trim() }
|
||||
$gameVersionsList = $gameVersions -split "," | ForEach-Object { $_.Trim() }
|
||||
$javaList = $java -split "," | ForEach-Object { $_.Trim() }
|
||||
|
||||
Set-MultilineOutput "loaders" $loadersList
|
||||
Set-MultilineOutput "game-versions" $gameVersionsList
|
||||
Set-MultilineOutput "java" $javaList
|
||||
"short-version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||||
@@ -0,0 +1,82 @@
|
||||
param(
|
||||
[string]$ArtifactDir,
|
||||
[string]$Type # "beta" or "release"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# ---- Validate required env vars ----
|
||||
foreach ($var in @('R2_SECRET_ID', 'R2_SECRET_KEY', 'R2_BUCKET', 'R2_BASE_URL')) {
|
||||
if (-not $env:$var) { throw "Missing required env: $var" }
|
||||
}
|
||||
|
||||
$suffix = if ($Type -eq "beta") { "-beta" } else { "" }
|
||||
|
||||
# ---- Find the built jar ----
|
||||
$jar = Get-ChildItem -Path $ArtifactDir -Filter "*.jar" | Where-Object { $_.Name -notlike "*-sources.jar" } | Select-Object -First 1
|
||||
if (-not $jar) { throw "No jar found in $ArtifactDir" }
|
||||
|
||||
$jarFilename = $jar.Name
|
||||
$jarKey = "mods/$jarFilename"
|
||||
|
||||
# ---- Derive short version from gradle.properties + build number ----
|
||||
# mod_version=15.0, IS_SNAPSHOT=true, GITHUB_RUN_NUMBER=33 -> 15.0-s33
|
||||
# mod_version=15.0, IS_SNAPSHOT=false -> 15.0
|
||||
$version = ((Get-Content "gradle.properties" | Select-String "^mod_version=") -replace "^mod_version=", "").Trim()
|
||||
$isSnapshot = if ($env:IS_SNAPSHOT) { $env:IS_SNAPSHOT -ne "false" } else { $true }
|
||||
if ($isSnapshot) {
|
||||
$shortVersion = "$version-s$env:GITHUB_RUN_NUMBER"
|
||||
} else {
|
||||
$shortVersion = "$version"
|
||||
}
|
||||
|
||||
# ---- Read MC major versions from gradle.properties ----
|
||||
$mcVersions = ((Get-Content "gradle.properties" | Select-String "^minecraft_major_versions=") -replace "^.*=", "").Trim()
|
||||
$mcVersionList = $mcVersions -split "," | ForEach-Object { $_.Trim() }
|
||||
|
||||
$baseUrl = $env:R2_BASE_URL.TrimEnd('/')
|
||||
|
||||
# ---- Generate latest(-beta).json ----
|
||||
$latestJson = @{
|
||||
version = $shortVersion
|
||||
downloads = @{ Universal = "$baseUrl/$jarKey" }
|
||||
launchermeta = @{}
|
||||
} | ConvertTo-Json -Depth 10
|
||||
Set-Content -Path "$ArtifactDir/latest$suffix.json" -Value $latestJson -NoNewline
|
||||
|
||||
# ---- Generate detail(-beta).json ----
|
||||
$details = [ordered]@{}
|
||||
foreach ($mcVer in $mcVersionList) {
|
||||
$details[$mcVer] = @{ Universal = "$baseUrl/$jarKey" }
|
||||
}
|
||||
$detailJson = @{
|
||||
version = $shortVersion
|
||||
timestamp = [System.DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
|
||||
details = $details
|
||||
} | ConvertTo-Json -Depth 10
|
||||
Set-Content -Path "$ArtifactDir/detail$suffix.json" -Value $detailJson -NoNewline
|
||||
|
||||
# ---- Upload JSON files to R2 ----
|
||||
$env:AWS_ACCESS_KEY_ID = $env:R2_SECRET_ID
|
||||
$env:AWS_SECRET_ACCESS_KEY = $env:R2_SECRET_KEY
|
||||
$env:AWS_DEFAULT_REGION = "auto"
|
||||
|
||||
aws s3 cp "$ArtifactDir/latest$suffix.json" "s3://$env:R2_BUCKET/latest$suffix.json" --endpoint-url $($env:R2_BASE_URL.TrimEnd('/'))
|
||||
aws s3 cp "$ArtifactDir/detail$suffix.json" "s3://$env:R2_BUCKET/detail$suffix.json" --endpoint-url $($env:R2_BASE_URL.TrimEnd('/'))
|
||||
|
||||
# ---- Upload JSON files to COS ----
|
||||
try {
|
||||
pip install coscmd -q --disable-pip-version-check
|
||||
coscmd config -a $env:COS_SECRET_ID -s $env:COS_SECRET_KEY -b $env:COS_BUCKET -r ap-shanghai
|
||||
coscmd upload "$ArtifactDir/latest$suffix.json" "latest$suffix.json"
|
||||
coscmd upload "$ArtifactDir/detail$suffix.json" "detail$suffix.json"
|
||||
} catch {
|
||||
Write-Warning "COS JSON upload failed: $_"
|
||||
}
|
||||
|
||||
# ---- Output CDN URLs for subsequent refresh step ----
|
||||
$cdnBase = "https://csl.littleservice.cn"
|
||||
"cdn-urls<<EOF" | Out-File $env:GITHUB_OUTPUT -Append
|
||||
"${cdnBase}/latest${suffix}.json" | Out-File $env:GITHUB_OUTPUT -Append
|
||||
"${cdnBase}/detail${suffix}.json" | Out-File $env:GITHUB_OUTPUT -Append
|
||||
"EOF" | Out-File $env:GITHUB_OUTPUT -Append
|
||||
@@ -1,15 +0,0 @@
|
||||
param(
|
||||
[string] $GradleCommand = "./gradlew.bat"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$RepositoryRoot = (Resolve-Path -LiteralPath (Join-Path $ScriptRoot "../..")).Path
|
||||
Set-Location -LiteralPath $RepositoryRoot
|
||||
|
||||
& $GradleCommand clean build --stacktrace
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Gradle build failed with exit code $LASTEXITCODE."
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
$RunnerTemp = if ([string]::IsNullOrWhiteSpace($env:RUNNER_TEMP)) {
|
||||
[System.IO.Path]::GetTempPath()
|
||||
} else {
|
||||
$env:RUNNER_TEMP
|
||||
}
|
||||
|
||||
function Add-ActionPath {
|
||||
param([Parameter(Mandatory = $true)][string] $Path)
|
||||
|
||||
$env:Path = "$Path;$env:Path"
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:GITHUB_PATH)) {
|
||||
Add-Content -LiteralPath $env:GITHUB_PATH -Value $Path
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Command aws -ErrorAction SilentlyContinue)) {
|
||||
$installer = Join-Path $RunnerTemp "AWSCLIV2.msi"
|
||||
Invoke-WebRequest -Uri "https://awscli.amazonaws.com/AWSCLIV2.msi" -OutFile $installer
|
||||
$install = Start-Process msiexec.exe -Wait -PassThru -ArgumentList "/i `"$installer`" /qn"
|
||||
if ($install.ExitCode -ne 0) {
|
||||
throw "AWS CLI installer failed with exit code $($install.ExitCode)."
|
||||
}
|
||||
|
||||
$awsCliDir = Join-Path $env:ProgramFiles "Amazon/AWSCLIV2"
|
||||
$machinePath = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||
$userPath = [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
$env:Path = "$awsCliDir;$machinePath;$userPath;$env:Path"
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:GITHUB_PATH)) {
|
||||
Add-Content -LiteralPath $env:GITHUB_PATH -Value $awsCliDir
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Command coscli -ErrorAction SilentlyContinue)) {
|
||||
$coscliDir = Join-Path $RunnerTemp "coscli"
|
||||
New-Item -ItemType Directory -Force -Path $coscliDir | Out-Null
|
||||
Invoke-WebRequest -Uri "https://github.com/tencentyun/coscli/releases/download/v1.0.8/coscli-v1.0.8-windows-amd64.exe" -OutFile (Join-Path $coscliDir "coscli.exe")
|
||||
Add-ActionPath $coscliDir
|
||||
}
|
||||
|
||||
if (-not (Get-Command tccli -ErrorAction SilentlyContinue)) {
|
||||
python -m pip install --user tccli
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "tccli install failed with exit code $LASTEXITCODE."
|
||||
}
|
||||
|
||||
$pythonUserScripts = Join-Path (python -m site --user-base) "Scripts"
|
||||
Add-ActionPath $pythonUserScripts
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
param(
|
||||
[string] $SourcePath = "Bootstrap/build/libs",
|
||||
[string] $DestinationPath = "build/publish"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$RepositoryRoot = (Resolve-Path -LiteralPath (Join-Path $ScriptRoot "../..")).Path
|
||||
Set-Location -LiteralPath $RepositoryRoot
|
||||
|
||||
function Resolve-RepoPath {
|
||||
param([Parameter(Mandatory = $true)][string] $Path)
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($Path)) {
|
||||
return [System.IO.Path]::GetFullPath($Path)
|
||||
}
|
||||
|
||||
return [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($RepositoryRoot, $Path))
|
||||
}
|
||||
|
||||
$source = Resolve-RepoPath $SourcePath
|
||||
$destination = Resolve-RepoPath $DestinationPath
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $destination | Out-Null
|
||||
|
||||
$jars = Get-ChildItem -LiteralPath $source -Filter "CustomSkinLoader_Universal-*.jar" -File |
|
||||
Where-Object { $_.Name -notlike "*-sources.jar" }
|
||||
|
||||
if (-not $jars) {
|
||||
throw "No Universal jar found under $SourcePath."
|
||||
}
|
||||
|
||||
$jars | Copy-Item -Destination $destination -Force
|
||||
@@ -1,25 +0,0 @@
|
||||
param(
|
||||
[string] $Channel = $env:PUBLISH_CHANNEL,
|
||||
[string] $LatestJsonName = $env:LATEST_JSON_NAME,
|
||||
[string] $DetailJsonName = $env:DETAIL_JSON_NAME
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Channel)) {
|
||||
$Channel = "Beta"
|
||||
}
|
||||
|
||||
$publishScript = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Path) "publish-artifacts.ps1"
|
||||
$arguments = @("-Channel", $Channel)
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($LatestJsonName)) {
|
||||
$arguments += @("-LatestJsonName", $LatestJsonName)
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($DetailJsonName)) {
|
||||
$arguments += @("-DetailJsonName", $DetailJsonName)
|
||||
}
|
||||
|
||||
& $publishScript @arguments
|
||||
@@ -1,427 +0,0 @@
|
||||
param(
|
||||
[ValidateSet("Beta", "Release")]
|
||||
[string] $Channel = "Beta",
|
||||
|
||||
[string] $LatestJsonName,
|
||||
|
||||
[string] $DetailJsonName,
|
||||
|
||||
[string] $ArtifactsRoot = "build/publish",
|
||||
|
||||
[switch] $SkipObjectStorage
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$RepositoryRoot = (Resolve-Path -LiteralPath (Join-Path $ScriptRoot "..\..")).Path
|
||||
Set-Location -LiteralPath $RepositoryRoot
|
||||
|
||||
function Resolve-RepoPath {
|
||||
param([Parameter(Mandatory = $true)][string] $Path)
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($Path)) {
|
||||
return [System.IO.Path]::GetFullPath($Path)
|
||||
}
|
||||
|
||||
return [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($RepositoryRoot, $Path))
|
||||
}
|
||||
|
||||
function ConvertTo-ShortVersion {
|
||||
param([Parameter(Mandatory = $true)][string] $Version)
|
||||
|
||||
return $Version.Replace("SNAPSHOT-", "s")
|
||||
}
|
||||
|
||||
function Read-BuildProperties {
|
||||
$properties = [ordered] @{}
|
||||
foreach ($line in Get-Content -LiteralPath (Resolve-RepoPath "build.properties")) {
|
||||
$trimmedLine = $line.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($trimmedLine) -or $trimmedLine.StartsWith("#")) {
|
||||
continue
|
||||
}
|
||||
|
||||
$separatorIndex = $trimmedLine.IndexOf("=")
|
||||
if ($separatorIndex -lt 1) {
|
||||
continue
|
||||
}
|
||||
|
||||
$name = $trimmedLine.Substring(0, $separatorIndex).Trim()
|
||||
$value = $trimmedLine.Substring($separatorIndex + 1).Trim()
|
||||
$properties[$name] = $value
|
||||
}
|
||||
|
||||
return $properties
|
||||
}
|
||||
|
||||
function Get-RequiredProperty {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][System.Collections.IDictionary] $Properties,
|
||||
[Parameter(Mandatory = $true)][string] $Name
|
||||
)
|
||||
|
||||
$value = $Properties[$Name]
|
||||
if ([string]::IsNullOrWhiteSpace($value)) {
|
||||
throw "Missing $Name in build.properties"
|
||||
}
|
||||
|
||||
return $value
|
||||
}
|
||||
|
||||
function Get-PropertyList {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][System.Collections.IDictionary] $Properties,
|
||||
[Parameter(Mandatory = $true)][string] $Name
|
||||
)
|
||||
|
||||
return (Get-RequiredProperty $Properties $Name) -split "," |
|
||||
ForEach-Object { $_.Trim() } |
|
||||
Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
|
||||
}
|
||||
|
||||
function Get-PropertyListByNames {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][System.Collections.IDictionary] $Properties,
|
||||
[Parameter(Mandatory = $true)][string[]] $Names
|
||||
)
|
||||
|
||||
foreach ($name in $Names) {
|
||||
if (-not [string]::IsNullOrWhiteSpace($Properties[$name])) {
|
||||
return Get-PropertyList $Properties $name
|
||||
}
|
||||
}
|
||||
|
||||
throw "Missing one of these properties in build.properties: $($Names -join ', ')"
|
||||
}
|
||||
|
||||
function Test-VersionAtLeast {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string] $Version,
|
||||
[Parameter(Mandatory = $true)][string] $MinimumVersion
|
||||
)
|
||||
|
||||
return [version] $Version -ge [version] $MinimumVersion
|
||||
}
|
||||
|
||||
function Get-VersionFromJarName {
|
||||
param([Parameter(Mandatory = $true)][string] $FileName)
|
||||
|
||||
$prefix = "CustomSkinLoader_Universal-"
|
||||
$suffix = ".jar"
|
||||
if (-not $FileName.StartsWith($prefix) -or -not $FileName.EndsWith($suffix)) {
|
||||
throw "Unexpected Universal jar name: $FileName"
|
||||
}
|
||||
|
||||
return $FileName.Substring($prefix.Length, $FileName.Length - $prefix.Length - $suffix.Length)
|
||||
}
|
||||
|
||||
function New-Directory {
|
||||
param([Parameter(Mandatory = $true)][string] $Path)
|
||||
|
||||
[System.IO.Directory]::CreateDirectory((Resolve-RepoPath $Path)) | Out-Null
|
||||
}
|
||||
|
||||
function Copy-PublishArtifacts {
|
||||
param([Parameter(Mandatory = $true)][string] $Destination)
|
||||
|
||||
New-Directory $Destination
|
||||
|
||||
$destinationPath = Resolve-RepoPath $Destination
|
||||
Get-ChildItem -LiteralPath $destinationPath -File -ErrorAction SilentlyContinue | Remove-Item -Force
|
||||
|
||||
$jar = Get-ChildItem -LiteralPath (Resolve-RepoPath "Bootstrap/build/libs") -Filter "CustomSkinLoader_Universal-*.jar" -File -ErrorAction Stop |
|
||||
Where-Object { $_.Name -notlike "*-sources.jar" } |
|
||||
Sort-Object LastWriteTime -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
if (-not $jar) {
|
||||
throw "No Universal jar found under Bootstrap/build/libs."
|
||||
}
|
||||
|
||||
Copy-Item -LiteralPath $jar.FullName -Destination (Join-Path $destinationPath $jar.Name) -Force
|
||||
return Get-Item -LiteralPath (Join-Path $destinationPath $jar.Name)
|
||||
}
|
||||
|
||||
function ConvertTo-JsonFile {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)] $InputObject,
|
||||
[Parameter(Mandatory = $true)][string] $Path
|
||||
)
|
||||
|
||||
$json = $InputObject | ConvertTo-Json -Depth 10
|
||||
$absolutePath = Resolve-RepoPath $Path
|
||||
[System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($absolutePath)) | Out-Null
|
||||
[System.IO.File]::WriteAllText($absolutePath, $json + [System.Environment]::NewLine, [System.Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
|
||||
function New-Metadata {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string] $Version,
|
||||
[Parameter(Mandatory = $true)][string] $OutputDirectory,
|
||||
[Parameter(Mandatory = $true)][string] $LatestName,
|
||||
[Parameter(Mandatory = $true)][string] $DetailName,
|
||||
[Parameter(Mandatory = $true)][System.Collections.IDictionary] $BuildProperties
|
||||
)
|
||||
|
||||
$publicBaseUrl = if ([string]::IsNullOrWhiteSpace($env:CLOUDFLARE_CDN_ROOT)) { "https://csl.3-3.dev/" } else { $env:CLOUDFLARE_CDN_ROOT.Trim() }
|
||||
if (-not $publicBaseUrl.EndsWith("/")) {
|
||||
$publicBaseUrl += "/"
|
||||
}
|
||||
|
||||
$outputPath = Resolve-RepoPath $OutputDirectory
|
||||
$jars = Get-ChildItem -LiteralPath $outputPath -Filter "CustomSkinLoader_Universal-*.jar" -File |
|
||||
Sort-Object Name
|
||||
|
||||
if (-not $jars) {
|
||||
throw "No publish jars found in $OutputDirectory."
|
||||
}
|
||||
|
||||
$latest = [ordered] @{
|
||||
version = ConvertTo-ShortVersion $Version
|
||||
downloads = [ordered] @{}
|
||||
launchermeta = [ordered] @{}
|
||||
}
|
||||
|
||||
foreach ($jar in $jars) {
|
||||
$latest.downloads["Universal"] = "$publicBaseUrl`mods/$($jar.Name)"
|
||||
}
|
||||
|
||||
$minecraftMajorVersions = Get-PropertyList $BuildProperties "minecraft_major_versions"
|
||||
$detailMap = [ordered] @{}
|
||||
foreach ($minecraftVersion in $minecraftMajorVersions) {
|
||||
$loaderMap = [ordered] @{}
|
||||
$loaderMap["Forge"] = $latest.downloads["Universal"]
|
||||
|
||||
if (Test-VersionAtLeast $minecraftVersion "1.14") {
|
||||
$loaderMap["Fabric"] = $latest.downloads["Universal"]
|
||||
$loaderMap["Quilt"] = $latest.downloads["Universal"]
|
||||
}
|
||||
|
||||
if (Test-VersionAtLeast $minecraftVersion "1.20") {
|
||||
$loaderMap["NeoForge"] = $latest.downloads["Universal"]
|
||||
}
|
||||
|
||||
$detailMap[$minecraftVersion] = $loaderMap
|
||||
}
|
||||
|
||||
$detail = [ordered] @{
|
||||
version = $latest.version
|
||||
timestamp = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
|
||||
details = $detailMap
|
||||
}
|
||||
|
||||
ConvertTo-JsonFile $latest (Join-Path $outputPath $LatestName)
|
||||
ConvertTo-JsonFile $detail (Join-Path $outputPath $DetailName)
|
||||
}
|
||||
|
||||
function Write-GitHubOutputValue {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string] $Name,
|
||||
[Parameter(Mandatory = $true)][string] $Value
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($env:GITHUB_OUTPUT)) {
|
||||
return
|
||||
}
|
||||
|
||||
$delimiter = "EOF_$([guid]::NewGuid().ToString('N'))"
|
||||
$content = "$Name<<$delimiter" + [System.Environment]::NewLine +
|
||||
$Value + [System.Environment]::NewLine +
|
||||
$delimiter + [System.Environment]::NewLine
|
||||
[System.IO.File]::AppendAllText($env:GITHUB_OUTPUT, $content, [System.Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
|
||||
function Write-PublishOutputs {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string] $Version,
|
||||
[Parameter(Mandatory = $true)][System.Collections.IDictionary] $BuildProperties
|
||||
)
|
||||
|
||||
$shortVersion = ConvertTo-ShortVersion $Version
|
||||
$edition = Get-RequiredProperty $BuildProperties "edition"
|
||||
Write-GitHubOutputValue "edition" $edition
|
||||
Write-GitHubOutputValue "version" $shortVersion
|
||||
Write-GitHubOutputValue "mc_publish_name" "CustomSkinLoader_$edition`_$shortVersion"
|
||||
Write-GitHubOutputValue "mc_publish_version" "$shortVersion-$edition"
|
||||
Write-GitHubOutputValue "loaders" ((Get-PropertyListByNames $BuildProperties @("loaders", "mod_loaders")) -join [System.Environment]::NewLine)
|
||||
Write-GitHubOutputValue "game_versions" ((Get-PropertyListByNames $BuildProperties @("game-versions", "minecraft_major_versions")) -join [System.Environment]::NewLine)
|
||||
Write-GitHubOutputValue "java_versions" ((Get-PropertyListByNames $BuildProperties @("java", "java_full_versions")) -join [System.Environment]::NewLine)
|
||||
}
|
||||
|
||||
function Invoke-AwsCliUpload {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string] $EndpointUrl,
|
||||
[Parameter(Mandatory = $true)][string] $Bucket,
|
||||
[Parameter(Mandatory = $true)][string] $AccessKeyId,
|
||||
[Parameter(Mandatory = $true)][string] $SecretAccessKey,
|
||||
[Parameter(Mandatory = $true)][string] $Directory
|
||||
)
|
||||
|
||||
$aws = Get-Command aws -ErrorAction SilentlyContinue
|
||||
if (-not $aws) {
|
||||
Write-Warning "AWS CLI was not found. Skip S3-compatible upload."
|
||||
return
|
||||
}
|
||||
|
||||
$oldAccessKey = $env:AWS_ACCESS_KEY_ID
|
||||
$oldSecretKey = $env:AWS_SECRET_ACCESS_KEY
|
||||
$oldRegion = $env:AWS_DEFAULT_REGION
|
||||
|
||||
try {
|
||||
$env:AWS_ACCESS_KEY_ID = $AccessKeyId
|
||||
$env:AWS_SECRET_ACCESS_KEY = $SecretAccessKey
|
||||
$env:AWS_DEFAULT_REGION = "auto"
|
||||
|
||||
foreach ($file in Get-ChildItem -LiteralPath $Directory -File) {
|
||||
$key = if ($file.Extension -eq ".jar") { "mods/$($file.Name)" } else { $file.Name }
|
||||
& aws --endpoint-url $EndpointUrl s3 cp $file.FullName "s3://$Bucket/$key" --only-show-errors
|
||||
}
|
||||
} finally {
|
||||
$env:AWS_ACCESS_KEY_ID = $oldAccessKey
|
||||
$env:AWS_SECRET_ACCESS_KEY = $oldSecretKey
|
||||
$env:AWS_DEFAULT_REGION = $oldRegion
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-CosCliUpload {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string] $Bucket,
|
||||
[Parameter(Mandatory = $true)][string] $SecretId,
|
||||
[Parameter(Mandatory = $true)][string] $SecretKey,
|
||||
[Parameter(Mandatory = $true)][string] $Directory
|
||||
)
|
||||
|
||||
$coscli = Get-Command coscli -ErrorAction SilentlyContinue
|
||||
if (-not $coscli) {
|
||||
Write-Warning "coscli was not found. Skip Tencent COS upload."
|
||||
return
|
||||
}
|
||||
|
||||
$configPath = Join-Path $env:RUNNER_TEMP "coscli-customskinloader.yaml"
|
||||
$cosRegion = if ([string]::IsNullOrWhiteSpace($env:COS_REGION)) { "ap-shanghai" } else { $env:COS_REGION.Trim() }
|
||||
@"
|
||||
cos:
|
||||
base:
|
||||
secretid: $SecretId
|
||||
secretkey: $SecretKey
|
||||
sessiontoken: ""
|
||||
protocol: https
|
||||
buckets:
|
||||
- name: $Bucket
|
||||
alias: $Bucket
|
||||
region: $cosRegion
|
||||
endpoint: cos.$cosRegion.myqcloud.com
|
||||
ofs: false
|
||||
"@ | Set-Content -LiteralPath $configPath -Encoding UTF8
|
||||
|
||||
foreach ($file in Get-ChildItem -LiteralPath $Directory -File) {
|
||||
$key = if ($file.Extension -eq ".jar") { "mods/$($file.Name)" } else { $file.Name }
|
||||
& coscli -c $configPath cp $file.FullName "cos://$Bucket/$key"
|
||||
}
|
||||
}
|
||||
|
||||
function Get-PublishObjectKeys {
|
||||
param([Parameter(Mandatory = $true)][string] $Directory)
|
||||
|
||||
return Get-ChildItem -LiteralPath $Directory -File |
|
||||
ForEach-Object {
|
||||
if ($_.Extension -eq ".jar") {
|
||||
"mods/$($_.Name)"
|
||||
} else {
|
||||
$_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-TencentCdnRefresh {
|
||||
param([Parameter(Mandatory = $true)][string[]] $Keys)
|
||||
|
||||
$cdnRoot = if ([string]::IsNullOrWhiteSpace($env:TENCENT_CDN_ROOT)) { "https://csl.littleservice.cn/" } else { $env:TENCENT_CDN_ROOT.Trim() }
|
||||
if (-not $cdnRoot.EndsWith("/")) {
|
||||
$cdnRoot += "/"
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($env:COS_SECRET_ID) -or [string]::IsNullOrWhiteSpace($env:COS_SECRET_KEY)) {
|
||||
Write-Host "Tencent CDN credentials are incomplete. Skip CDN refresh."
|
||||
return
|
||||
}
|
||||
|
||||
$tccli = Get-Command tccli -ErrorAction SilentlyContinue
|
||||
if (-not $tccli) {
|
||||
Write-Warning "tccli was not found. Skip Tencent CDN refresh."
|
||||
return
|
||||
}
|
||||
|
||||
$oldSecretId = $env:TENCENTCLOUD_SECRET_ID
|
||||
$oldSecretKey = $env:TENCENTCLOUD_SECRET_KEY
|
||||
try {
|
||||
$env:TENCENTCLOUD_SECRET_ID = $env:COS_SECRET_ID
|
||||
$env:TENCENTCLOUD_SECRET_KEY = $env:COS_SECRET_KEY
|
||||
$urlsJson = ConvertTo-Json -Compress -InputObject @($Keys | ForEach-Object { "$cdnRoot$_" })
|
||||
|
||||
& tccli cdn PurgeUrlsCache --Urls $urlsJson
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Tencent CDN purge failed."
|
||||
}
|
||||
|
||||
& tccli cdn PushUrlsCache --Urls $urlsJson
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Tencent CDN push failed."
|
||||
}
|
||||
} finally {
|
||||
$env:TENCENTCLOUD_SECRET_ID = $oldSecretId
|
||||
$env:TENCENTCLOUD_SECRET_KEY = $oldSecretKey
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($LatestJsonName)) {
|
||||
$LatestJsonName = switch ($Channel) {
|
||||
"Beta" { "latest-beta.json" }
|
||||
"Canary" { "latest-canary.json" }
|
||||
"Release" { "latest.json" }
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($DetailJsonName)) {
|
||||
$DetailJsonName = switch ($Channel) {
|
||||
"Beta" { "detail-beta.json" }
|
||||
"Canary" { "detail-canary.json" }
|
||||
"Release" { "detail.json" }
|
||||
}
|
||||
}
|
||||
|
||||
New-Directory $ArtifactsRoot
|
||||
$buildProperties = Read-BuildProperties
|
||||
$artifacts = Copy-PublishArtifacts $ArtifactsRoot
|
||||
$ArtifactsRoot = Resolve-RepoPath $ArtifactsRoot
|
||||
$fullVersion = Get-VersionFromJarName $artifacts[0].Name
|
||||
New-Metadata -Version $fullVersion -OutputDirectory $ArtifactsRoot -LatestName $LatestJsonName -DetailName $DetailJsonName -BuildProperties $buildProperties
|
||||
Write-PublishOutputs -Version $fullVersion -BuildProperties $buildProperties
|
||||
|
||||
Write-Host "Prepared publish artifacts:"
|
||||
Get-ChildItem -LiteralPath $ArtifactsRoot -File | ForEach-Object { Write-Host " - $($_.Name)" }
|
||||
|
||||
if ($SkipObjectStorage) {
|
||||
Write-Host "SkipObjectStorage was set. Metadata generated locally only."
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:R2_BASE_URL) -and
|
||||
-not [string]::IsNullOrWhiteSpace($env:R2_BUCKET) -and
|
||||
-not [string]::IsNullOrWhiteSpace($env:R2_SECRET_ID) -and
|
||||
-not [string]::IsNullOrWhiteSpace($env:R2_SECRET_KEY)) {
|
||||
Invoke-AwsCliUpload -EndpointUrl $env:R2_BASE_URL -Bucket $env:R2_BUCKET -AccessKeyId $env:R2_SECRET_ID -SecretAccessKey $env:R2_SECRET_KEY -Directory $ArtifactsRoot
|
||||
} else {
|
||||
Write-Host "R2 secrets are incomplete. Skip R2 upload."
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:COS_BUCKET) -and
|
||||
-not [string]::IsNullOrWhiteSpace($env:COS_SECRET_ID) -and
|
||||
-not [string]::IsNullOrWhiteSpace($env:COS_SECRET_KEY)) {
|
||||
Invoke-CosCliUpload -Bucket $env:COS_BUCKET -SecretId $env:COS_SECRET_ID -SecretKey $env:COS_SECRET_KEY -Directory $ArtifactsRoot
|
||||
} else {
|
||||
Write-Host "COS secrets are incomplete. Skip COS upload."
|
||||
}
|
||||
|
||||
Invoke-TencentCdnRefresh -Keys @(Get-PublishObjectKeys $ArtifactsRoot)
|
||||
@@ -1,37 +0,0 @@
|
||||
param(
|
||||
[string] $BranchName = $env:GITHUB_REF_NAME,
|
||||
[string] $BuildType = $env:BUILD_TYPE,
|
||||
[string] $OutputPath = "build/publish/release-notes.md",
|
||||
[string] $TimeZoneId = "China Standard Time"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$RepositoryRoot = (Resolve-Path -LiteralPath (Join-Path $ScriptRoot "../..")).Path
|
||||
Set-Location -LiteralPath $RepositoryRoot
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($BranchName)) {
|
||||
throw "BranchName is required."
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($BuildType)) {
|
||||
throw "BuildType is required."
|
||||
}
|
||||
|
||||
$absoluteOutputPath = if ([System.IO.Path]::IsPathRooted($OutputPath)) {
|
||||
[System.IO.Path]::GetFullPath($OutputPath)
|
||||
} else {
|
||||
[System.IO.Path]::GetFullPath([System.IO.Path]::Combine($RepositoryRoot, $OutputPath))
|
||||
}
|
||||
|
||||
[System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($absoluteOutputPath)) | Out-Null
|
||||
|
||||
$buildTime = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]::UtcNow, $TimeZoneId).ToString("yyyy.MM.dd HH:mm")
|
||||
@"
|
||||
Build Time / 构建时间: $buildTime
|
||||
|
||||
Synchronize $BranchName branch code updates, keeping only the latest $BuildType build.
|
||||
自动同步 $BranchName 分支构建产物,仅保留最新 $BuildType 版本。
|
||||
"@ | Set-Content -LiteralPath $absoluteOutputPath -Encoding UTF8
|
||||
+64
-16
@@ -1,21 +1,69 @@
|
||||
name: Beta
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 15-develop
|
||||
workflow_dispatch:
|
||||
branches: [15-develop]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-beta:
|
||||
name: Build Beta
|
||||
uses: ./.github/workflows/common.yml
|
||||
with:
|
||||
type: Beta
|
||||
publish: true
|
||||
prerelease-tag: Beta-Build
|
||||
prerelease-name: CustomSkinLoader Beta Build
|
||||
latest-json: latest-beta.json
|
||||
detail-json: detail-beta.json
|
||||
is-snapshot: true
|
||||
secrets: inherit
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: ./.github/actions/build
|
||||
with:
|
||||
artifact-name: CustomSkinLoader-Beta-${{ github.run_number }}
|
||||
|
||||
publish:
|
||||
name: Publish
|
||||
needs: build
|
||||
runs-on: windows-latest
|
||||
environment: Build
|
||||
env:
|
||||
IS_SNAPSHOT: 'true'
|
||||
R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }}
|
||||
R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_BASE_URL: ${{ secrets.R2_BASE_URL }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
COS_BUCKET: ${{ secrets.COS_BUCKET }}
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: CustomSkinLoader-Beta-${{ github.run_number }}
|
||||
path: artifact
|
||||
|
||||
- uses: ./.github/actions/publish
|
||||
with:
|
||||
artifact-dir: artifact
|
||||
type: beta
|
||||
|
||||
- name: Generate CI-Build body
|
||||
shell: pwsh
|
||||
run: |
|
||||
@"
|
||||
Build Time / 构建时间 : $((Get-Date).ToUniversalTime().AddHours(8).ToString("yyyy.MM.dd HH:mm"))
|
||||
Auto build from branch $env:GITHUB_REF_NAME
|
||||
|
||||
[How to use?](https://github.com/xfl03/MCCustomSkinLoader/wiki/How-to-Use)
|
||||
"@ | Set-Content -Path ci-build-body.md -NoNewline
|
||||
|
||||
- name: Move CI-Build tag to current commit
|
||||
uses: richardsimko/update-tag@v1
|
||||
with:
|
||||
tag_name: CI-Build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: GitHub PreRelease
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: CI-Build
|
||||
name: CustomSkinLoader CI-Build
|
||||
prerelease: true
|
||||
body_path: ci-build-body.md
|
||||
files: artifact/*.jar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,173 +0,0 @@
|
||||
name: Common
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
type:
|
||||
required: true
|
||||
type: string
|
||||
publish:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
release:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
prerelease-tag:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
prerelease-name:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
latest-json:
|
||||
required: false
|
||||
type: string
|
||||
default: latest-beta.json
|
||||
detail-json:
|
||||
required: false
|
||||
type: string
|
||||
default: detail-beta.json
|
||||
is-snapshot:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: powershell
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 25
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: liberica
|
||||
java-version: "25"
|
||||
cache: gradle
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
IS_SNAPSHOT: ${{ inputs['is-snapshot'] }}
|
||||
run: ./.github/scripts/build.ps1
|
||||
|
||||
- name: Install publish CLIs
|
||||
if: ${{ inputs.publish || inputs.release }}
|
||||
run: ./.github/scripts/install-publish-clis.ps1
|
||||
|
||||
- name: Prepare publish artifacts
|
||||
id: publish-artifacts
|
||||
if: ${{ inputs.publish || inputs.release }}
|
||||
env:
|
||||
IS_SNAPSHOT: ${{ inputs['is-snapshot'] }}
|
||||
PUBLISH_CHANNEL: ${{ inputs.type }}
|
||||
LATEST_JSON_NAME: ${{ inputs['latest-json'] }}
|
||||
DETAIL_JSON_NAME: ${{ inputs['detail-json'] }}
|
||||
R2_BASE_URL: ${{ secrets.R2_BASE_URL }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }}
|
||||
R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }}
|
||||
COS_BUCKET: ${{ secrets.COS_BUCKET }}
|
||||
COS_REGION: ${{ secrets.COS_REGION }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
TENCENT_CDN_ROOT: ${{ secrets.TENCENT_CDN_ROOT }}
|
||||
CLOUDFLARE_CDN_ROOT: ${{ secrets.CLOUDFLARE_CDN_ROOT }}
|
||||
run: ./.github/scripts/prepare-publish-artifacts.ps1
|
||||
|
||||
- name: Prepare build artifacts
|
||||
if: ${{ !(inputs.publish || inputs.release) }}
|
||||
run: ./.github/scripts/prepare-build-artifacts.ps1
|
||||
|
||||
- name: Upload workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CustomSkinLoader-${{ inputs.type }}-${{ github.run_number }}
|
||||
path: build/publish/*
|
||||
|
||||
- name: Write pre-release body
|
||||
if: ${{ inputs.publish && inputs['prerelease-tag'] != '' }}
|
||||
env:
|
||||
BUILD_TYPE: ${{ inputs.type }}
|
||||
run: ./.github/scripts/write-prerelease-body.ps1
|
||||
|
||||
- name: Delete previous pre-release assets
|
||||
if: ${{ inputs.publish && inputs['prerelease-tag'] != '' }}
|
||||
uses: 8Mi-Tech/delete-release-assets-action@main
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ inputs['prerelease-tag'] }}
|
||||
deleteOnlyFromDrafts: false
|
||||
|
||||
- name: Move pre-release tag
|
||||
if: ${{ inputs.publish && inputs['prerelease-tag'] != '' }}
|
||||
uses: richardsimko/update-tag@v1
|
||||
with:
|
||||
tag_name: ${{ inputs['prerelease-tag'] }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish GitHub pre-release
|
||||
if: ${{ inputs.publish && inputs['prerelease-tag'] != '' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: ${{ inputs['prerelease-name'] }}
|
||||
tag_name: ${{ inputs['prerelease-tag'] }}
|
||||
prerelease: true
|
||||
make_latest: false
|
||||
body_path: build/publish/release-notes.md
|
||||
overwrite_files: true
|
||||
files: |
|
||||
build/publish/*.jar
|
||||
build/publish/*.json
|
||||
|
||||
- name: Publish GitHub release assets
|
||||
if: ${{ inputs.release }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
overwrite_files: true
|
||||
files: |
|
||||
build/publish/*.jar
|
||||
build/publish/*.json
|
||||
|
||||
- name: Publish to CurseForge and Modrinth
|
||||
if: ${{ inputs.release }}
|
||||
uses: Kir-Antipov/[email protected]
|
||||
with:
|
||||
modrinth-id: idMHQ4n2
|
||||
modrinth-featured: true
|
||||
modrinth-unfeature-mode: subset
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
|
||||
curseforge-id: 286924
|
||||
curseforge-token: ${{ secrets.CURSEFORGE_API_KEY }}
|
||||
|
||||
name: ${{ steps.publish-artifacts.outputs.mc_publish_name }}
|
||||
version: ${{ steps.publish-artifacts.outputs.mc_publish_version }}
|
||||
version-type: release
|
||||
loaders: |
|
||||
${{ steps.publish-artifacts.outputs.loaders }}
|
||||
game-versions: |
|
||||
${{ steps.publish-artifacts.outputs.game_versions }}
|
||||
game-version-filter: releases
|
||||
java: |
|
||||
${{ steps.publish-artifacts.outputs.java_versions }}
|
||||
|
||||
retry-attempts: 2
|
||||
retry-delay: 10000
|
||||
fail-mode: fail
|
||||
|
||||
files: |
|
||||
build/publish/*.jar
|
||||
@@ -1,18 +1,14 @@
|
||||
name: Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
types: [opened, synchronize, reopened]
|
||||
branches: [15-develop]
|
||||
|
||||
jobs:
|
||||
build-pull-request:
|
||||
name: Build Pull Request
|
||||
uses: ./.github/workflows/common.yml
|
||||
with:
|
||||
type: PullRequest
|
||||
publish: false
|
||||
release: false
|
||||
is-snapshot: true
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: ./.github/actions/build
|
||||
with:
|
||||
artifact-name: CustomSkinLoader-PR-${{ github.run_number }}
|
||||
@@ -1,17 +1,78 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-release:
|
||||
name: Build Release
|
||||
uses: ./.github/workflows/common.yml
|
||||
with:
|
||||
type: Release
|
||||
release: true
|
||||
latest-json: latest.json
|
||||
detail-json: detail.json
|
||||
is-snapshot: false
|
||||
secrets: inherit
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: ./.github/actions/build
|
||||
with:
|
||||
is-snapshot: 'false'
|
||||
artifact-name: CustomSkinLoader-Release-${{ github.run_number }}
|
||||
|
||||
publish:
|
||||
name: Publish
|
||||
needs: build
|
||||
runs-on: windows-latest
|
||||
environment: Build
|
||||
env:
|
||||
IS_SNAPSHOT: 'false'
|
||||
R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }}
|
||||
R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }}
|
||||
R2_BUCKET: ${{ secrets.R2_BUCKET }}
|
||||
R2_BASE_URL: ${{ secrets.R2_BASE_URL }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
COS_BUCKET: ${{ secrets.COS_BUCKET }}
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: CustomSkinLoader-Release-${{ github.run_number }}
|
||||
path: artifact
|
||||
|
||||
- uses: ./.github/actions/publish
|
||||
with:
|
||||
artifact-dir: artifact
|
||||
type: release
|
||||
|
||||
- name: Get publish info from gradle.properties
|
||||
id: info
|
||||
shell: pwsh
|
||||
run: .github/scripts/Get-PublishInfo.ps1
|
||||
|
||||
- uses: Kir-Antipov/[email protected]
|
||||
with:
|
||||
modrinth-id: idMHQ4n2
|
||||
modrinth-featured: true
|
||||
modrinth-unfeature-mode: subset
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
curseforge-id: 286924
|
||||
curseforge-token: ${{ secrets.CURSEFORGE_API_KEY }}
|
||||
name: CustomSkinLoader_Universal_${{ steps.info.outputs.short-version }}
|
||||
version: ${{ steps.info.outputs.short-version }}-Universal
|
||||
version-type: release
|
||||
loaders: |
|
||||
${{ steps.info.outputs.loaders }}
|
||||
game-versions: |
|
||||
${{ steps.info.outputs.game-versions }}
|
||||
game-version-filter: releases
|
||||
java: |
|
||||
${{ steps.info.outputs.java }}
|
||||
retry-attempts: 2
|
||||
retry-delay: 10000
|
||||
fail-mode: fail
|
||||
files: |
|
||||
artifact/*.jar
|
||||
|
||||
- name: GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: artifact/*.jar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
manifestLibraries {
|
||||
add 'https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.fabricmc.fabric-loader/0.19.2.json'
|
||||
add "https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.fabricmc.fabric-loader/${fabric_v1_version}.json"
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
manifestLibraries {
|
||||
add 'https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.minecraftforge/14.23.5.2864.json'
|
||||
add "https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.minecraftforge/${forge_v1_version}.json"
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
manifestLibraries {
|
||||
add 'https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.minecraftforge/36.2.42.json'
|
||||
add "https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.minecraftforge/${forge_v2_version}.json"
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
manifestLibraries {
|
||||
add 'https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.neoforged/20.5.21-beta.json'
|
||||
add "https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.neoforged/${neoforge_v1_version}.json"
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
manifestLibraries {
|
||||
add 'https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.neoforged/26.1.2.59-beta.json'
|
||||
add "https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.neoforged/${neoforge_v2_version}.json"
|
||||
}
|
||||
+1
-1
@@ -90,7 +90,7 @@ Keep pull requests focused. If a cleanup is unrelated to the bug or feature, sen
|
||||
|
||||
Pull requests run the shared GitHub Actions build on `windows-latest` with PowerShell and Java 25. This is a CI choice; local builds should remain portable across Windows, Linux, and macOS.
|
||||
|
||||
Publishing jobs generate the Universal jar plus metadata files from `build.properties`. Beta builds publish moving beta metadata, release builds publish release metadata and upload to distribution platforms. Object-storage upload is optional and is skipped when the required secrets are not configured.
|
||||
Publishing jobs generate the Universal jar plus metadata files from `gradle.properties`. Beta builds publish moving beta metadata, release builds publish release metadata and upload to distribution platforms. Object-storage upload is optional and is skipped when the required secrets are not configured.
|
||||
|
||||
To generate publish metadata locally without uploading, first build the project, then run:
|
||||
|
||||
|
||||
+6
-15
@@ -1,19 +1,10 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
import org.gradle.api.attributes.java.TargetJvmVersion
|
||||
|
||||
def buildPropertiesFile = rootProject.file('build.properties')
|
||||
|
||||
if (!buildPropertiesFile) {
|
||||
throw new GradleException('Missing build.properties')
|
||||
}
|
||||
|
||||
def buildProperties = new Properties()
|
||||
buildPropertiesFile.withInputStream { buildProperties.load(it) }
|
||||
|
||||
def requireBuildProperty = { String propertyName ->
|
||||
def propertyValue = buildProperties.getProperty(propertyName)?.trim()
|
||||
def propertyValue = rootProject.findProperty(propertyName)?.toString()?.trim()
|
||||
if (!propertyValue) {
|
||||
throw new GradleException("Missing ${propertyName} in ${buildPropertiesFile}")
|
||||
throw new GradleException("Missing ${propertyName} in gradle.properties")
|
||||
}
|
||||
propertyValue
|
||||
}
|
||||
@@ -26,9 +17,9 @@ def isTruthy = { String value ->
|
||||
value.trim().toLowerCase(Locale.ROOT) == 'true'
|
||||
}
|
||||
|
||||
def releaseName = requireBuildProperty('name')
|
||||
def releaseGroup = requireBuildProperty('group')
|
||||
def releaseVersion = requireBuildProperty('version')
|
||||
def releaseName = requireBuildProperty('mod_name')
|
||||
def releaseGroup = requireBuildProperty('mod_group')
|
||||
def releaseVersion = requireBuildProperty('mod_version')
|
||||
def releaseBuildNumber = System.getenv('GITHUB_RUN_NUMBER')?.trim() ?: '0'
|
||||
def releaseIsSnapshot = isTruthy(System.getenv('IS_SNAPSHOT'))
|
||||
def releaseFullVersion = (releaseIsSnapshot ? "${releaseVersion}-SNAPSHOT-${releaseBuildNumber}" : releaseVersion).toString()
|
||||
@@ -71,7 +62,7 @@ subprojects {
|
||||
|
||||
manifestLibraries {
|
||||
// Share Bootstrap's dependency set with all packaged child modules.
|
||||
add 'https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.minecraft/26.1.2.json'
|
||||
add "https://raw.githubusercontent.com/PrismLauncher/meta-launcher/refs/heads/master/net.minecraft/${minecraft_version}.json"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
name=CustomSkinLoader
|
||||
group=customskinloader
|
||||
version=15.0
|
||||
mod_name=CustomSkinLoader
|
||||
mod_group=customskinloader
|
||||
mod_version=15.0
|
||||
edition=Universal
|
||||
minecraft_major_versions=1.8,1.9,1.10,1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19,1.20,1.21,26.1
|
||||
|
||||
minecraft_version=26.1.2
|
||||
fabric_v1_version=0.19.2
|
||||
forge_v1_version=14.23.5.2864
|
||||
forge_v2_version=36.2.42
|
||||
neoforge_v1_version=20.6.13-beta
|
||||
neoforge_v2_version=26.1.2.59-beta
|
||||
|
||||
loaders=fabric,forge,neoforge,quilt
|
||||
game-versions=1.8,1.8.8,1.8.9,1.9,1.9.4,1.10,1.10.2,1.11,1.11.2,1.12,1.12.1,1.12.2,1.13.2,1.14,1.14.1,1.14.2,1.14.3,1.14.4,1.15,1.15.1,1.15.2,1.16,1.16.1,1.16.2,1.16.3,1.16.4,1.16.5,1.17,1.17.1,1.18,1.18.1,1.18.2,1.19,1.19.1,1.19.2,1.19.3,1.19.4,1.20,1.20.1,1.20.2,1.20.3,1.20.4,1.20.5,1.20.6,1.21,1.21.1,1.21.2,1.21.3,1.21.4,1.21.5,1.21.6,1.21.7,1.21.8,1.21.9,1.21.10,1.21.11,26.1,26.1.1,26.1.2
|
||||
game_versions=1.8,1.8.8,1.8.9,1.9,1.9.4,1.10,1.10.2,1.11,1.11.2,1.12,1.12.1,1.12.2,1.13.2,1.14,1.14.1,1.14.2,1.14.3,1.14.4,1.15,1.15.1,1.15.2,1.16,1.16.1,1.16.2,1.16.3,1.16.4,1.16.5,1.17,1.17.1,1.18,1.18.1,1.18.2,1.19,1.19.1,1.19.2,1.19.3,1.19.4,1.20,1.20.1,1.20.2,1.20.3,1.20.4,1.20.5,1.20.6,1.21,1.21.1,1.21.2,1.21.3,1.21.4,1.21.5,1.21.6,1.21.7,1.21.8,1.21.9,1.21.10,1.21.11,26.1,26.1.1,26.1.2
|
||||
java=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
rootProject.name = 'CustomSkinLoader-Universal'
|
||||
rootProject.name = 'MCCustomSkinLoader'
|
||||
|
||||
include(
|
||||
'Bootstrap',
|
||||
|
||||
Reference in new issue
Block a user