build-and-deploy #107
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |