diff options
-rw-r--r-- | README.md | 40 | ||||
-rw-r--r-- | Rakefile | 142 | ||||
-rw-r--r-- | lib/task_helpers.rb | 2 | ||||
-rw-r--r-- | nanoc.yaml | 4 |
4 files changed, 184 insertions, 4 deletions
@@ -45,7 +45,7 @@ To preview any changes you make to GitLab documentation, you need: - [`.tool-versions`](.tool-versions) - Node.js, at the version specified in [`.tool-versions`](.tool-versions). - Yarn, at the version specified in [`.tool-versions`](.tool-versions). -- [jq](https://stedolan.github.io/jq/), needed by some Rake tasks. +- [jq](https://stedolan.github.io/jq/), needed by some [Rake tasks](#rake-tasks). - Xcode *(macOS only)*: - Run `xcode-select --install` to install the command line tools only. - Or download and install the entire package using the macOS's App Store. @@ -575,7 +575,16 @@ it with: To test that the CSP header works as expected, you can visit <https://cspvalidator.org/> and paste the URL that you want tested. -## Generate the feature flag tables +## Rake Tasks + +The GitLab Docs project has some raketasks that automate various things. You +can see the list of rake tasks with: + +```shell +bundle exec rake -T +``` + +### Generate the feature flag tables The [feature flag tables](https://docs.gitlab.com/ee/user/feature_flags.html) are generated dynamically when GitLab Docs are published. @@ -590,6 +599,33 @@ Do this any time you want fresh data from your GitLab checkout. Any time you rebuild the site using `nanoc`, the feature flags tables are populated with data. +### Clean up redirects + +The `docs:clean_redirects` rake task automates the removal of the expired +redirect files, which is part of the monthly +[scheduled TW tasks](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#regularly-scheduled-tasks) +as seen in the "Local tasks" section of the [issue template](https://gitlab.com/gitlab-org/technical-writing/-/blob/main/.gitlab/issue_templates/tw-monthly-tasks.md): + +```shell +bundle exec rake docs:clean_redirects +``` + +The task: + +1. Searches the doc files of each upstream product and: + 1. Checks the `remove_date` defined in the YAML front matter. If the + `remove_date` is before the day you run the task, it removes the doc + and updates `content/_data/redirects.yaml`. + 1. Creates a branch, commits the changes, and pushes the branch with + various push options to automatically create the merge request. +1. When all the upstream products MRs have been created, it creates a branch + in the `gitlab-docs` repository, adds the changed `content/_data/redirects.yaml`, + and pushes the branch with various push options to automatically create the + merge request. + +Once all the MRs have been created, be sure to edit them to cross link between +them and the recurring tasks issue. + ## Troubleshooting If you see a `Nanoc::Core::Site::DuplicateIdentifierError` error, confirm you have no symlinks @@ -186,7 +186,7 @@ namespace :release do puts "=> Commit and push to create a merge request" `git commit -m "Update dropdown to #{current_version}"` - `git push origin #{branch_name} -o merge_request.create -o merge_request.target=#{version} -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="release"` + `git push origin #{branch_name} -o merge_request.create -o merge_request.target=#{version} -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="release"` end end end @@ -235,3 +235,143 @@ task :redirects do end end end + +# +# https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page +# +namespace :docs do + require 'date' + require 'pathname' + require "yaml" + desc 'GitLab | Docs | Clean up old redirects' + task :clean_redirects do + source_dir = File.expand_path(__dir__) + redirects_yaml = "#{source_dir}/content/_data/redirects.yaml" + today = Time.now.utc.to_date + mr_title = "Clean up docs redirects - #{today}" + mr_description = "Monthly cleanup of docs redirects.</br><p>See https://about.gitlab.com/handbook/engineering/ux/technical-writing/#regularly-scheduled-tasks</p></br></hr></br><p>_Created automatically: https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/README.md#clean-up-redirects_</p>" + + products.each_value do |product| + # + # Calculate new path from the redirect URL. + # + # If the redirect is not a full URL: + # 1. Create a new Pathname of the file + # 2. Use dirname to get all but the last component of the path + # 3. Join with the redirect_to entry + # 4. Substitute: + # - '.md' => '.html' + # - 'doc/' => '/ee/' + # + # If the redirect URL is a full URL pointing to the Docs site + # (cross-linking among the 4 products), remove the FQDN prefix: + # + # From : https://docs.gitlab.com/ee/install/requirements.html + # To : /ee/install/requirements.html + # + def new_path(redirect, filename, content_dir, slug) + if !redirect.start_with?('http') + Pathname.new(filename).dirname.join(redirect).to_s.gsub(/\.md/, '.html').gsub(content_dir, "/#{slug}") + elsif redirect.start_with?('https://docs.gitlab.com') + redirect.gsub('https://docs.gitlab.com', '') + else + redirect + end + end + + content_dir = product['content_dir'] + next unless Dir.exist?(content_dir) + + default_branch = default_branch(product['repo']) + slug = product['slug'] + counter = 0 + + Dir.chdir(content_dir) + puts "=> (#{slug}): Stashing changes of #{slug} and syncing with upstream default branch" + system("git stash --quiet -u") if git_workdir_dirty? + system("git checkout --quiet #{default_branch}") + system("git fetch --quiet origin #{default_branch}") + system("git reset --quiet --hard origin/#{default_branch}") + Dir.chdir(source_dir) + + # + # Find the files to be deleted. + # Exclude 'doc/development/documentation/index.md' because it + # contains an example of the YAML front matter. + # + files_to_be_deleted = `grep -Ir 'remove_date:' #{content_dir} | grep -v doc/development/documentation/index.md | cut -d ":" -f1`.split("\n") + + # + # Iterate over the files to be deleted and print the needed + # YAML entries for the Docs site redirects. + # + files_to_be_deleted.each do |filename| + frontmatter = YAML.safe_load(File.read(filename)) + remove_date = Date.parse(frontmatter['remove_date']) + old_path = filename.gsub(/\.md/, '.html').gsub(content_dir, "/#{slug}") + + # + # Check if the removal date is before today, and delete the file and + # print the content to be pasted in + # https://gitlab.com/gitlab-org/gitlab-docs/-/blob/master/content/_data/redirects.yaml. + # The remove_date of redirects.yaml should be nine months in the future. + # To not be confused with the remove_date of the Markdown page. + # + next unless remove_date < today + + counter += 1 + + File.delete(filename) if File.exist?(filename) + File.open(redirects_yaml, 'a') do |post| + post.puts " - from: #{old_path}" + post.puts " to: #{new_path(frontmatter['redirect_to'], filename, content_dir, slug)}" + post.puts " remove_date: #{remove_date >> 9}" + end + end + + # + # If more than one files are found: + # + # 1. cd into each repository + # 2. Create a redirects branch + # 3. Add the changed files + # 4. Commit and push the branch to create the MR + # + next unless counter.positive? + + redirects_branch = "clean-docs-redirects-#{slug}-#{today}" + + puts "=> (#{slug}): Found #{counter} redirect(s)" + Dir.chdir(content_dir) + puts "=> (#{slug}): Creating a new branch for the redirects MR" + system("git checkout --quiet -b #{redirects_branch} origin/#{default_branch}") + puts "=> (#{slug}): Committing and pushing to create a merge request" + system("git add .") + system("git commit --quiet -m 'Update docs redirects #{today}'") + `git push 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"` if ENV['SKIP_MR'].nil? + Dir.chdir(source_dir) + puts + end + + # + # Finally, create the gitlab-docs MR + # + # 1. Create a redirects branch + # 2. Add the changed files + # 3. Commit and push the branch to create the MR + # + redirects_branch = "clean-docs-redirects-#{today}" + + puts "=> (gitlab-docs): Stashing changes of gitlab-docs and syncing with upstream default branch" + system("git stash --quiet -u") if git_workdir_dirty? + system("git checkout --quiet main") + system("git fetch --quiet origin main") + system("git reset --quiet --hard origin/main") + puts "=> (gitlab-docs): Creating a new branch for the redirects MR" + system("git checkout --quiet -b #{redirects_branch} origin/main") + puts "=> (gitlab-docs): Committing and pushing to create a merge request" + system("git add #{redirects_yaml}") + system("git commit --quiet -m 'Update docs redirects #{today}'") + `git push 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"` if ENV['SKIP_MR'].nil? + end +end diff --git a/lib/task_helpers.rb b/lib/task_helpers.rb index 358169b4a..85a53c959 100644 --- a/lib/task_helpers.rb +++ b/lib/task_helpers.rb @@ -69,5 +69,5 @@ def default_branch(repo) # https://docs.gitlab.com/ee/api/README.html#namespaced-path-encoding url_encoded_path = repo.sub('https://gitlab.com/', '').sub('.git', '').gsub('/', '%2F') - `curl https://gitlab.com/api/v4/projects/#{url_encoded_path} | jq --raw-output .default_branch`.tr("\n", '') + `curl --silent https://gitlab.com/api/v4/projects/#{url_encoded_path} | jq --raw-output .default_branch`.tr("\n", '') end diff --git a/nanoc.yaml b/nanoc.yaml index ccae7b694..4486a3e83 100644 --- a/nanoc.yaml +++ b/nanoc.yaml @@ -125,15 +125,19 @@ products: slug: 'ee' repo: 'https://gitlab.com/gitlab-org/gitlab.git' project_dir: '../gitlab' + content_dir: '../gitlab/doc' runner: slug: 'runner' repo: 'https://gitlab.com/gitlab-org/gitlab-runner.git' project_dir: '../gitlab-runner' + content_dir: '../gitlab-runner/docs' omnibus: slug: 'omnibus' repo: 'https://gitlab.com/gitlab-org/omnibus-gitlab.git' project_dir: '../omnibus-gitlab' + content_dir: '../omnibus-gitlab/doc' charts: slug: 'charts' repo: 'https://gitlab.com/gitlab-org/charts/gitlab.git' project_dir: '../charts-gitlab' + content_dir: '../charts-gitlab/doc' |