Skip to content

build-and-deploy

build-and-deploy #107

name: build-and-deploy
on:
push:
branches: [main]
schedule:
# Nightly rebuild to refresh GitHub-derived enrichment data (stars,
# contributors, last commit, etc.) without requiring a code change.
- cron: '23 5 * * *'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install landscape2
run: |
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/cncf/landscape2/releases/download/v1.1.0/landscape2-installer.sh | sh
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Restore landscape2 cache
uses: actions/cache@v4
with:
path: .landscape2-cache
key: landscape2-${{ github.run_id }}
restore-keys: |
landscape2-
- name: Build landscape
env:
GITHUB_TOKENS: ${{ secrets.LANDSCAPE_GH_TOKENS }}
run: |
landscape2 build \
--data-file landscape.yml \
--settings-file settings.yml \
--guide-file guide.yml \
--logos-path logos \
--cache-dir .landscape2-cache \
--output-dir build
- name: Strip hardcoded "TAG " prefix from chips and stats table
# landscape2 hardcodes "TAG " into two separate template strings:
# - main bundle: `<div>TAG ` used by chip rendering on cards
# - stats bundle: `<tr><td>TAG </td>` used by the stats-page
# "Distribution by ... TAG" table (each row reads "TAG <value>")
# No settings flag suppresses either. Patch both so chips/rows
# show just the value. Defensive: warns if patterns disappear
# upstream.
run: |
set -e
before_div=$(grep -ohc '<div>TAG ' build/assets/*.js | paste -sd+ - | bc || echo 0)
before_td=$(grep -ohc '<tr><td>TAG ' build/assets/*.js | paste -sd+ - | bc || echo 0)
find build/assets -name '*.js' -exec sed -i 's|<div>TAG |<div>|g' {} +
find build/assets -name '*.js' -exec sed -i 's|<tr><td>TAG </td>|<tr><td></td>|g' {} +
after_div=$(grep -ohc '<div>TAG ' build/assets/*.js | paste -sd+ - | bc || echo 0)
after_td=$(grep -ohc '<tr><td>TAG ' build/assets/*.js | paste -sd+ - | bc || echo 0)
echo "stripped chip <div> prefix: $before_div -> $after_div"
echo "stripped stats <tr><td> prefix: $before_td -> $after_td"
if [ "$before_div" = "0" ] && [ "$before_td" = "0" ]; then
echo "WARNING: didn't find chip-prefix or stats-prefix templates; landscape2 may have changed them." >&2
fi
- name: Uppercase stats-page tag/maturity labels via CSS
# Stats-page tables and the maturity chart legend pass tag/project
# values raw ("arc", "jpl", "ammos") — they should render as
# acronyms. Inject a CSS rule that uppercases the relevant
# cells. The existing Content-*.css that ships the stats table
# styles is the right target (one file with `_table_` class names).
run: |
set -e
rule='table td:first-child,.apexcharts-legend-text{text-transform:uppercase}'
patched=0
for css in build/assets/Content-*.css; do
if grep -q '_table_' "$css"; then
echo "$rule" >> "$css"
patched=$((patched + 1))
fi
done
echo "uppercase rule appended to $patched stats CSS file(s)"
if [ "$patched" = "0" ]; then
echo "WARNING: stats CSS file not found." >&2
fi
- name: Disable "all" magic-bypass in group filter
# landscape2's bundled JS shorts-circuits the group filter when
# the active group's normalized_name === "all" — it skips the
# category check and renders every item in every category it
# appears in (primary + additional_categories). With our AMMOS
# quick-filter using second_path, that double-renders the 6
# AMMOS items in our "All" view. Strip the `&&t!==ct` clause
# so the filter always runs normally — the All group then
# respects its category list (which excludes AMMOS).
run: |
set -e
before=$(grep -ohc 'baseDS\.groups&&t!==ct' build/assets/*.js | paste -sd+ - | bc || echo 0)
find build/assets -name '*.js' -exec sed -i 's|baseDS\.groups&&t!==ct|baseDS.groups|g' {} +
after=$(grep -ohc 'baseDS\.groups&&t!==ct' build/assets/*.js | paste -sd+ - | bc || echo 0)
echo "patched magic bypass: $before occurrences -> $after"
if [ "$before" = "0" ]; then
echo "WARNING: didn't find the 'all' magic-bypass; landscape2 may have changed the bundle." >&2
fi
- name: Uppercase tag-formatter (filter chip labels)
# landscape2's chip-label formatter `hi(e)` Title-Cases each
# word ("jpl" -> "Jpl"). Card chips have CSS text-uppercase
# so it's masked there, but filter-modal options don't —
# showing "Jpl"/"Ammos"/"Mpsa" instead of the proper acronyms.
# Replace the formatter body with toUpperCase + hyphen->space
# so all our identifier-style tags render as proper acronyms.
run: |
python3 <<'PY'
import re, glob
pat = (
r'hi=e=>\{const r=e\.replace\([^,]+," "\)\.split\(" "\);'
r'for\(let n=0;n<r\.length;n\+\+\)r\[n\]=[A-Za-z0-9_]+\(r\[n\]\);'
r'return r\.join\(" "\)\}'
)
patched = 0
for js in glob.glob('build/assets/*.js'):
with open(js) as f: text = f.read()
new = re.sub(pat, 'hi=e=>e.toUpperCase().replace(/-/g," ")', text)
if new != text:
with open(js, 'w') as f: f.write(new)
patched += 1
print(f'patched tag-formatter in {patched} bundle(s)')
if patched == 0:
import sys
print('WARNING: tag-formatter pattern not found; landscape2 may have changed it.', file=sys.stderr)
PY
- name: Hide "Powered by CNCF" footer line
# landscape2 hardcodes a "Powered by [CNCF interactive
# landscapes generator]." line in the footer DOM template;
# there's no settings flag to suppress it. Inject a
# display:none style attribute on the wrapping <div> so the
# surrounding JS DOM-traversal still works (firstChild /
# nextSibling chain is preserved) but the line isn't visible.
# Our settings.yml `footer.text` quote renders above it.
run: |
set -e
before=$(grep -ohc '<div>Powered by ' build/assets/*.js | paste -sd+ - | bc || echo 0)
find build/assets -name '*.js' -exec sed -i 's|<div>Powered by |<div style="display:none">Powered by |g' {} +
after=$(grep -ohc '<div>Powered by ' build/assets/*.js | paste -sd+ - | bc || echo 0)
echo "hid powered-by line: $before occurrences -> $after"
if [ "$before" = "0" ]; then
echo "WARNING: didn't find the Powered by template; landscape2 may have changed it." >&2
fi
- name: Override page title to "Open Mission Software Landscape"
# landscape2's HTML template hardcodes `{{ foundation }} Landscape`
# for <title>, og:title, twitter:title, and the JSON-LD name. With
# foundation=NASA (driving the per-card NASA AMMOS / NASA <CENTER>
# badges), the tab title becomes "NASA Landscape" — but our actual
# site brand is "Open Mission Software Landscape" (matches the
# header wordmark). Patch the built HTML to use the correct title.
run: |
set -e
before=$(grep -ohc 'NASA Landscape' build/index.html build/404.html 2>/dev/null | paste -sd+ - | bc || echo 0)
find build -maxdepth 2 -name '*.html' -exec sed -i 's|NASA Landscape|Open Mission Software Landscape|g' {} +
after=$(grep -ohc 'NASA Landscape' build/index.html build/404.html 2>/dev/null | paste -sd+ - | bc || echo 0)
echo "rewrote title: $before occurrences -> $after"
- name: Copy index.html to 404.html (SPA routing on GH Pages)
run: cp build/index.html build/404.html
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: build
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4