Update buildscripts (#335)

Merged changes from https://github.com/Nomifactory/Nomifactory/tree/dev/buildtools made after February 2022 (when I helped @tracer4b get the build scripts at the time set up).

CurseForge subsequently did its API changes so the old scripts don't work anymore.

You will need to create a Secret called CFCORE_API_TOKEN which contains the CurseForge API authentication token you wish to use (for https://api.curseforge.com). When running build scripts locally, you need to have an environment variable set with the same name and value.

This token allows the script to download mod jars required for building the server zip. Without this token, at the very least mods that disallow third-party downloads would return blank download links and that build target would fail. It might be needed to use the API at all, but @NotMyWing is our CICD author and resident expert, so I would defer to him on details.

/* Commits */

* Switch API calls to CFCore (#914)

Necessary to continue using the CurseForge API.

* Propagate the CFCore token to GHA

* Move download URL forging to fetchFileInfo

* Add CurseForge Beta deployment workflow (#944)

---------

Co-authored-by: Neeve <winwyv@gmail.com>
This commit is contained in:
Exaxxion 2023-04-17 01:21:45 -07:00 committed by GitHub
parent 36dfebfcf0
commit d3c771d94f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 2113 additions and 1540 deletions

83
.github/workflows/deploycfrc.yml vendored Normal file
View File

@ -0,0 +1,83 @@
name: Deploy to CurseForge (RC)
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to checkout'
required: true
default: 'dev'
version:
description: 'RC version to deploy (e. g. "v1.3")'
required: true
flavorTitle:
description: 'Flavor title (e. g. "Community Update")'
required: false
jobs:
deploy:
name: Deploy to CurseForge (RC) (${{ github.event.inputs.version }})
runs-on: ubuntu-latest
env:
GITHUB_BRANCH: ${{ github.event.inputs.branch }}
RC_VERSION: ${{ github.event.inputs.version }}
BUILD_FLAVOR_TITLE: ${{ github.event.inputs.flavorTitle }}
steps:
- name: "Checkout code"
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.inputs.tag }}
- name: "Restore cached files"
uses: actions/cache@v2
id: cache
with:
path: |
~/.npm
./.cache
./buildtools/node_modules
key: ${{ runner.os }}-bunny-${{ hashFiles('**/.cache', '**/package-lock.json', '**/manifest.json') }}
restore-keys: ${{ runner.os }}-bunny-
- name: "Setup NodeJS v16"
uses: actions/setup-node@v2
with:
node-version: "16"
check-latest: true
- name: "Download NPM packages"
working-directory: ./buildtools
run: npm ci
- name: "Check environmental variables"
working-directory: ./buildtools
run: npx gulp check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CURSEFORGE_PROJECT_ID: ${{ secrets.CURSEFORGE_PROJECT_ID }}
CURSEFORGE_API_TOKEN: ${{ secrets.CURSEFORGE_API_TOKEN }}
CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }}
- name: "Build everything"
working-directory: ./buildtools
run: npx gulp buildAll
env:
CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }}
- name: "Prune cache"
working-directory: ./buildtools
run: npx gulp pruneCache
env:
CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }}
- name: "Zip everything"
working-directory: ./buildtools
run: npx gulp zipAll
- name: "Deploy to CurseForge"
env:
CURSEFORGE_PROJECT_ID: ${{ secrets.CURSEFORGE_PROJECT_ID }}
CURSEFORGE_API_TOKEN: ${{ secrets.CURSEFORGE_API_TOKEN }}
working-directory: ./buildtools
run: npx gulp deployCurseForgeBeta

View File

@ -1,106 +1,104 @@
name: Nightly Builds name: Nightly Builds
on: on:
push: push:
branches: branches:
- dev - dev
tags-ignore: tags-ignore:
- '**' - '**'
jobs: jobs:
nightly: nightly:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Cancel previous runs - name: Cancel previous runs
uses: styfle/cancel-workflow-action@0.8.0 uses: styfle/cancel-workflow-action@0.8.0
with: with:
access_token: ${{ secrets.GITHUB_TOKEN }} access_token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: git fetch --prune --unshallow --tags --force - run: git fetch --prune --unshallow --tags --force
- name: Restore cached files - name: Restore cached files
uses: actions/cache@v2 uses: actions/cache@v2
id: cache id: cache
with: with:
path: | path: |
~/.npm ~/.npm
./.cache ./.cache
./buildtools/node_modules ./buildtools/node_modules
key: ${{ runner.os }}-bunny-${{ hashFiles('**/.cache', '**/package-lock.json', '**/manifest.json') }} key: ${{ runner.os }}-bunny-${{ hashFiles('**/.cache', '**/package-lock.json', '**/manifest.json') }}
restore-keys: ${{ runner.os }}-bunny- restore-keys: ${{ runner.os }}-bunny-
- name: "Setup NodeJS v16" - name: "Setup NodeJS v16"
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: "16" node-version: "16"
check-latest: true check-latest: true
- name: "Download NPM packages" - name: "Download NPM packages"
working-directory: ./buildtools working-directory: ./buildtools
run: npm ci run: npm ci
- name: "Check environmental variables" - name: "Check environmental variables"
working-directory: ./buildtools working-directory: ./buildtools
run: npx gulp check run: npx gulp check
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CURSEFORGE_PROJECT_ID: ${{ secrets.CURSEFORGE_PROJECT_ID }} CURSEFORGE_PROJECT_ID: ${{ secrets.CURSEFORGE_PROJECT_ID }}
CURSEFORGE_API_TOKEN: ${{ secrets.CURSEFORGE_API_TOKEN }} CURSEFORGE_API_TOKEN: ${{ secrets.CURSEFORGE_API_TOKEN }}
CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }} CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }}
- name: "Build everything" - name: "Build everything"
working-directory: ./buildtools working-directory: ./buildtools
run: npx gulp buildAll run: npx gulp buildAll
env: env:
CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }} CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }}
- name: "Prune cache" - name: "Prune cache"
working-directory: ./buildtools working-directory: ./buildtools
run: npx gulp pruneCache run: npx gulp pruneCache
env:
CFCORE_API_TOKEN: ${{ secrets.CFCORE_API_TOKEN }} ##
## Upload artifacts.
## ##
## Upload artifacts. - name: "Make artifact names"
## id: artifactNames
- name: "Make artifact names" working-directory: ./buildtools
id: artifactNames run: npx gulp makeArtifactNames
working-directory: ./buildtools
run: npx gulp makeArtifactNames - name: "Upload client artifact"
uses: actions/upload-artifact@v2
- name: "Upload client artifact" with:
uses: actions/upload-artifact@v2 name: ${{ steps.artifactNames.outputs.client }}
with: path: |
name: ${{ steps.artifactNames.outputs.client }} build/client/**/*
path: |
build/client/**/* - name: "Upload server artifact"
uses: actions/upload-artifact@v2
- name: "Upload server artifact" with:
uses: actions/upload-artifact@v2 name: ${{ steps.artifactNames.outputs.server }}
with: path: |
name: ${{ steps.artifactNames.outputs.server }} build/server/**/*
path: |
build/server/**/* - name: "Upload lang artifact"
uses: actions/upload-artifact@v2
- name: "Upload lang artifact" with:
uses: actions/upload-artifact@v2 name: ${{ steps.artifactNames.outputs.lang }}
with: path: |
name: ${{ steps.artifactNames.outputs.lang }} build/lang/**/*
path: |
build/lang/**/* - name: "Upload changelog artifact"
uses: actions/upload-artifact@v2
- name: "Upload changelog artifact" with:
uses: actions/upload-artifact@v2 name: changelog
with: path: |
name: changelog build/shared/CHANGELOG.md
path: |
build/shared/CHANGELOG.md - name: "Fire Discord webhook"
working-directory: ./buildtools
- name: "Fire Discord webhook" run: npx gulp fireNightlyWebhook
working-directory: ./buildtools env:
run: npx gulp fireNightlyWebhook GITHUB_RUN_ID: ${{ github.run_id }}
env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
GITHUB_RUN_ID: ${{ github.run_id }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}

View File

@ -28,8 +28,7 @@ export const zipMMC = zip.zipMMC;
import * as gha from "./tasks/misc/gha"; import * as gha from "./tasks/misc/gha";
export const makeArtifactNames = gha.makeArtifactNames; export const makeArtifactNames = gha.makeArtifactNames;
import deployCurseForgeTask from "./tasks/deploy/curseforge"; export { deployCurseForge, deployCurseForgeBeta } from "./tasks/deploy/curseforge";
export const deployCurseForge = deployCurseForgeTask;
import deployReleasesTask from "./tasks/deploy/releases"; import deployReleasesTask from "./tasks/deploy/releases";
export const deployReleases = deployReleasesTask; export const deployReleases = deployReleasesTask;

File diff suppressed because it is too large Load Diff

View File

@ -40,8 +40,8 @@
"requestretry": "^5.0.0", "requestretry": "^5.0.0",
"sanitize-filename": "^1.6.3", "sanitize-filename": "^1.6.3",
"sha1": "^1.1.1", "sha1": "^1.1.1",
"ts-node": "^9.1.1", "ts-node": "^10.9.1",
"typescript": "^4.2.3", "typescript": "^4.8.4",
"unzipper": "^0.10.11", "unzipper": "^0.10.11",
"upath": "^2.0.1" "upath": "^2.0.1"
}, },

View File

@ -9,24 +9,30 @@ import { makeArtifactNameBody } from "../../util/util";
import sanitize from "sanitize-filename"; import sanitize from "sanitize-filename";
const CURSEFORGE_LEGACY_ENDPOINT = "https://minecraft.curseforge.com/"; const CURSEFORGE_LEGACY_ENDPOINT = "https://minecraft.curseforge.com/";
const variablesToCheck = ["CURSEFORGE_API_TOKEN", "CURSEFORGE_PROJECT_ID", "GITHUB_TAG"]; const variablesToCheck = ["CURSEFORGE_API_TOKEN", "CURSEFORGE_PROJECT_ID"];
interface CFUploadOptions {
releaseType?: "release" | "beta";
}
/** /**
* Uploads build artifacts to CurseForge. * Uploads beta artifacts to CurseForge.
*/ */
async function deployCurseForge(): Promise<void> { export async function deployCurseForgeBeta(): Promise<void> {
/** /**
* Obligatory variable check. * Obligatory variable check.
*/ */
variablesToCheck.forEach((vari) => { ["RC_VERSION", ...variablesToCheck].forEach((vari) => {
if (!process.env[vari]) { if (!process.env[vari]) {
throw new Error(`Environmental variable ${vari} is unset.`); throw new Error(`Environmental variable ${vari} is unset.`);
} }
}); });
const tag = process.env.GITHUB_TAG; const version = process.env.RC_VERSION;
const flavorTitle = process.env.BUILD_FLAVOR_TITLE; const flavorTitle = process.env.BUILD_FLAVOR_TITLE;
const displayName = [modpackManifest.name, tag.replace(/^v/, ""), flavorTitle].filter(Boolean).join(" - "); const displayName = [modpackManifest.name, [version.replace(/^v/, ""), "Release Candidate"].join(" "), flavorTitle]
.filter(Boolean)
.join(" - ");
const files = [ const files = [
{ {
@ -42,6 +48,14 @@ async function deployCurseForge(): Promise<void> {
/** /**
* Obligatory file check. * Obligatory file check.
*/ */
await upload(files, {
releaseType: "beta",
});
}
async function upload(files: { name: string; displayName: string }[], opts?: CFUploadOptions) {
opts = opts || {};
files.forEach((file) => { files.forEach((file) => {
const path = upath.join(buildConfig.buildDestinationDirectory, file.name); const path = upath.join(buildConfig.buildDestinationDirectory, file.name);
if (!fs.existsSync(path)) { if (!fs.existsSync(path)) {
@ -71,6 +85,10 @@ async function deployCurseForge(): Promise<void> {
maxAttempts: 5, maxAttempts: 5,
})) || []; })) || [];
if (!versionsManifest) {
throw new Error("Failed to fetch CurseForge version manifest.");
}
const version = versionsManifest.find((m) => m.name == modpackManifest.minecraft.version); const version = versionsManifest.find((m) => m.name == modpackManifest.minecraft.version);
if (!version) { if (!version) {
@ -92,7 +110,7 @@ async function deployCurseForge(): Promise<void> {
metadata: JSON.stringify({ metadata: JSON.stringify({
changelog: changelog, changelog: changelog,
changelogType: "markdown", changelogType: "markdown",
releaseType: "release", releaseType: opts.releaseType || "release",
parentFileID: clientFileID, parentFileID: clientFileID,
gameVersions: clientFileID ? undefined : [version.id], gameVersions: clientFileID ? undefined : [version.id],
displayName: file.displayName, displayName: file.displayName,
@ -117,4 +135,33 @@ async function deployCurseForge(): Promise<void> {
} }
} }
export default deployCurseForge; /**
* Uploads build artifacts to CurseForge.
*/
export async function deployCurseForge(): Promise<void> {
/**
* Obligatory variable check.
*/
["GITHUB_TAG", ...variablesToCheck].forEach((vari) => {
if (!process.env[vari]) {
throw new Error(`Environmental variable ${vari} is unset.`);
}
});
const tag = process.env.GITHUB_TAG;
const flavorTitle = process.env.BUILD_FLAVOR_TITLE;
const displayName = [modpackManifest.name, tag.replace(/^v/, ""), flavorTitle].filter(Boolean).join(" - ");
const files = [
{
name: sanitize((makeArtifactNameBody(modpackManifest.name) + "-client.zip").toLowerCase()),
displayName: displayName,
},
{
name: sanitize((makeArtifactNameBody(modpackManifest.name) + "-server.zip").toLowerCase()),
displayName: `${displayName} Server`,
},
];
upload(files);
}

View File

@ -10,6 +10,8 @@ const randomPatchesConfigFile = "config/randompatches.cfg";
*/ */
export default async function transformManifestVersion(): Promise<void> { export default async function transformManifestVersion(): Promise<void> {
let versionTitle; let versionTitle;
// We're building a tag.
if (process.env.GITHUB_TAG) { if (process.env.GITHUB_TAG) {
const flavorTitle = process.env.BUILD_FLAVOR_TITLE; const flavorTitle = process.env.BUILD_FLAVOR_TITLE;
const tag = process.env.GITHUB_TAG.replace(/^v/, ""); const tag = process.env.GITHUB_TAG.replace(/^v/, "");
@ -18,6 +20,18 @@ export default async function transformManifestVersion(): Promise<void> {
modpackManifest.version = tag; modpackManifest.version = tag;
} }
// If we're buildig a release candidate, transform it appropriately.
else if (process.env.RC_VERSION) {
const rcVer = process.env.RC_VERSION;
const flavorTitle = process.env.BUILD_FLAVOR_TITLE;
const tag = rcVer.replace(/^v/, "");
versionTitle = [modpackManifest.name, [tag, "Release Candidate"].join(" "), flavorTitle]
.filter(Boolean)
.join(" - ");
modpackManifest.version = [rcVer, "rc"].join("-");
}
// If SHA is provided and the build isn't tagged, append both the branch and short SHA. // If SHA is provided and the build isn't tagged, append both the branch and short SHA.
else if (process.env.GITHUB_SHA && process.env.GITHUB_REF && process.env.GITHUB_REF.startsWith("refs/heads/")) { else if (process.env.GITHUB_SHA && process.env.GITHUB_REF && process.env.GITHUB_REF.startsWith("refs/heads/")) {
const shortCommit = process.env.GITHUB_SHA.substr(0, 7); const shortCommit = process.env.GITHUB_SHA.substr(0, 7);

View File

@ -156,6 +156,10 @@ export function makeArtifactNameBody(baseName: string): string {
if (process.env.GITHUB_TAG) { if (process.env.GITHUB_TAG) {
return `${baseName}-${process.env.GITHUB_TAG}`; return `${baseName}-${process.env.GITHUB_TAG}`;
} }
// RC.
else if (process.env.RC_VERSION) {
return `${baseName}-${process.env.RC_VERSION.replace(/^v/, "")}-rc`;
}
// If SHA is provided and the build isn't tagged, append both the branch and short SHA. // If SHA is provided and the build isn't tagged, append both the branch and short SHA.
else if (process.env.GITHUB_SHA && process.env.GITHUB_REF && process.env.GITHUB_REF.startsWith("refs/heads/")) { else if (process.env.GITHUB_SHA && process.env.GITHUB_REF && process.env.GITHUB_REF.startsWith("refs/heads/")) {
const shortCommit = process.env.GITHUB_SHA.substr(0, 7); const shortCommit = process.env.GITHUB_SHA.substr(0, 7);

View File

@ -1,19 +1,19 @@
:: Server Launch Script :: Server Launch Script
:: ::
:: Thrown together by Neeve in under five minutes, Public Domain :: Thrown together by Neeve in under five minutes, Public Domain
:: https://github.com/Neeve01 :: https://github.com/Neeve01
:: ::
:: Added java version check by t0suj4, Public Domain :: Added java version check by t0suj4, Public Domain
:: https://github.com/t0su4 :: https://github.com/t0su4
:: DO NOT EDIT UNLESS YOU KNOW WHAT YOU'RE DOING :: DO NOT EDIT UNLESS YOU KNOW WHAT YOU'RE DOING
@ECHO OFF @ECHO OFF
SET FORGEJAR={{forgeJar}} SET FORGEJAR={{{forgeJar}}}
SET JAVA_PARAMETERS={{jvmArgs}} SET JAVA_PARAMETERS={{{jvmArgs}}}
:: these you can edit :: these you can edit
SET MIN_RAM={{minRAM}} SET MIN_RAM={{{minRAM}}}
SET MAX_RAM={{maxRAM}} SET MAX_RAM={{{maxRAM}}}
:: DO NOT EDIT ANYTHING PAST THIS LINE :: DO NOT EDIT ANYTHING PAST THIS LINE
SET LAUNCHPARAMS=-server -Xms%MIN_RAM% -Xmx%MAX_RAM% %JAVA_PARAMETERS% -Dlog4j.configurationFile=log4j2_112-116.xml -jar %FORGEJAR% nogui SET LAUNCHPARAMS=-server -Xms%MIN_RAM% -Xmx%MAX_RAM% %JAVA_PARAMETERS% -Dlog4j.configurationFile=log4j2_112-116.xml -jar %FORGEJAR% nogui

View File

@ -3,18 +3,18 @@
# Server Launch Script # Server Launch Script
# #
# Thrown together by Neeve in under five minutes, Public Domain # Thrown together by Neeve in under five minutes, Public Domain
# https://github.com/Neeve01 # https://github.com/Neeve01
# #
# Fixed and added java version check by t0suj4, Public Domain # Fixed and added java version check by t0suj4, Public Domain
# https://github.com/t0suj4 # https://github.com/t0suj4
# DO NOT EDIT UNLESS YOU KNOW WHAT YOU'RE DOING # DO NOT EDIT UNLESS YOU KNOW WHAT YOU'RE DOING
FORGEJAR='{{forgeJar}}' FORGEJAR='{{{forgeJar}}}'
JAVA_PARAMETERS='{{jvmArgs}}' JAVA_PARAMETERS='{{{jvmArgs}}}'
# these you can edit # these you can edit
MIN_RAM='{{minRAM}}' MIN_RAM='{{{minRAM}}}'
MAX_RAM='{{maxRAM}}' MAX_RAM='{{{maxRAM}}}'
# DO NOT EDIT ANYTHING PAST THIS LINE # DO NOT EDIT ANYTHING PAST THIS LINE
LAUNCHPARAMS="-server -Xms$MIN_RAM -Xmx$MAX_RAM $JAVA_PARAMETERS -Dlog4j.configurationFile=log4j2_112-116.xml -jar $FORGEJAR nogui" LAUNCHPARAMS="-server -Xms$MIN_RAM -Xmx$MAX_RAM $JAVA_PARAMETERS -Dlog4j.configurationFile=log4j2_112-116.xml -jar $FORGEJAR nogui"