From d3603947cc663d8a9bcb5890ff72f849d38dbf3e Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Thu, 7 May 2020 11:46:54 -0500 Subject: [PATCH] Added semi-automatic game:release rake task --- Gemfile | 2 + Gemfile.lock | 4 + Rakefile | 6 ++ i-mic-fps.rb | 20 +++- lib/ui/menus/settings_menu.rb | 2 +- rakelib/release.rake | 166 ++++++++++++++++++++++++++++++++++ 6 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 rakelib/release.rake diff --git a/Gemfile b/Gemfile index c9911c4..4743343 100644 --- a/Gemfile +++ b/Gemfile @@ -8,4 +8,6 @@ gem "async-websocket" group(:packaging) do gem "releasy", github: "gosu/releasy" gem "ocra" + gem "rubyzip" + gem "excon" end diff --git a/Gemfile.lock b/Gemfile.lock index 1b9099a..59d2c94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -40,6 +40,7 @@ GEM protocol-websocket (~> 0.7.0) console (1.8.2) cri (2.1.0) + excon (0.73.0) gosu (0.15.1) gosu (0.15.1-x64-mingw32) gosu_more_drawables (0.3.0) @@ -61,6 +62,7 @@ GEM protocol-http (~> 0.2) protocol-http1 (~> 0.2) rake (13.0.1) + rubyzip (2.3.0) timers (4.3.0) PLATFORMS @@ -70,11 +72,13 @@ PLATFORMS DEPENDENCIES async-websocket cyberarm_engine! + excon nokogiri (>= 1.11.0.rc1) ocra opengl-bindings rake releasy! + rubyzip BUNDLED WITH 2.1.4 diff --git a/Rakefile b/Rakefile index c073ec4..68e4fef 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,9 @@ +require "json" +require "tmpdir" +require "fileutils" + +require "zip" +require "excon" require "releasy" require 'bundler/setup' # Releasy requires that your application uses bundler. require_relative "lib/version" diff --git a/i-mic-fps.rb b/i-mic-fps.rb index 4bf1875..1f61304 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -4,6 +4,7 @@ require "json" require "abbrev" require "time" require "socket" +require "tmpdir" require "opengl" require "glu" @@ -134,7 +135,22 @@ require_relative "lib/tools/map_editor" # Don't launch game if IMICFPS_SERVER_MODE is defined # or if game is being packaged -unless defined?(IMICFPS_SERVER_MODE) or defined?(Ocra) +def prevent_launch? + packaging_lockfile = File.expand_path("i-mic-fps-packaging.lock", Dir.tmpdir) + m = "Game client not launched" + + return [true, "#{m}: Server is running"] if defined?(IMICFPS_SERVER_MODE) && IMICFPS_SERVER_MODE + + return [true, "#{m}: Packaging is running"] if defined?(Ocra) + + if File.exist?(packaging_lockfile) && File.read(packaging_lockfile).strip == IMICFPS::VERSION + return [true, "#{m}: Packaging lockfile is present (#{packaging_lockfile})"] + end + + return [false, ""] +end + +unless prevent_launch?[0] if ARGV.join.include?("--profile") begin require "ruby-prof" @@ -149,4 +165,6 @@ unless defined?(IMICFPS_SERVER_MODE) or defined?(Ocra) else IMICFPS::Window.new.show end +else + puts prevent_launch?[1] end \ No newline at end of file diff --git a/lib/ui/menus/settings_menu.rb b/lib/ui/menus/settings_menu.rb index 570f168..c39d1d1 100644 --- a/lib/ui/menus/settings_menu.rb +++ b/lib/ui/menus/settings_menu.rb @@ -66,7 +66,7 @@ class IMICFPS end end - check_box "Fullscreen", padding_top: 25, padding_top: 25 + check_box "Fullscreen", padding_top: 25, padding_bottom: 25 flow do stack do diff --git a/rakelib/release.rake b/rakelib/release.rake new file mode 100644 index 0000000..19394f2 --- /dev/null +++ b/rakelib/release.rake @@ -0,0 +1,166 @@ +PACKAGING_LOCKFILE = File.expand_path("i-mic-fps-packaging.lock", Dir.tmpdir) +GITHUB_API_URL = "https://api.github.com/repos/cyberarm/i-mic-fps" +USERAGENT = "cyberarm +i-mic-fps" +DEFAULT_HEADERS = {"Authorization": "token #{ENV["GITHUB_TOKEN"]}", "User-Agent": USERAGENT} + +def sh_with_status(command) + outbuf = IO.popen(command, :err => [:child, :out], &:read) + status = $? + + return status +end + +def version + IMICFPS::VERSION +end + +def version_tag + "v#{version}" +end + +def release_name + "#{IMICFPS::NAME.gsub(" ", "-").downcase}_#{version_tag}" +end + +def clean? + sh_with_status(%w[git diff --exit-code]).success? +end + +def committed? + sh_with_status(%w[git diff-index --quiet --cached HEAD]).success? +end + +def guard_clean + clean? && committed? || abort(" There are files that need to be committed.") +end + +def tag_version + sh %W[git tag -m Version\ #{version} #{version_tag}] + puts " #{version_tag}." +rescue RuntimeError + puts " Untagging #{version_tag} due to error." + sh_with_status %W[git tag -d #{version_tag}] + abort +end + +def already_tagged? + return false unless sh(%w[git tag]).split(/\n/).include?(version_tag) + abort " Tag #{version_tag} has already been created." +end + +def create_lockfile + File.open(PACKAGING_LOCKFILE, "w") { |f| f.write version } +end +def remove_lockfile + File.delete(PACKAGING_LOCKFILE) + rescue Errno::ENOENT +end + +def create_directory(dir) + levels = dir.split("/") + location = "" + levels.each do |level| + location +="#{level}/" + mkdir_p location unless File.exist?(location) + end +end + +def build_package(path) + abort " Package folder already exists!" if File.exist?(path) + sh "rake build:windows:folder" +end + +def patch_windows_package(folder) + patch = "require_relative \"i-mic-fps/i-mic-fps\"" + patch_file = "#{folder}/src/i-mic-fps.rb" + + File.open(patch_file, "w") { |f| f.write patch } +end + +def create_archive(folder, archive) + abort " Archive already exists!" if File.exist?(archive) + Zip::File.open(archive, Zip::File::CREATE) do |zipfile| + Dir["#{folder}/**/**"].each do |file| + zipfile.add(file.sub(folder + '/', ''), file) + end + end +end + +def get_release + url = "#{GITHUB_API_URL}/releases" + request = Excon.get(url, headers: DEFAULT_HEADERS) + + if request.status == 200 + release = JSON.parse(request.body).find { |r| r["tag_name"] == version_tag } + return release + else + abort " Getting repo releases failed! (#{request.status})" + end +end + +def upload_asset(asset) + github_token = ENV["GITHUB_TOKEN"] + abort " GITHUB_TOKEN not set!" unless github_token + + release = get_release + upload_url = release["upload_url"].split("{?").first + "?name=#{asset.split("/").last}" + + file = File.read(asset) + + headers = DEFAULT_HEADERS + headers["Content-Type"] = "application/zip" + headers["Content-Length"] = file.size + + request = Excon.post(upload_url, body: file, headers: headers) + abort " Upload failed! #{request.body} (#{request.status})" unless request.status.between?(200, 201) +end + +namespace "game" do + desc "Create git tag, build, and release package" + task :release do + puts "Checking for uncommited changes..." + guard_clean + puts "Checking git tag for #{version_tag}..." + already_tagged? + puts "Committing git tag #{version_tag}..." + tag_version + puts "Pushing changes..." + sh "git push origin master" + sh "git push origin master --tags" + + path = File.expand_path("../pkg/#{release_name}_WIN32", __dir__) + + puts "Building release package '#{release_name}', this may take a while..." + create_lockfile + build_package(path) + puts "Patching..." + patch_windows_package(path) + puts "Creating archive..." + create_archive(path, "#{path}.zip") + remove_lockfile + + puts "Pushing package to github..." + upload_asset("#{path}.zip") + puts "Done." + end + + desc "Remove packaging assets" + task "release:cleanup" do + path = File.expand_path("../pkg", __dir__) + + if File.exist?(path) + puts "Cleaning up..." + + Dir["#{path}/**"].each do |file| + puts "Removing #{file}..." + if File.directory?(file) + FileUtils.remove_entry_secure(file) + else + File.delete(file) + end + end + + puts "Done." + end + end +end \ No newline at end of file