#206 Outreachy: My ideas for redesigning and Improving Fedora docs experience
Opened 2 years ago by khushi. Modified 2 years ago
fedora-docs/ khushi/docs-fp-o prod  into  master

Add package maintainers
Otto Urpelainen • 2 years ago  
Move eln-docs to GitHub
Aleksandra Fedorova • 3 years ago  
Publish PgM docs to prod
Ben Cotton • 4 years ago  
file modified
+1
@@ -1,3 +1,4 @@ 

  build

  public

  cache

+ build-scripts/output

file modified
+3 -3
@@ -1,9 +1,9 @@ 

- FROM fedora:29

+ FROM fedora:34

  

- RUN dnf -y module install nodejs:10 && \

+ RUN dnf -y module install nodejs:16 && \

      dnf clean all

  

- RUN npm i -g @antora/cli@2.0 @antora/site-generator-default@2.0

+ RUN npm i -g @antora/cli@3.0.0 @antora/site-generator-default@3.0.0

  

  WORKDIR /antora

  ENTRYPOINT [ "antora" ]

file modified
+6 -6
@@ -1,13 +1,13 @@ 

- FROM fedora:29

+ FROM fedora:34

  

- RUN dnf -y module install nodejs:10/default && \

-     dnf -y install git && \

+ RUN dnf -y module install nodejs:16 && \

+     dnf -y install git python3-yaml && \

      dnf clean all

  

- RUN npm i -g @antora/cli@2.0 @antora/site-generator-default@2.0

+ RUN npm i -g @antora/cli@3.0.0 @antora/site-generator@3.0.0

  

- ADD rebuild-site.sh /antora/rebuild-site.sh

+ ADD rebuild-site.py /antora/rebuild-site.py

  

  WORKDIR /antora

  

- CMD /antora/rebuild-site.sh

+ CMD /antora/rebuild-site.py

file modified
+41 -2
@@ -1,7 +1,46 @@ 

  # Building the docs

  

+ This script is used in OpenShift to rebuild the whole site for Fedora.

+ 

+ 

+ ## Local testing

+ 

+ Test the build locally using podman.

+ 

+ First, make sure your in the right directory — it's the same one that has this *README.md* file. Then build the container on your system:

+ 

+ ```

+ $ podman build --no-cache -t fedora-docs-openshift-rebuild . 

+ ```

+ 

+ And then run it:

+ 

+ ```

+ $ mkdir output

+ $ podman run --rm -it -e "BUILD_ENV=prod" -v $(pwd)/output:/antora/output:Z fedora-docs-openshift-rebuild

+ ```

+ 

+ The output will be saved in `./output/`.

+ 

+ ### Changing configuration

+ 

+ You can also set different environment variables by setting `-e "VAR_NAME=value"` in the `podman run` command.

+ See a list of supported variables below.

+ 

  ```

- docker run --rm -it -e "BUILD_ENV=stg" -v $(pwd)/output:/antora/output antora-openshift-rebuild

+ # The script requires the following environment variables to be set:

+ # 

+ # Variable          Values      Effect

+ # -----------------|-----------------------------------------------------------

+ # BUILD_ENV         prod        Build the production version of the site

+ #                               using the "prod" branch. DEFAULT

+ #                   stg         Build the staging version of the site

+ #                               using the "stg" branch.

+ # -----------------|-----------------------------------------------------------

+ # BUILD_LANGS       english     Build the "en-US" version only. DEFAULT

+ #                   translated  Build only the translated versions.

+ #                   all         Build the "en-US" and the translated versions.

  ```

  

- The output will be in `./output/`.

+ Please note that rebuilding all the languages locally will take many hours and results in gigabytes of output.

+ 

@@ -0,0 +1,572 @@ 

+ #!/usr/bin/python3

+ 

+ 

+ # The script requires the following environment variables to be set:

+ # 

+ # Variable          Values      Effect

+ # -----------------|-----------------------------------------------------------

+ # BUILD_ENV         prod        Build the production version of the site

+ #                               using the "prod" branch. DEFAULT

+ #                   stg         Build the staging version of the site

+ #                               using the "stg" branch.

+ # -----------------|-----------------------------------------------------------

+ # BUILD_LANGS       english     Build the "en-US" version only. DEFAULT

+ #                   translated  Build only the translated versions.

+ #                   all         Build the "en-US" and the translated versions.

+ #

+ #

+ 

+ 

+ import tempfile

+ import yaml

+ import os

+ import errno

+ import subprocess

+ import copy

+ import datetime

+ import shutil

+ import sys

+ import glob

+ import re

+ 

+ 

+ def get_config():

+     config = {}

+ 

+     config["docs_repo_branch"] = os.getenv(

+         "BUILD_ENV",

+         "prod")

+ 

+     config["build_langs"] = os.getenv(

+         "BUILD_LANGS",

+         "english")

+ 

+     config["docs_repo_url"] = os.getenv(

+         "DOCS_REPO_URL",

+         "https://pagure.io/fedora-docs/docs-fp-o.git")

+ 

+     config["translated_sources_repo_url"] = os.getenv(

+         "TRANSLATED_SOURCES_REPO_URL",

+         "https://pagure.io/fedora-docs/translated-sources.git"

+     )

+ 

+     config["translated_adockeywords_repo_url"] = os.getenv(

+         "TRANSLATED_ADOCKEYWORDS_REPO_URL",

+         "https://pagure.io/fedora-docs-l10n/asciidoc-keywords.git")

+     

+     os.environ['CI'] = "true"

+ 

+     return config

+ 

+ 

+ def log(msg):

+     print(msg, flush=True)

+ 

+ 

+ def get_languages(config):

+     languages_dict = {}

+ 

+     with tempfile.TemporaryDirectory() as workdir:

+         translated_sources_repo = os.path.join(workdir, "translated_sources_repo")

+         subprocess.run(["git", "clone", "--depth=1", config["translated_sources_repo_url"], translated_sources_repo])

+ 

+         languages = []

+         filename_blacklist = [".git"]

+         for filename in os.listdir(translated_sources_repo):

+             filepath = os.path.join(translated_sources_repo, filename)

+             if os.path.isdir(filepath) and filename not in filename_blacklist:

+                 languages.append(filename)

+ 

+         languages.sort()

+ 

+         for lang in languages:

+             languages_dict[lang] = []

+ 

+             lang_dir = os.path.join(translated_sources_repo, lang)

+             for component in os.listdir(lang_dir):

+                 version_dir = os.path.join(lang_dir, component)

+                 for version in os.listdir(version_dir):

+                     start_path = "{lang}/{component}/{version}".format(

+                             lang=lang, component=component, version=version)

+ 

+                     # This is a workaround for cases when a component doesn't have

+                     # the ROOT module that should contain the antora.yml.

+                     # Without the ROOT module the translation scripts won't

+                     # pick up the antora.yml causing the docs build to fail.

+                     # So we're only including directories with the antora.yml file.

+                     if "antora.yml" in os.listdir(os.path.join(version_dir, version)):

+                         languages_dict[lang].append(start_path)

+ 

+     return languages_dict

+ 

+ 

+ def generate_lang_switch_ui(languages):

+     template_start = """

+         <div class="page-languages">

+             <button class="languages-menu-toggle" title="Show other languages of the site">

+                 {{{env.ANTORA_LANGUAGE}}}

+             </button>

+             <div class="languages-menu">

+     """

+     template_end = """

+             </div>

+         </div>

+     """

+ 

+     template_list = []

+     template_list.append(template_start)

+     for language in languages:

+         link = '<a class="language" href="{{{{siteRootPath}}}}/../{language}{{{{page.url}}}}">{language}</a>'.format(

+                     language=language)

+         template_list.append(link)

+     template_list.append(template_end)

+ 

+     return "\n".join(template_list)

+ 

+ def get_metadata_from_branch(branch, repodir):

+     cmd = f"""

+       for file in $(git ls-tree -r --name-only origin/{branch}|grep -E "adoc$"); do 

+         git log -1 --format="'$file':%n  refs: %S%n  hash: %h%n  date: %as" origin/{branch} -- $file;

+       done"""

+     s = subprocess.run(cmd, shell=True, cwd=repodir,  stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

+     return yaml.safe_load(s.stdout)

+ 

+ def prefetch_sources(original_sources, site_yml, config):

+     if not os.path.isdir(original_sources):

+         os.mkdir(original_sources)

+ 

+     default_branch = site_yml["content"].get("branches", ["master"])

+     if type(default_branch) is str:

+         default_branch = [default_branch]

+ 

+     metadata = {}

+ 

+     for repo_data in site_yml["content"]["sources"]:

+       gitdir = tempfile.TemporaryDirectory(dir=original_sources)

+       dirname = gitdir.name

+       gitdir.cleanup()

+       log(f"Fetching {repo_data['url']}...")

+       subprocess.run(["git", "clone", repo_data['url'], dirname])

+       repo_data['url'] = dirname

+ 

+       branches = repo_data.get("branches", default_branch)

+       if type(branches) is str:

+         branches = [branches]

+ 

+       for branch in branches:

+         y = get_metadata_from_branch(branch, repo_data['url'])

+         if dirname in metadata:

+           metadata[dirname][branch] = y

+         else:

+           metadata[dirname] = { branch: y }

+ 

+     if metadata:

+       with open("/tmp/metadata.yml", "w") as f:

+         yaml.dump(metadata, f)

+ 

+     return site_yml

+ 

+ def prepare_translated_sources(translated_sources, site_yml, languages, config):

+     with tempfile.TemporaryDirectory() as workdir:

+         # Location of the translated-sources repo

+         #   (This repo only holds content that has some translations done,

+         #   so it might be incomplete.)

+         translated_sources_original = os.path.join(workdir, "translated_sources_original")

+ 

+         # Location of the English sources in the same structure

+         # as translated-sources, so:

+         #    COMPONENT/VERSION/antora.yml

+         #    COMPONENT/VERSION/modules/MODULE1

+         #    COMPONENT/VERSION/modules/MODULE2

+         #    COMPONENT/VERSION/modules/...

+         en_sources = os.path.join(workdir, "en_sources")

+ 

+         # Clone the original translated-sources

+         subprocess.run(["git", "clone", "--depth=1", config["translated_sources_repo_url"], translated_sources_original])

+ 

+         # Get a list of the original English repos

+         repos = []

+         default_branch = site_yml["content"].get("branches", ["master"])

+         if type(default_branch) is str:

+             default_branch = [default_branch]

+ 

+         for repo_data in site_yml["content"]["sources"]:

+ 

+             branches = repo_data.get("branches", default_branch)

+             if type(branches) is str:

+                 branches = [branches]

+ 

+             start_path = repo_data.get("start_path", "")

+ 

+             for branch in branches:

+                 repo = {}

+                 repo["url"] = repo_data["url"]

+                 repo["branch"] = branch

+                 repo["start_path"] = start_path

+ 

+                 repos.append(repo)

+         

+         # Clome the original English sources and put them into the

+         # desired structure in en_sources (described above)

+         components = {}

+         for repo in repos:

+             with tempfile.TemporaryDirectory() as tmp_repo_root:

+                 log("")

+                 log("Cloning {url} {branch}".format(url=repo["url"], branch=repo["branch"]))

+                 subprocess.run(["git", "clone", "--branch", repo["branch"], "--depth=1", repo["url"], tmp_repo_root])

+ 

+                 repo_dir = os.path.join(tmp_repo_root, repo["start_path"])

+                 antora_yml_file = os.path.join(repo_dir, "antora.yml")

+                 with open(antora_yml_file, "r") as file:

+                     antora_yml = yaml.safe_load(file)

+ 

+                 component = antora_yml["name"]

+                 version = antora_yml["version"]

+                 # if component version is null (~), fallback to "master"

+                 if not version:

+                     version = "master"

+ 

+                 # Saving components and all their versions

+                 if component not in components:

+                     components[component] = set()

+                 components[component].add(version)

+ 

+                 for module in os.listdir(os.path.join(repo_dir, "modules")):

+                     # Now this is looping over modules accross all components,

+                     # so component, module, and version variables are available

+ 

+                     try:

+                         os.makedirs(os.path.join(en_sources, component, version, "modules"))

+                     except OSError as e:

+                         if e.errno != errno.EEXIST:

+                             raise

+                     

+                     original_module_dir = os.path.join(repo_dir, "modules", module)

+                     module_dir = os.path.join(en_sources, component, version, "modules", module)

+ 

+                     subprocess.run(["cp", "-a", original_module_dir, module_dir])

+ 

+                     if module == "ROOT" or "nav" in antora_yml:

+                         # if this is the main antora.yml file

+                         subprocess.run(["cp", "-a", antora_yml_file, os.path.join(en_sources, component, version, "antora.yml")])

+                         log("----- copying antora.yml for  {component} {module} {version}".format(

+                                 component=component, module=module, version=version))

+                     else:

+                         log("----- skipping antora.yml for  {component} {module} {version}".format(

+                                 component=component, module=module, version=version))

+ 

+         # Set up the language structure in translated_sources

+         for language in languages:

+             lang_dir = os.path.join(translated_sources, language)

+             try:

+                 os.makedirs(lang_dir)

+             except OSError as e:

+                 if e.errno != errno.EEXIST:

+                     raise

+         

+         # Copy the English sources in the translated_sources

+         for language in languages:

+             lang_dir = os.path.join(translated_sources, language)

+             for component in components:

+                 en_component_dir = os.path.join(en_sources, component)

+                 subprocess.run(["cp", "-a", en_component_dir, lang_dir])

+ 

+         # And finally copy the original translated sources

+         # into translated_sources

+         for language in languages:

+             src = os.path.join(translated_sources_original, language)

+             subprocess.run(["cp", "-a", src, translated_sources + "/"])

+ 

+     return components

+ 

+ 

+ def prepare_localized_admonitions(languages, config):

+     """ Asciidoc use keywords for admonitions and others items """

+     keywords = {}

+ 

+     with tempfile.TemporaryDirectory() as workdir:

+         translated_keywords_repo = os.path.join(workdir, "asciidoc-keywords")

+         subprocess.run(["git", "clone", "--depth=1", config["translated_adockeywords_repo_url"], translated_keywords_repo])

+ 

+         languages = []

+         log(translated_keywords_repo + "/langs/*/asciidoc-attributes.yml")

+         for filename in glob.glob(translated_keywords_repo + "/langs/*/asciidoc-attributes.yml"):

+             languages.append(filename.rsplit("/")[::-1][1])

+ 

+         for lang in languages:

+             file = translated_keywords_repo + "/langs/" + lang + "/asciidoc-attributes.yml"

+             with open(file, 'r') as stream:

+                 try:

+                     keywords[lang] = yaml.load(stream)

+                 except yaml.YAMLError as exc:

+                     print(exc)

+ 

+     return keywords

+ 

+ 

+ def init_git_repo(path):

+     try:

+         os.makedirs(path)

+     except OSError as e:

+         if e.errno != errno.EEXIST:

+             raise

+     subprocess.run(["git", "init"], cwd=path)

+     subprocess.run(["git", "config", "user.name", "Your Name"], cwd=path)

+     subprocess.run(["git", "config", "user.email", "you@example.com"], cwd=path)

+     subprocess.run(["git", "commit", "--allow-empty", "-m", "init"], cwd=path)

+ 

+ def get_version_from_file(index_file):

+     latest = None

+     if os.path.isfile(index_file):

+       with open(index_file, 'r') as f:

+         for l in f:

+           m = re.search(r'data-version="(f\d+)"', l)

+           if m:

+             latest = m[1]

+             break

+     return latest

+ 

+ 

+ def gen_redirect(lang, results_dir):

+     htaccess = os.path.join(results_dir, ".htaccess")

+     latest = get_version_from_file(f"{results_dir}/fedora/latest/index.html")

+     if latest:

+       htaccess_content = f"""

+         ErrorDocument 404 /{lang}/404.html

+         Redirect 302 /{lang}/fedora/{latest} /{lang}/fedora/latest

+         """

+       with open(htaccess, "w") as file:

+           file.write(htaccess_content)

+ 

+ def main():

+     config = get_config()

+     

+     with tempfile.TemporaryDirectory() as workdir:

+ 

+         #####--------------------------------------#####

+         #####  Preparation                         #####

+         #####--------------------------------------#####

+ 

+         # Location of the docs-fp-o repo

+         docs_repo = os.path.join(workdir, "docs_repo")

+ 

+         # Location of the translated sources used for the build

+         #   (That's the translated-sources repo with the missing files added

+         #   from the English sources.)

+         translated_sources = os.path.join(workdir, "translated_sources")

+         init_git_repo(translated_sources)

+ 

+         log("")

+         log("===== Getting the site definition (site.yml) =====")

+         subprocess.run(["git", "clone", "--branch", config["docs_repo_branch"], "--depth=1", config["docs_repo_url"], docs_repo])

+ 

+         with open(os.path.join(docs_repo, "site.yml"), "r") as file:

+             original_site_yml = yaml.safe_load(file)

+ 

+         log("")

+         log("===== Getting a list of languages =====")

+         languages = get_languages(config)

+         log("  Languages: {}".format(" ".join(languages)))

+ 

+         log("")

+         log("===== Generating the language switch UI =====")

+         lang_switch_ui = generate_lang_switch_ui(["en-US"] + list(languages.keys()))

+ 

+         ui_dir = os.path.join(docs_repo, "supplemental-ui", "partials")

+         try:

+             os.makedirs(ui_dir)

+         except OSError as e:

+             if e.errno != errno.EEXIST:

+                 raise

+ 

+         ui_file = os.path.join(ui_dir, "page-languages.hbs")

+         with open(ui_file, "w") as file:

+             file.write(lang_switch_ui)

+ 

+         # Timestamp to be included in the footer of the docs

+         timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')

+         antora_env = copy.deepcopy(os.environ)

+         antora_env["ANTORA_DATE"] = timestamp

+ 

+ 

+ 

+         #####--------------------------------------#####

+         #####  English site build                  #####

+         #####--------------------------------------#####

+ 

+         if config["build_langs"] == "english" or config["build_langs"] == "all":

+ 

+             log("")

+             log("===== Prefetching all components =====")

+             original_sources = os.path.join(workdir, "orginal_sources")

+             site_local = prefetch_sources(original_sources, original_site_yml, config)

+             log(original_site_yml["content"]["sources"][0]['url'])

+             log(site_local["content"]["sources"][0]['url'])

+ 

+             filename = os.path.join(docs_repo, "site-local.yml")

+             with open(filename, "w") as file:

+                 file.write(yaml.dump(site_local))

+ 

+             

+ 

+             log("")

+             log("===== Building the en-US site =====")

+             antora_env["ANTORA_LANGUAGE"] = "en-US"

+             # result = subprocess.run(["antora", "--html-url-extension-style=indexify", os.path.join(docs_repo, "site.yml")], env=antora_env)

+             result = subprocess.run(["antora", "--html-url-extension-style=indexify", filename], env=antora_env)

+ 

+             if result.returncode != 0:

+                 log("ERROR building the en-US site")

+                 sys.exit(1)

+                 

+             log("")

+             log("===== Copying the en-US site =====")

+             source_dir = os.path.join(docs_repo, "public")

+             target_dir_copying = "/antora/output/en-US.building"

+             target_dir_copied = "/antora/output/en-US.building/en-US"

+             target_dir_final = "/antora/output/en-US"

+ 

+             # Generate htaccess for redirect

+             gen_redirect("en-US", os.path.join(source_dir, "en-US"))

+ 

+             shutil.rmtree(target_dir_copying, ignore_errors=True)

+             subprocess.run(["cp", "-a", source_dir, target_dir_copying])

+             shutil.rmtree(target_dir_final, ignore_errors=True)

+             shutil.move(target_dir_copied, target_dir_final)

+             shutil.rmtree(target_dir_copying, ignore_errors=True)

+ 

+             log("")

+             log("===== Copying the index.html =====")

+             source_index_html = os.path.join(docs_repo, "static", "index.html")

+             target_index_html = "/antora/output/index.html"

+             shutil.copy(source_index_html, target_index_html)

+ 

+ 

+ 

+         #####--------------------------------------#####

+         #####  Translated site build               #####

+         #####--------------------------------------#####

+ 

+ 

+         if config["build_langs"] == "translated" or config["build_langs"] == "all":

+ 

+             log("")

+             log("===== Preparing the translated sources =====")

+             components = prepare_translated_sources(translated_sources, original_site_yml, languages, config)

+ 

+             log("")

+             log("===== Preparing the translated ascidoc keywords =====")

+             keywords = prepare_localized_admonitions(languages, config)

+ 

+             log("")

+             log("===== Generating site.lang.yml files =====")

+             for lang in languages:

+                 lang_site_yml = copy.deepcopy(original_site_yml)

+ 

+                 lang_site_yml["output"]["dir"] = "./public/{lang}".format(lang=lang)

+ 

+                 lang_site_yml["content"] = {}

+                 # Branches are set to HEAD because the script uses a locally-generated

+                 # content on top of the original translated-sources repo

+                 lang_site_yml["content"]["branches"] = "HEAD"

+                 # disable the "Edit this Page"

+                 lang_site_yml["content"]["edit_url"] = False

+                 lang_site_yml["content"]["sources"] = []

+ 

+                 for component, versions in components.items():

+                     for version in versions:

+                         source = {}

+                         source["url"] = translated_sources

+                         source["start_path"] = "{lang}/{component}/{version}".format(

+                                     lang=lang, component=component, version=version)

+ 

+                         lang_site_yml["content"]["sources"].append(source)

+ 

+                 if lang in keywords:

+                     if "attributes" in lang_site_yml["asciidoc"]:

+                         lang_site_yml["asciidoc"]["attributes"].append(keywords[lang])

+                     else:

+                         lang_site_yml["asciidoc"]["attributes"] = keywords[lang]

+ 

+                 # disable page-last-update extension 

+                 if "antora" in lang_site_yml and "extensions" in lang_site_yml["antora"]:

+                   for ext in lang_site_yml["antora"]["extensions"]:

+                     if 'id' in ext and ext['id'] == "page-last-update":

+                       ext['enabled'] = False

+ 

+                 filename = os.path.join(docs_repo, "site-{lang}.yml".format(lang=lang))

+                 with open(filename, "w") as file:

+                     file.write(yaml.dump(lang_site_yml))

+ 

+                 log("  {lang} done".format(lang=lang))

+ 

+             # Building all the translated sites

+             lastlang = list(languages)[-1]

+             for lang in languages:

+                 log("")

+                 log("===== Building the {lang} site =====".format(lang=lang))

+                 filename = "site-{lang}.yml".format(lang=lang)

+                 antora_env["ANTORA_LANGUAGE"] = lang

+                 result = subprocess.run(["antora", "--html-url-extension-style=indexify", os.path.join(docs_repo, filename)], env=antora_env)

+ 

+                 if result.returncode != 0:

+                     log("ERROR building the {lang} site".format(lang=lang))

+                     sys.exit(1)

+ 

+                 # Copying the translated site

+                 log("")

+                 log(f"=== Copying the {lang} site ===")

+ 

+                 results_dir = os.path.join(docs_repo, "public", lang)

+                 publish_dir = f"/antora/output/{lang}"

+                 copying_dir = f"/antora/output/{lang}.tmp"

+                 lastlang_dir = f"/antora/output/{lastlang}"

+ 

+                 # I have:

+                 # docs_repo/public/xx         <- results_dir  (local partition)

+                 # /antora/output/xx.tmp       <- copying_dir  (mounted partition)

+                 # /antora/output/xx           <- publish_dir  (mounted partition)

+                 #

+                 # I need to:

+                 #   1/  copy from local to mounted

+                 #   2/  remove old in mounted

+                 #   3/  move new within mounted

+                 #   4/  remove the copying dir

+ 

+                 # Generate htaccess for redirect

+                 gen_redirect(lang, results_dir)

+ 

+                 # Make sure copying_dir doesn't exist

+                 shutil.rmtree(copying_dir, ignore_errors=True)

+ 

+                 # Copy results from local partition to a mounted partition

+                 log(f"Copying from {results_dir} to {copying_dir}")

+                 subprocess.run(["cp", "-a", results_dir, copying_dir])

+ 

+                 # Swap the old tree for the new one for each language

+                 log(f"Moving language to the final place: {copying_dir} to {publish_dir}")

+                 shutil.rmtree(publish_dir, ignore_errors=True)

+                 subprocess.run(["mv", copying_dir, publish_dir])

+ 

+                 # Recreate hardlinks as we go, in case the rsync job

+                 # start while we are still building

+                 if (lang != lastlang):

+                     log(f"hardlinking files: {publish_dir} - {lastlang_dir}")

+                     subprocess.run(["hardlink", "-cv", publish_dir, lastlang_dir])

+ 

+                 # Remove local build

+                 shutil.rmtree(results_dir, ignore_errors=True)

+ 

+             # End Building all the translated sites

+ 

+             # https://pagure.io/fedora-infrastructure/issue/8964

+             log("Consolidate files with hardlink...")

+             subprocess.run(["hardlink", "-cv", "/antora/output/"])

+ 

+             log("DONE!")

+     

+ 

+ 

+ if __name__ == "__main__":

+     main()

+ 

@@ -1,59 +0,0 @@ 

- #/bin/bash

- 

- echo ""

- echo "$(date +%G-%m-%d-%H%M%S): Building Fedora Docs..."

- echo ""

- 

- SOURCE_REPO="https://pagure.io/fedora-docs/docs-fp-o.git"

- BUILD_CMD="antora --html-url-extension-style=indexify site.yml"

- 

- target="/antora"

- 

- if [ -z ${BUILD_ENV+x} ]; then 

-     BUILD_ENV="master"   

- fi

- 

- 

- if ! workdir=$(mktemp -d) ; then

-     echo "Error creating a tempdir. Exiting."

-     exit 1

- fi

- 

- if ! git clone --single-branch --branch $BUILD_ENV  $SOURCE_REPO "$workdir/source" ; then

-     echo ""

-     echo "Error cloning the source repo."

-     rm -rf "$workdir"

-     exit 1

- else

-     echo "OK  cloned source repo"

- fi

- 

- if [ ! -f "$workdir/source/site.yml" ]; then

-     echo ""

-     echo "Error! There is no site.yml in the source."

-     rm -rf "$workdir"

-     exit 1

- fi

- 

- pushd "$workdir/source/" > /dev/null

- 

- 

- export ANTORA_DATE=$(date -u)

- 

- if ! $BUILD_CMD ; then

-     echo ""

-     echo "Error building the site."

-     rm -rf "$workdir"

-     exit 1

- fi

- 

- popd > /dev/null

- 

- cp -r "$workdir/source/public/en-US" "$target/output/en-US.building" && rm -rf "$target/output/en-US" && mv "$target/output/en-US.building" "$target/output/en-US" || exit 1

- cp "$workdir/source/static/index.html" "$target/output/index.html" || exit 1

- 

- rm -rf "$workdir"

- 

- echo ""

- echo "$(date +%G-%m-%d-%H%M%S): Building of Fedora Docs has finished successfully!"

- echo ""

file modified
+1 -1
@@ -1,6 +1,6 @@ 

  #!/bin/sh

  

- image="docker.io/antora/antora"

+ image="docker.io/antora/antora:3.0.0"

  cmd="--html-url-extension-style=indexify site.yml"

  

  if [ "$(uname)" == "Darwin" ]; then

@@ -0,0 +1,38 @@ 

+ 

+ module.exports.register = function () {

+   this.on('contentClassified', async ({ contentCatalog }) => {

+     const logger = this.require('@antora/logger').get('page-last-update')

+     const yaml = this.require('js-yaml')

+     const path = this.require('path')

+     const fs = this.require('fs')

+     const pages = contentCatalog.findBy({ family: 'page' })

+     const pageRx = new RegExp('modules/[^/]+/pages/(?:.+/)*[^.].*\.adoc$')

+ 

+     if (fs.existsSync("/tmp/metadata.yml")) {

+       let data = fs.readFileSync("/tmp/metadata.yml", "utf-8")

+       let y = yaml.loadAll(data)

+     

+       for (const page of pages) {

+         if (page.src.origin.type == "git" && pageRx.test(page.src.path)) {

+           const relpath = path.join(page.src.origin.startPath, page.src.path)

+           const abspath = page.src.origin.gitdir.replace(/\/\.git$/, "")

+           // logger.warn(abspath)

+           const contents = page.contents.toString('utf-8')

+           const branch = page.src.origin.branch

+           if (abspath in y[0] && branch in y[0][abspath] && relpath in y[0][abspath][branch]) {

+             let last_update = y[0][abspath][branch][relpath]["date"].toISOString().split('T')[0]

+             logger.warn({name: relpath, rev: branch, update: last_update})

+             

+             // Inject attribute in page content

+             const patchedContents = ":page-last-updated: " + last_update + "\n" + contents

+             page.contents = Buffer.from(patchedContents)

+           }

+         }

+       }

+ 

+     } else {

+       logger.warn("no git metadata found, skipping...")

+     }

+     this.updateVariables({ contentCatalog })

+   })

+ }

file modified
+86 -6
@@ -1,5 +1,5 @@ 

  site:

-   title: Fedora Docs Site

+   title: Fedora Docs

    url: https://docs.fedoraproject.org/en-US/

    start_page: docs::index.adoc

  content:
@@ -14,6 +14,11 @@ 

    - url: https://pagure.io/fedora-docs/release-docs-home.git

      branches:

      - master

+     - f35

+     - f34

+     - f33

+     - f32

+     - f31

      - f30

      - f29

      - f28
@@ -22,6 +27,11 @@ 

    - url: https://pagure.io/fedora-docs/install-guide.git

      branches:

      - master

+     - f35

+     - f34

+     - f33

+     - f32

+     - f31

      - f30

      - f29

      - f28
@@ -30,6 +40,11 @@ 

    - url: https://pagure.io/fedora-docs/system-administrators-guide.git

      branches:

      - master

+     - f35

+     - f34

+     - f33

+     - f32

+     - f31

      - f30

      - f29

      - f28
@@ -38,6 +53,11 @@ 

    - url: https://pagure.io/fedora-docs/release-notes.git

      branches:

      - master

+     - f35

+     - f34

+     - f33

+     - f32

+     - f31

      - f30

      - f29

      - f28
@@ -47,12 +67,24 @@ 

    - url: https://pagure.io/mentored-projects.git

    - url: https://pagure.io/fedora-commops.git

      start_path: docs

+     branches: main

+   - url: https://pagure.io/fedora-websites.git

+     start_path: docs

+     branches: main

    - url: https://pagure.io/Fedora-Council/council-docs.git

      start_path: council

+     branches: main

    - url: https://pagure.io/Fedora-Council/council-docs.git

      start_path: project

+     branches: main

+   - url: https://pagure.io/Fedora-Council/status_reports.git

+     branches: main

    - url: https://pagure.io/fedora-docs/modularity.git

+   - url: https://pagure.io/fedora-docs/package-maintainer-docs.git

+     branches: main

    - url: https://github.com/fedora-silverblue/silverblue-docs.git

+   - url: https://pagure.io/fedora-kde/kinoite-docs

+     branches: main

    - url: https://pagure.io/fedora-docs/documentation-contributors-guide.git

    - url: https://pagure.io/fedora-docs/flatpak.git

    - url: https://pagure.io/fedora-diversity.git
@@ -63,29 +95,77 @@ 

    - url: https://pagure.io/fesco/fesco-docs.git

      start_path: fesco

    - url: https://pagure.io/fedora-iot/iot-docs.git

-   - url: https://pagure.io/fedora-badges.git

-     start_path: docs

+   - url: https://pagure.io/fedora-badges/docs.git

    - url: https://pagure.io/fedora-docs/remix-building.git

    - url: https://github.com/containers/docs.git

+     branches: main

    - url: https://pagure.io/neuro-sig/documentation.git

+     branches: main

    - url: https://pagure.io/sig-teleirc/infrastructure.git

      start_path: docs

    - url: https://pagure.io/fedora-ci/docs.git

    - url: https://pagure.io/java-packaging-howto.git

-   - url: https://pagure.io/fedora-docs/taiga-docs.git

+   - url: https://pagure.io/fedora-magazine.git

+   - url: https://pagure.io/minimization.git

+   - url: https://github.com/coreos/fedora-coreos-docs.git

+     branches: main

+   - url: https://pagure.io/cpe/rawhide-gating-docs.git

+   - url: https://pagure.io/cpe/docs.git

+   - url: https://pagure.io/fedora-qa/qa-docs.git

+   - url: https://pagure.io/fedora-pgm/pgm_docs.git

+     branches: main

+   - url: https://pagure.io/fedora-pgm/pgm_docs.git

+     branches: main

+     start_path: releases

+   - url: https://pagure.io/Ask-Fedora-SOP-docs.git

+   - url: https://pagure.io/fedora-join/fedora-join-docs.git

+   - url: https://pagure.io/fedora-docs/localization.git

+   - url: https://pagure.io/fedora-l10n/docs.git

+   - url: https://github.com/fedora-eln/eln-docs.git

+   - url: https://pagure.io/i3-sig/docs.git

+   - url: https://github.com/fedora-infra/fedora-accounts-docs.git

+     branches: main

+   - url: https://pagure.io/gaming/documentation.git

+     branches: main

+   - url: https://pagure.io/fedora-server.git

+     branches: main

+     start_path: docs

+   - url: https://pagure.io/fedora-server.git

+     branches: main

+     start_path: wg

+   - url: https://pagure.io/epel.git

+     branches: main

+   - url: https://pagure.io/infra-docs-fpo.git

+   - url: https://pagure.io/fedora-workstation/workstation-docs.git

+     branches: main

+   - url: https://gitlab.com/fedora/marketing/marketing-docs.git

+     branches: main

+   - url: https://pagure.io/defensive-coding-guide.git

  ui:

    bundle:

-     url: https://asamalik.fedorapeople.org/ui-bundle.zip

+     url: https://releases.pagure.org/fedora-docs/fedora-docs-ui/ui-bundle-1.08.zip

      snapshot: true

    default_layout: with_menu

+   supplemental_files: ./supplemental-ui

  output:

    clean: true

    dir: ./public/en-US

    destinations:

    - provider: archive

  runtime:

-   pull: true

+   fetch: true

    cache_dir: ./cache

+   log:

+     format: pretty

+     level: fatal

  asciidoc:

    extensions:

    - ./lib/extensions/package-inline-macro.js

+ antora:

+   extensions:

+   - id: page-last-update

+     require: ./lib/extensions/page-last-update.js

+     enabled: true

+ urls:

+   latest_version_segment: latest

+ 

@@ -0,0 +1,1 @@ 

+ <!-- Add any HTML code to show at the top of each page — like a banner to a survey, some announcement, etc. Leave this file empty to not show anything-->

Figma prototype link 🔗


Starting with my first impression of the Fedora docs page:

  • So many blue blocks feel overwhelming and too much to take in.
  • The grey banners give a dull and boring look.
  • Darker text on a light background is always easier to read as compared to the opposite. (Accessibility is important).
  • The icons in the top right corner might get overlooked easily.
  • Someone searching for a particular topic/subtopic would not be able to find it easily as subtopics are not mentioned and there is no search bar as well.

My Improvements and proposal:

  • Gave the page a simple and clean look, and did not use any other color apart from the 2 blues.
  • Reduced the overall width of the page so that it is easier to scan/read.
  • Completed removed the block design to give more white space and breathing room.
    • Mentioned subtopics also on the front page itself so that they can be found easily
  • Added a search bar, where keywords can be searched directly.
  • Improved the footer by placing the 3 links/icons (history, edit, report) there
    • Because I felt that someone would first go through the page and then find a bug to report or decide to see the history or edit.
  • Added the fedora logo as the watermark which looks good according to me.