Skip to content

Instantly share code, notes, and snippets.

@FluffierThanThou
Created December 14, 2016 14:32
Show Gist options
  • Save FluffierThanThou/f7ec56d1353feab8d14f32a2819f24e8 to your computer and use it in GitHub Desktop.
Save FluffierThanThou/f7ec56d1353feab8d14f32a2819f24e8 to your computer and use it in GitHub Desktop.
node rimworld update script
var fs = require("fs");
var path = require("path");
var vdf = require("vdf");
var exec = require("child_process").execSync;
var GitHubApi = require("github");
var parseGit = require('parse-git-config');
const git_api_token = "SECRET";
const steam_login = "SECRET";
// fetch the mod location, name and release type
var mod = process.argv[2];
var name = process.argv[3] || mod;
var major = process.argv[4] != undefined;
var base_install_path = "C:/Program Files (x86)/Steam/steamapps/common/RimWorld/Mods";
var install_path = path.join( base_install_path, mod );
var configfile = path.join( mod, "Source", "ModConfig.json" );
var vdffile = path.join( mod, "Source", "SteamConfig.vdf" );
console.log( "Running steam update process for " + mod + "..." );
// check git status is clean (and it's gitted in the first place)
if ( !checkGitStatus() ){
console.error( "uncommitted changes, or commits not pushed!" );
process.exit(1);
}
// get mod config file
var config = getConfig( configfile );
// check if we've set a publishedfileid
if ( config.publishedfileid === undefined ){
console.error( "please set a publishedfileid \n(note that in order to correctly set tags, the initial release should be performed from within the game)" );
process.exit(2);
}
// bump version
if (major)
config.version.major++;
else
config.version.minor++;
// update changenotes
config.changenote = getChangeNote();
// make sure the mods' .vdf exists
checkSteamVDF( mod, config );
// set changenote and put version in description of vdf
updateVDF();
// try releasing on the workshop, note that vdffile path appears to be relative to the location of steamcmd
exec( "steamcmd +login "+ steam_login + " workshop_build_item ..\\" + vdffile + " +quit", {stdio:[0,1,2]} );
// do github release
createGithubReleaseWithAsset();
// NOTE: final wrapup (git pull & store updated config is handled in createGithubReleaseWithAsset)
/////////////////////////////////////////////////////////////////////////////////
/// utility functions below.
function createGithubReleaseWithAsset(){
github = new GitHubApi({
debug: true,
protocol: "https",
host: "api.github.com",
headers: {
"user-agent": "mod-update-script"
},
Promise: global.Promise,
timeout: 20000
})
github.authenticate({
type: "token",
token: git_api_token
})
github.repos.createRelease({
owner: config.git_user,
repo: config.git_repo,
tag_name: getVersionString(),
name: name + " v" + getVersionString(),
body: "THIS IS NOT A REAL RELEASE! I'm testing my build script(s). \n\n - Fluffy", // getReleaseBodyText
prerelease: false
}, function( err, res) {
if (err)
throw err;
console.log( "GitHub release created, uploading archive...")
github.repos.uploadAsset({
owner: config.git_user,
repo: config.git_repo,
id: res.id,
filePath: path.resolve( mod+".rar" ),
name: mod + ".rar",
label: name + " v" + getVersionString()
}, function( err, res ){
if (err)
throw err;
console.log( "Archive uploaded." );
// pull the new tag from the repo
exec( at(mod) + "git pull --tags", {stdio:[0,1,2]} );
// store config
fs.writeFileSync( configfile, JSON.stringify( config, null, 4 ), 'utf-8' );
// process complete!
console.log( "Done!" );
})
})
}
function getGitInfo(){
var git = parseGit.sync({cwd: mod, path: ".git/config"});
var origin = git['remote "origin"'].url;
var regex = /^https:\/\/github\.com\/(.+?)\/(.+?)\.git$/;
var parts = origin.match( regex );
return { user: parts[1], repo: parts[2] }
}
function updateVDF(){
var vdf_raw = fs.readFileSync( vdffile, 'utf-8' );
var vdf_data = vdf.parse( vdf_raw );
vdf_data.workshopitem.changenote = config.changenote;
vdf_data.workshopitem.description = getDescription( getVersionString() );
fs.writeFileSync( vdffile, vdf.dump( vdf_data ), 'utf-8' );
}
function updatePublishedfileid(){
var vdf_raw = fs.readFileSync( vdffile, 'utf-8' );
var vdf_data = vdf.parse( vdf_raw );
config.publishedfileid = vdf_data.workshopitem.publishedfileid;
}
function getVersionString(){
return config.version.phase + "." + config.version.alpha + "." + config.version.major + "." + config.version.minor;
}
function checkSteamVDF(){
try {
fs.statSync( vdffile );
} catch(e){
createSteamVDF();
}
}
function checkGitStatus(){
var uncommited_work = exec( at( mod ) + "git status --porcelain" ).toString().trim();
if ( uncommited_work != '' )
return false;
var commits_not_pushed = exec( at( mod ) + "git log origin/master.." ).toString().trim();
if ( commits_not_pushed != '' )
return false;
return true;
}
function at( wd ){
return "cd " + wd + " && ";
}
function createSteamVDF(){
var vdf_data = {
"workshopitem": {
"appid": 294100,
"contentfolder": config.install_path,
"previewfile": path.join( config.install_path, "About", "preview.png" ),
"visibilitiy": config.visibility,
"title": config.name,
"description": config.description,
"changenote": config.changenote,
"publishedfileid": config.publishedfileid,
}
}
fs.writeFileSync( vdffile, vdf.dump( vdf_data ), 'utf-8' );
}
function getChangeNote(){
return exec( at(mod) + "git log " + getCurrentGitTag() + "..HEAD --pretty=format:\"%s\"").toString( 'utf-8' );
}
function getDescription(version){
return "";
}
function getCurrentGitTag(){
return exec( at(mod) + "git describe --tags --abbrev=0").toString( 'utf-8' ).trim();
}
function getConfig(){
try {
config = JSON.parse( fs.readFileSync( configfile, 'utf-8' ) );
} catch(e)
{
console.log( "No config file found, creating..." );
git_info = getGitInfo();
config = {
name: name,
version: {
phase: 0,
alpha: 16,
major: 0,
minor: 0
},
visibility: 0,
install_path: install_path,
description: getDescription(),
publishedfileid: undefined,
git_repo: git_info.repo,
git_user: git_info.user
}
config.changenote = getChangeNote();
fs.writeFileSync( configfile, JSON.stringify( config, null, 4 ), 'utf-8' );
}
return config;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment