diff options
author | Achilleas Pipinellis <axil@gitlab.com> | 2023-04-24 19:55:02 +0300 |
---|---|---|
committer | Sarah German <sgerman@gitlab.com> | 2023-04-24 19:55:02 +0300 |
commit | e5c3820bf5695e7ed08f9153881c1f1470f35238 (patch) | |
tree | c9f18bda3343538eed8b85287e0a4b5d0aeff6b6 /lib | |
parent | 554f24e7fb4e1e03df64d095d12aab90e57461e4 (diff) |
Automate the update of versions.json
Diffstat (limited to 'lib')
-rw-r--r-- | lib/release.rb | 141 | ||||
-rw-r--r-- | lib/tasks/redirects.rake | 40 | ||||
-rw-r--r-- | lib/tasks/release.rake | 73 | ||||
-rw-r--r-- | lib/tasks/task_helpers.rb | 32 |
4 files changed, 192 insertions, 94 deletions
diff --git a/lib/release.rb b/lib/release.rb new file mode 100644 index 00000000..d6b2627f --- /dev/null +++ b/lib/release.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require_relative 'tasks/task_helpers' + +require 'fileutils' +require 'pathname' + +class Release + CURRENT_RELEASE_DATE = Date.today.strftime("%Y-%m-22") + NEXT_RELEASE_DATE = (Date.today >> 1).strftime("%Y-%m-22") + PREVIOUS_RELEASE_DATE = (Date.today << 1).strftime("%Y-%m-22") + PREVIOUS_PREVIOUS_RELEASE_DATE = (Date.today << 2).strftime("%Y-%m-22") + + ExplicitError = Class.new(StandardError) + + def initialize(version: nil, dry_run: ENV['DRY_RUN'] == 'true') + @version = version || task_helpers.milestone(CURRENT_RELEASE_DATE) + @dry_run = dry_run + end + + def single + # Disable lefthook because it causes PATH errors + # https://docs.gitlab.com/ee/development/contributing/style_guides.html#disable-lefthook-temporarily + ENV['LEFTHOOK'] = '0' + + raise ExplicitError, "Local branch already exists. Run `git branch --delete --force #{version}` and rerun the task." if !dry_run && task_helpers.local_branch_exist?(version) + raise ExplicitError, "'#{dockerfile}' already exists. Run `rm #{dockerfile}` and rerun the task." if dockerfile.exist? + + stash_changes + checkout_main_and_update + create_branch_for_version + create_dockerfile + commit_dockerfile + git_push_branch + end + + def update_versions_dropdown + if dry_run + info("DRY RUN: Not updating the version dropdown...") + else + current_version = task_helpers.milestone(CURRENT_RELEASE_DATE) + next_version = task_helpers.milestone(NEXT_RELEASE_DATE) + previous_version = task_helpers.milestone(PREVIOUS_RELEASE_DATE) + previous_previous_version = task_helpers.milestone(PREVIOUS_PREVIOUS_RELEASE_DATE) + + dropdown_json = JSON.load_file!('content/versions.json') + dropdown_json.first.merge!( + 'next' => next_version, + 'current' => current_version, + 'last_minor' => [previous_version, previous_previous_version] + ) + + info("Updating content/versions.json...") + File.write('content/versions.json', JSON.pretty_generate(dropdown_json)) + end + end + + private + + attr_reader :version, :dry_run + + def dockerfile + @dockerfile ||= Pathname.new("#{version}.Dockerfile") + end + + def stash_changes + if dry_run + info("DRY RUN: Not stashing local changes.") + else + info("Stashing local changes...") + exec_cmd("git stash -u") if task_helpers.git_workdir_dirty? + end + end + + def checkout_main_and_update + if dry_run + info("DRY RUN: Not checking out main branch and pulling updates.") + else + info("Checking out main branch and pulling updates...") + exec_cmd("git checkout main") + exec_cmd("git pull origin main") + end + end + + def create_branch_for_version + if dry_run + info("DRY RUN: Not creating branch #{version}.") + else + info("Creating branch #{version}...") + exec_cmd("git checkout -b #{version}") + end + end + + def create_dockerfile + single_dockerfile = Pathname.new('dockerfiles/single.Dockerfile') + + if dry_run + info("DRY RUN: Not creating file #{dockerfile}.") + else + info("Creating file #{dockerfile}...") + dockerfile.open('w') do |post| + post.write(single_dockerfile.read.gsub('ARG VER', "ARG VER=#{version}")) + end + end + end + + def commit_dockerfile + if dry_run + info("DRY RUN: Not adding file #{dockerfile} to branch #{version} or commiting changes.") + else + info("Adding file #{dockerfile} and commiting changes to branch #{version}...") + exec_cmd("git add #{version}.Dockerfile") + exec_cmd("git commit -m 'Release cut #{version}'") + end + end + + def git_push_branch + if dry_run + info("DRY RUN: Not pushing branch #{version}.") + else + info("Pushing branch #{version}. Don't create a merge request...") + exec_cmd("git push origin #{version}") + end + end + + def task_helpers + @task_helpers ||= TaskHelpers.new + end + + def exec_cmd(cmd) + `#{cmd}` + end + + def info(msg) + task_helpers.info("gitlab-docs", msg) + end + + def error(msg) + task_helpers.error("gitlab-docs", msg) + end +end diff --git a/lib/tasks/redirects.rake b/lib/tasks/redirects.rake index 13e07a42..aa815d2d 100644 --- a/lib/tasks/redirects.rake +++ b/lib/tasks/redirects.rake @@ -29,6 +29,8 @@ end namespace :docs do desc 'GitLab | Docs | Clean up old redirects' task :clean_redirects do + include TaskHelpers::Output + redirects_yaml = "#{task_helpers.project_root}/content/_data/redirects.yaml" today = Time.now.utc.to_date mr_description = "Monthly cleanup of docs redirects.</br><p>See https://about.gitlab.com/handbook/product/ux/technical-writing/#regularly-scheduled-tasks</p></br></hr></br><p>_Created automatically: https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/raketasks.md#clean-up-redirects_</p>" @@ -43,9 +45,9 @@ namespace :docs do abort("\n#{TaskHelpers::COLOR_CODE_RED}ERROR: jq not found. Install jq and run task again.#{TaskHelpers::COLOR_CODE_RESET}") if `which jq`.empty? if ENV['DRY_RUN'] == 'true' - TaskHelpers.info("gitlab-docs", "Not stashing changes in gitlab-docs or syncing with upstream default branch because running in dry run mode.") + info("gitlab-docs", "Not stashing changes in gitlab-docs or syncing with upstream default branch because running in dry run mode.") else - TaskHelpers.info("gitlab-docs", "Stashing changes in gitlab-docs and syncing with upstream default branch...") + info("gitlab-docs", "Stashing changes in gitlab-docs and syncing with upstream default branch...") system("git stash --quiet -u") if task_helpers.git_workdir_dirty? system("git checkout --quiet main") system("git fetch --quiet origin main") @@ -93,9 +95,9 @@ namespace :docs do Dir.chdir(content_dir) do if ENV['DRY_RUN'] == 'true' - TaskHelpers.info(slug, "Running in dry run mode...") + info(slug, "Running in dry run mode...") else - TaskHelpers.info(slug, "Stashing changes and syncing with upstream default branch...") + info(slug, "Stashing changes and syncing with upstream default branch...") system("git", "stash", "--quiet", "-u") if task_helpers.git_workdir_dirty? system("git", "checkout", "--quiet", default_branch) system("git", "fetch", "--quiet", "origin", default_branch) @@ -135,12 +137,12 @@ namespace :docs do # next unless remove_date < today - TaskHelpers.info(slug, "In #{filename}, remove date: #{remove_date} is less than today (#{today}).") + info(slug, "In #{filename}, remove date: #{remove_date} is less than today (#{today}).") counter += 1 if ENV['DRY_RUN'] == 'true' - TaskHelpers.info(slug, "Not deleting #{filename} because running in dry run mode.") + info(slug, "Not deleting #{filename} because running in dry run mode.") else FileUtils.rm_f(filename) end @@ -150,7 +152,7 @@ namespace :docs do next if new_path(frontmatter['redirect_to'], filename, content_dir, slug).start_with?('http') if ENV['DRY_RUN'] == 'true' - TaskHelpers.info("gitlab-docs", "Not updating redirects.yaml because running in dry run mode.") + info("gitlab-docs", "Not updating redirects.yaml because running in dry run mode.") else File.open(redirects_yaml, 'a') do |post| post.puts " - from: #{old_path}" @@ -164,7 +166,7 @@ namespace :docs do next unless old_path.end_with?('index.html') if ENV['DRY_RUN'] == 'true' - TaskHelpers.info("gitlab-docs", "Not updating redirects.yaml because running in dry run mode.") + info("gitlab-docs", "Not updating redirects.yaml because running in dry run mode.") else File.open(redirects_yaml, 'a') do |post| post.puts " - from: #{old_path.gsub!('index.html', '')}" @@ -183,24 +185,24 @@ namespace :docs do # 4. Commit and push the branch to create the MR # - TaskHelpers.info(slug, "Found #{counter} redirect(s).") + info(slug, "Found #{counter} redirect(s).") next unless counter.positive? Dir.chdir(content_dir) do if ENV['DRY_RUN'] == 'true' - TaskHelpers.info(slug, "Not creating branch or commiting changes because running in dry run mode.") + info(slug, "Not creating branch or commiting changes because running in dry run mode.") else - TaskHelpers.info(slug, "Creating a new branch for the redirects merge request...") + info(slug, "Creating a new branch for the redirects merge request...") system("git", "checkout", "--quiet", "-b", redirects_branch, origin_default_branch) - TaskHelpers.info(slug, "Committing changes to branch...") + info(slug, "Committing changes to branch...") system("git", "add", ".") system("git", "commit", "--quiet", "-m", commit_message) end if ENV['DRY_RUN'] == 'true' - TaskHelpers.info(slug, "Not pushing branch because running in dry run mode.") + info(slug, "Not pushing branch because running in dry run mode.") else - TaskHelpers.info(slug, "Pushing branch to create a merge request...") + info(slug, "Pushing branch to create a merge request...") `git push --set-upstream origin #{redirects_branch} -o merge_request.create -o merge_request.remove_source_branch -o merge_request.title="#{mr_title}" -o merge_request.description="#{mr_description}" -o merge_request.label="Technical Writing" -o merge_request.label="documentation" -o merge_request.label="docs::improvement" -o merge_request.label="type::maintenance" -o merge_request.label="maintenance::refactor"` \ end end @@ -216,19 +218,19 @@ namespace :docs do # mr_title = "Clean up docs redirects - #{today}" if ENV['DRY_RUN'] == 'true' - TaskHelpers.info("gitlab-docs", "Not creating branch or commiting changes because running in dry run mode.") + info("gitlab-docs", "Not creating branch or commiting changes because running in dry run mode.") else - TaskHelpers.info("gitlab-docs", "Creating a new branch for the redirects merge request...") + info("gitlab-docs", "Creating a new branch for the redirects merge request...") system("git", "checkout", "--quiet", "-b", redirects_branch, "origin/main") - TaskHelpers.info("gitlab-docs", "Committing changes to branch...") + info("gitlab-docs", "Committing changes to branch...") system("git", "add", redirects_yaml) system("git", "commit", "--quiet", "-m", commit_message) end if ENV['DRY_RUN'] == 'true' - TaskHelpers.info("gitlab-docs", "Not pushing branch because running in dry run mode.") + info("gitlab-docs", "Not pushing branch because running in dry run mode.") else - TaskHelpers.info("gitlab-docs", "Pushing branch to create a merge request...") + info("gitlab-docs", "Pushing branch to create a merge request...") `git push --set-upstream origin #{redirects_branch} -o merge_request.create -o merge_request.remove_source_branch -o merge_request.title="#{mr_title}" -o merge_request.description="#{mr_description}" -o merge_request.label="Technical Writing" -o merge_request.label="redirects" -o merge_request.label="Category:Docs Site" -o merge_request.label="type::maintenance" -o merge_request.label="maintenance::refactor"` \ end end diff --git a/lib/tasks/release.rake b/lib/tasks/release.rake index 30c69b6e..cdd74620 100644 --- a/lib/tasks/release.rake +++ b/lib/tasks/release.rake @@ -1,74 +1,21 @@ # frozen_string_literal: true -require './lib/tasks/task_helpers' -require 'fileutils' -require 'pathname' - -task_helpers = TaskHelpers.new -DRY_RUN = ENV['DRY_RUN'] == 'true' +require_relative '../release' namespace :release do desc 'Creates a single release archive' task :single, :version do - require "highline/import" - version = task_helpers.current_milestone - - # Disable lefthook because it causes PATH errors - # https://docs.gitlab.com/ee/development/contributing/style_guides.html#disable-lefthook-temporarily - ENV['LEFTHOOK'] = '0' - - abort("\n#{TaskHelpers::COLOR_CODE_RED}ERROR: Rake aborted! Local branch already exists. Run `git branch --delete --force #{version}` and rerun the task.#{TaskHelpers::COLOR_CODE_RESET}") \ - if task_helpers.local_branch_exist?(version) - - if DRY_RUN - TaskHelpers.info("gitlab-docs", "DRY RUN: Not stashing local changes.") - else - TaskHelpers.info("gitlab-docs", "Stashing local changes...") - `git stash -u` if task_helpers.git_workdir_dirty? - end - - if DRY_RUN - TaskHelpers.info("gitlab-docs", "DRY RUN: Not checking out main branch and pulling updates.") - else - TaskHelpers.info("gitlab-docs", "Checking out main branch and pulling updates...") - `git checkout main` - `git pull origin main` - end + include TaskHelpers::Output - if DRY_RUN - TaskHelpers.info("gitlab-docs", "DRY RUN: Not creating branch #{version}.") - else - TaskHelpers.info("gitlab-docs", "Creating branch #{version}...") - `git checkout -b #{version}` - end - - dockerfile = Pathname.new("#{version}.Dockerfile") - single_dockerfile = Pathname.new('dockerfiles/single.Dockerfile') - - if DRY_RUN - TaskHelpers.info("gitlab-docs", "DRY RUN: Not creating file #{dockerfile}.") - elsif File.exist?(dockerfile) && ask("#{dockerfile} already exists. Do you want to overwrite?", %w[y n]) == 'n' - abort('rake aborted!') - else - TaskHelpers.info("gitlab-docs", "Creating file #{dockerfile}...") - dockerfile.open('w') do |post| - post.write(single_dockerfile.read.gsub('ARG VER', "ARG VER=#{version}")) - end - end - - if DRY_RUN - TaskHelpers.info("gitlab-docs", "DRY RUN: Not adding file #{dockerfile} to branch #{version} or commiting changes.") - else - TaskHelpers.info("gitlab-docs", "Adding file #{dockerfile} and commiting changes to branch #{version}...") - `git add #{version}.Dockerfile` - `git commit -m 'Release cut #{version}'` + begin + Release.new.single + rescue StandardError => e + abort(error_format('gitlab-docs', e.message)) end + end - if DRY_RUN - TaskHelpers.info("gitlab-docs", "DRY RUN: Not pushing branch #{version}.") - else - TaskHelpers.info("gitlab-docs", "Pushing branch #{version}. Don't create a merge request...") - `git push origin #{version}` - end + desc 'Updates the versions dropdown JSON file' + task :update_versions_dropdown do + Release.new.update_versions_dropdown end end diff --git a/lib/tasks/task_helpers.rb b/lib/tasks/task_helpers.rb index 7c33a3d3..28e99377 100644 --- a/lib/tasks/task_helpers.rb +++ b/lib/tasks/task_helpers.rb @@ -10,7 +10,22 @@ class TaskHelpers COLOR_CODE_RESET = "\e[0m" COLOR_CODE_RED = "\e[31m" COLOR_CODE_GREEN = "\e[32m" - CURRENT_RELEASE_DATE = Date.today.strftime("%Y-%m-22") + + module Output + def info(slug, message) + puts "#{COLOR_CODE_GREEN}INFO: (#{slug}): #{message} #{COLOR_CODE_RESET}" + end + + def error(slug, message) + puts error_format(slug, message) + end + + def error_format(slug, message) + "#{COLOR_CODE_RED}ERROR: (#{slug}): #{message} #{COLOR_CODE_RESET}" + end + end + + include Output def config # Parse the config file and create a hash. @@ -128,16 +143,9 @@ class TaskHelpers `curl --silent https://gitlab.com/api/v4/projects/#{url_encoded_path} | jq --raw-output .default_branch`.tr("\n", '') end - def self.info(slug, message) - puts "#{TaskHelpers::COLOR_CODE_GREEN}INFO: (#{slug}): #{message} #{TaskHelpers::COLOR_CODE_RESET}" - end - - def current_milestone - @current_milestone ||= begin - release_dates_json = File.read("#{project_root}/content/release_dates.json") - # Search in the relase dates hash for the upcoming release date - # and fetch the milestone title. - JSON.parse(release_dates_json).first[CURRENT_RELEASE_DATE] - end + # Search in the relase dates hash for the release date + # and fetch the milestone title. The date must be in the format of "<year>-<month>-22". + def milestone(date) + JSON.load_file!("#{project_root}/content/release_dates.json").first[date] end end |