diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 4eabd25a..20bbc0d4 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -8,8 +8,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 + - name: Download bootstrap file + run: wget https://raw.githubusercontent.com/progit/progit2-pub/master/bootstrap.sh + - name: Run bootstrap + run: sh bootstrap.sh - name: Set up Ruby uses: ruby/setup-ruby@v1 with: @@ -17,4 +21,4 @@ jobs: bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Build book - run: bundle exec rake book:build + run: bundle exec rake book:build_action diff --git a/.github/workflows/release-on-merge.yml b/.github/workflows/release-on-merge.yml index 7efabb3d..3c877b87 100644 --- a/.github/workflows/release-on-merge.yml +++ b/.github/workflows/release-on-merge.yml @@ -8,9 +8,13 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 with: fetch-depth: 0 + - name: get bootstrap file + run: wget https://raw.githubusercontent.com/progit/progit2-pub/master/bootstrap.sh + - name: run bootstrap + run: sh bootstrap.sh - name: Compute tag name id: compute-tag run: | @@ -27,7 +31,7 @@ jobs: bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Build release assets - run: bundle exec rake book:build_build + run: bundle exec rake book:build_action - name: Create release uses: ncipollo/release-action@v1 @@ -35,4 +39,4 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ steps.compute-tag.outputs.tagname }} commit: ${{ steps.compute-tag.outputs.branch }} - artifacts: './progit.epub,./progit.fb2.zip,./progit.mobi,./progit.pdf,./progit.html' + artifacts: './progit.epub,./progit.mobi,./progit.pdf,./progit.html' diff --git a/.gitignore b/.gitignore index 1d6d2e34..724ad441 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ progit.html progit.pdf progit.pdfmarks progit.epub -progit.fb2.zip progit-kf8.epub progit.mobi contributors.txt diff --git a/Gemfile b/Gemfile index 751a5956..b569101b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,23 +1,22 @@ source 'https://rubygems.org' -gem 'ffi', '1.16.3' gem 'rake' -gem 'asciidoctor', '2.0.12' +gem 'asciidoctor', '1.5.6.2' gem 'json' gem 'awesome_print' -gem 'ttfunk', '1.5.1' -gem 'asciidoctor-fb2' -gem 'asciidoctor-epub3', '1.5.0.alpha.11' +gem 'ttfunk', '= 1.5.1' +gem 'asciidoctor-epub3', '1.5.0.alpha.9' gem 'asciidoctor-pdf', '1.5.0.alpha.16' gem 'asciidoctor-pdf-cjk', '~> 0.1.3' -gem 'asciidoctor-pdf-cjk-kai_gen_gothic', github: 'Sherry520/asciidoctor-pdf-cjk-kai_gen_gothic' +gem 'asciidoctor-pdf-cjk-kai_gen_gothic', '~> 0.1.1' gem 'coderay' gem 'pygments.rb' gem 'thread_safe' gem 'epubcheck-ruby' -gem 'html-proofer' +gem 'kindlegen' -gem 'kindlegen', '3.1.1' +gem 'octokit' +gem 'github_changelog_generator', github: 'Furtif/github-changelog-generator' diff --git a/Rakefile b/Rakefile index cb01f185..9cbfebc1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,7 @@ +# coding: utf-8 +require 'octokit' +require 'github_changelog_generator' + def exec_or_raise(command) puts `#{command}` if (! $?.success?) @@ -5,169 +9,242 @@ def exec_or_raise(command) end end -namespace :book do +module GitHubChangelogGenerator + + #OPTIONS = %w[ user project token date_format output + # bug_prefix enhancement_prefix issue_prefix + # header merge_prefix issues + # add_issues_wo_labels add_pr_wo_labels + # pulls filter_issues_by_milestone author + # unreleased_only unreleased unreleased_label + # compare_link include_labels exclude_labels + # bug_labels enhancement_labels + # between_tags exclude_tags exclude_tags_regex since_tag max_issues + # github_site github_endpoint simple_list + # future_release release_branch verbose release_url + # base configure_sections add_sections] + + def get_log(&task_block) + options = Parser.default_options + yield(options) if task_block + + options[:user],options[:project] = ENV['TRAVIS_REPO_SLUG'].split('/') + options[:token] = ENV['GITHUB_API_TOKEN'] + options[:unreleased] = false + + generator = Generator.new options + generator.compound_changelog + end - # Download asciidoctor-pdf-cjk-kai_gen_gothic - exec_or_raise("asciidoctor-pdf-cjk-kai_gen_gothic-install") + module_function :get_log +end - # Variables referenced for build - version_string = `git describe --tags --abbrev=0`.chomp - if version_string.empty? - version_string = '0' - else - versions = version_string.split('.') - version_string = versions[0] + '.' + versions[1] + '.' + versions[2].to_i.next.to_s - end - date_string = Time.now.strftime('%Y-%m-%d') - header_hash = `git rev-parse --short HEAD`.strip - - # Check language - repo = File.basename(`git rev-parse --show-toplevel`.chomp) - lang_match = repo.match(/progit2-([a-z-]*)/) - if lang_match - lang = lang_match[1] - else - lang = "en" - end +namespace :book do + desc 'build basic book formats' + task :build do - begin - if lang == "zh" - params = "-r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicCN --attribute revnumber='#{version_string}' --attribute revdate='#{date_string}' --attribute lang='#{lang}'" - elsif lang == "zh-tw" - params = "-r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicTW --attribute revnumber='#{version_string}' --attribute revdate='#{date_string}' --attribute lang='#{lang}'" - elsif lang == "ja" - params = "-r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicJP --attribute revnumber='#{version_string}' --attribute revdate='#{date_string}' --attribute lang='#{lang}'" - elsif lang == "ko" - params = "-r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicKR --attribute revnumber='#{version_string}' --attribute revdate='#{date_string}' --attribute lang='#{lang}'" + puts "Generating contributors list" + exec_or_raise("git shortlog -s --all $translation_origin | grep -v -E '(Straub|Chacon)' | cut -f 2- | sort | column -c 110 > book/contributors.txt") + + # detect if the deployment is using glob + travis = File.read(".travis.yml") + version_string = ENV['TRAVIS_TAG'] || '0' + if travis.match(/file_glob/) + progit_v = "progit_v#{version_string}" + else + progit_v = "progit" + end + text = File.read('progit.asc') + new_contents = text.gsub("$$VERSION$$", version_string).gsub("$$DATE$$", Time.now.strftime("%Y-%m-%d")) + File.open("#{progit_v}.asc", "w") {|file| file.puts new_contents } + + puts "Converting to HTML..." + exec_or_raise("bundle exec asciidoctor #{progit_v}.asc") + puts " -- HTML output at #{progit_v}.html" + + puts "Converting to EPub..." + exec_or_raise("bundle exec asciidoctor-epub3 #{progit_v}.asc") + puts " -- Epub output at #{progit_v}.epub" + + exec_or_raise("epubcheck #{progit_v}.epub") + + puts "Converting to Mobi (kf8)..." + exec_or_raise("bundle exec asciidoctor-epub3 -a ebook-format=kf8 #{progit_v}.asc") + # remove the fake epub that would shadow the really one + exec_or_raise("rm progit*kf8.epub") + puts " -- Mobi output at #{progit_v}.mobi" + + repo = ENV['TRAVIS_REPO_SLUG'] + puts "Converting to PDF... (this one takes a while)" + if (repo == "progit/progit2-zh") + exec_or_raise("asciidoctor-pdf-cjk-kai_gen_gothic-install") + exec_or_raise("bundle exec asciidoctor-pdf -r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicCN #{progit_v}.asc") + elsif (repo == "progit/progit2-ja") + exec_or_raise("asciidoctor-pdf-cjk-kai_gen_gothic-install") + exec_or_raise("bundle exec asciidoctor-pdf -r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicJP #{progit_v}.asc") + elsif (repo == "progit/progit2-zh-tw") + exec_or_raise("asciidoctor-pdf-cjk-kai_gen_gothic-install") + exec_or_raise("bundle exec asciidoctor-pdf -r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicTW #{progit_v}.asc") + elsif (repo == "progit/progit2-ko") + exec_or_raise("asciidoctor-pdf-cjk-kai_gen_gothic-install") + exec_or_raise("bundle exec asciidoctor-pdf -r asciidoctor-pdf-cjk -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicKR #{progit_v}.asc") else - params = "--attribute revnumber='#{version_string}' --attribute revdate='#{date_string}'" + exec_or_raise("bundle exec asciidoctor-pdf #{progit_v}.asc 2>/dev/null") end - rescue => e - puts e.message - puts 'Error when checking repo language(ignored)' + puts " -- PDF output at #{progit_v}.pdf" end - # Check contributors list - # This checks commit hash stored in the header of list against current HEAD - def check_contrib - if File.exist?('book/contributors.txt') - current_head_hash = `git rev-parse --short HEAD`.strip - header = `head -n 1 book/contributors.txt`.strip - # Match regex, then coerce resulting array to string by join - header_hash = header.scan(/[a-f0-9]{7,}/).join - - if header_hash == current_head_hash - puts "Hash on header of contributors list (#{header_hash}) matches the current HEAD (#{current_head_hash})" + desc 'tag the repo with the latest version' + task :tag do + api_token = ENV['GITHUB_API_TOKEN'] + if ((api_token) && (ENV['TRAVIS_PULL_REQUEST'] == 'false')) + repo = ENV['TRAVIS_REPO_SLUG'] + @octokit = Octokit::Client.new(:access_token => api_token) + begin + last_version=@octokit.latest_release(repo).tag_name + rescue + last_version="2.1.-1" + end + new_patchlevel= last_version.split('.')[-1].to_i + 1 + new_version="2.1.#{new_patchlevel}" + if (ENV['TRAVIS_BRANCH']=='master') + obj = @octokit.create_tag(repo, new_version, "Version " + new_version, + ENV['TRAVIS_COMMIT'], 'commit', + 'Automatic build', 'automatic@no-domain.org', + Time.now.utc.iso8601) + begin + @octokit.create_ref(repo, "tags/#{new_version}", obj.sha) + rescue + p "the ref already exists ???" + end + p "Created tag #{last_version}" + elsif (ENV['TRAVIS_TAG']) + version = ENV['TRAVIS_TAG'] + changelog = GitHubChangelogGenerator.get_log do |config| + config[:since_tag] = last_version + end + credit_line = "\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*" + changelog.gsub!(credit_line, "") + @octokit.create_release(repo, new_version, {:name => "v#{new_version}", :body => changelog}) + p "Created release #{new_version}" else - puts "Hash on header of contributors list (#{header_hash}) does not match the current HEAD (#{current_head_hash}), refreshing" - sh "rm book/contributors.txt" - # Reenable and invoke task again - Rake::Task['book/contributors.txt'].reenable - Rake::Task['book/contributors.txt'].invoke + p 'This only runs on a commit to master' end + else + p 'No interaction with GitHub' end end - desc 'build basic book formats' - task :build => [:build_html, :build_epub, :build_fb2, :build_mobi, :build_pdf] do - begin - # Run check - Rake::Task['book:check'].invoke - - # Rescue to ignore checking errors - rescue => e - puts e.message - puts 'Error when checking books (ignored)' - end - end - - desc 'build basic book formats (for ci)' - task :ci => [:build_html, :build_epub, :build_fb2, :build_mobi, :build_pdf] do - # Run check, but don't ignore any errors - Rake::Task['book:check'].invoke - end - - desc 'generate contributors list' - file 'book/contributors.txt' do - puts 'Generating contributors list' - sh "echo 'Contributors as of #{header_hash}:\n' > book/contributors.txt" - sh "git shortlog -s HEAD | grep -v -E '(Straub|Chacon|dependabot)' | cut -f 2- | sort | column -c 120 >> book/contributors.txt" - end - - desc 'build HTML format' - task :build_html => 'book/contributors.txt' do - check_contrib() - - puts 'Converting to HTML...' - sh "bundle exec asciidoctor #{params} -a data-uri progit.asc" - puts ' -- HTML output at progit.html' - - end - - desc 'build Epub format' - task :build_epub => 'book/contributors.txt' do - check_contrib() - - puts 'Converting to EPub...' - sh "bundle exec asciidoctor-epub3 #{params} progit.asc" - puts ' -- Epub output at progit.epub' - - end - - desc 'build FB2 format' - task :build_fb2 => 'book/contributors.txt' do - check_contrib() - - puts 'Converting to FB2...' - sh "bundle exec asciidoctor-fb2 #{params} progit.asc" - puts ' -- FB2 output at progit.fb2.zip' - - end - - desc 'build Mobi format' - task :build_mobi => 'book/contributors.txt' do - check_contrib() - - puts "Converting to Mobi (kf8)..." - sh "bundle exec asciidoctor-epub3 #{params} -a ebook-format=kf8 progit.asc" - puts " -- Mobi output at progit.mobi" - end - - desc 'build PDF format' - task :build_pdf => 'book/contributors.txt' do - check_contrib() - - puts 'Converting to PDF... (this one takes a while)' - sh "bundle exec asciidoctor-pdf #{params} progit.asc 2>/dev/null" - puts ' -- PDF output at progit.pdf' - end - - desc 'Check generated books' - task :check => [:build_html, :build_epub] do - puts 'Checking generated books' - - sh "htmlproofer progit.html" - sh "epubcheck progit.epub" + desc 'convert book to asciidoctor compatibility' + task:convert do + `cp -aR ../progit2/images .` + `sed -i -e 's!/images/!!' .gitignore` + `git add images` + `git rm -r book/*/images` + + chapters = [ + ["01", "introduction" ], + ["02", "git-basics" ], + ["03", "git-branching" ], + ["04", "git-server" ], + ["05", "distributed-git" ], + ["06", "github" ], + ["07", "git-tools" ], + ["08", "customizing-git" ], + ["09", "git-and-other-scms" ], + ["10", "git-internals" ], + ["A", "git-in-other-environments" ], + ["B", "embedding-git" ], + ["C", "git-commands" ] + ] + + crossrefs = {} + chapters.each { | num, title | + if num =~ /[ABC]/ + chap = "#{num}-#{title}" + else + chap = "ch#{num}-#{title}" + end + Dir[File.join ["book","#{num}-#{title}" , "sections","*.asc"]].map { |filename| + File.read(filename).scan(/\[\[(.*?)\]\]/) + }.flatten.each { |ref| + crossrefs[ref] = "#{chap}" + } + } + + headrefs = {} + chapters.each { | num, title | + if num =~ /[ABC]/ + chap = "#{num}-#{title}" + else + chap = "ch#{num}-#{title}" + end + Dir[File.join ["book","#{num}-#{title}", "*.asc"]].map { |filename| + File.read(filename).scan(/\[\[([_a-z0-9]*?)\]\]/) + }.flatten.each { |ref| + headrefs[ref] = "#{chap}" + } + } + + # transform all internal cross refs + chapters.each { | num, title | + if num =~ /[ABC]/ + chap = "#{num}-#{title}" + else + chap = "ch#{num}-#{title}" + end + files = Dir[File.join ["book","#{num}-#{title}" , "sections","*.asc"]] + + Dir[File.join ["book","#{num}-#{title}" ,"1-*.asc"]] + p files + files.each { |filename| + content = File.read(filename) + new_contents = content.gsub(/\[\[([_a-z0-9]*?)\]\]/, '[[r\1]]').gsub( + "→", "→").gsub(/<<([_a-z0-9]*?)>>/) { |match| + ch = crossrefs[$1] + h = headrefs[$1] + # p " #{match} -> #{ch}, #{h}" + if ch + # if local do not add the file + if ch==chap + "<>" + else + "<<#{ch}#r#{$1}>>" + end + elsif h + if h==chap + "<<#{chap}>>" + else + "<<#{h}##{h}>>" + end + else + p "could not match xref #{$1}" + "<<#{$1}>>" + end + } + File.open(filename, "w") {|file| file.puts new_contents } + } + } + + chapters.each { | num, title | + if num =~ /[ABC]/ + chap = "#{num}-#{title}" + else + chap = "ch#{num}-#{title}" + end + Dir[File.join ["book","#{num}-#{title}" ,"1*.asc"]].map { |filename| + content = File.read (filename) + new_contents = content.gsub(/include::(.*?)asc/) {|match| + "include::book/#{num}-#{title}/#{$1}asc"} + `git rm -f #{filename}` + File.open("#{chap}.asc", "w") {|file| + file.puts "[##{chap}]\n" + file.puts new_contents } + `git add "#{chap}.asc"` + } + } end +end - desc 'Clean all generated files' - task :clean do - begin - puts 'Removing generated files' - - FileList['book/contributors.txt', 'progit.html', 'progit-kf8.epub', 'progit.epub', 'progit.fb2.zip', 'progit.mobi', 'progit.pdf'].each do |file| - rm file - # Rescue if file not found - rescue Errno::ENOENT => e - begin - puts e.message - puts 'Error removing files (ignored)' - end - end - end - end - -end task :default => "book:build"