Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 64 additions & 20 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,14 @@ jobs:

build:
needs: identity
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 30
env:
LIBTMUX_DOCS_PORT: ruby
LIBTMUX_DOCS_VERSION: ${{ matrix.version }}
LIBTMUX_DOCS_SOURCE_REPOSITORY: ${{ needs.identity.outputs.source-repository }}
LIBTMUX_DOCS_CHECKOUT_RUBY: ${{ github.workspace }}/port
LIBTMUX_DOCS_GENERATOR_CHECKOUT: ${{ github.workspace }}/docs-generator
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.identity.outputs.matrix) }}
Expand All @@ -186,9 +193,11 @@ jobs:
repository: ${{ needs.identity.outputs.source-repository }}
ref: ${{ needs.identity.outputs.source-ref }}
fetch-depth: 0
path: port
persist-credentials: false

- id: source
working-directory: port
env:
SELECTED_REF: ${{ needs.identity.outputs.source-ref }}
run: |
Expand All @@ -204,40 +213,58 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
path: .docs-generator
path: docs-generator
persist-credentials: false

- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: libtmux/docs
ref: 8fda4b89071621b9ed2c4722a68d61f6ecf9c1c4
path: .site
ref: 99532a7ec07ae3af3ef399941e81a1d6424720cb
path: docs
persist-credentials: false

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '26'

- name: Snapshot source and exporter before native generation
working-directory: docs
env:
LIBTMUX_DOCS_SOURCE_SHA: ${{ steps.source.outputs.sha }}
run: node scripts/publication-provenance.mjs snapshot "$RUNNER_TEMP/build-inputs.json" "$PWD"

- uses: ruby/setup-ruby@762794c140bbeda0f1224786aa33b4b46783a6c1 # v1.326.0
with:
ruby-version: '4.0.7'
bundler-cache: true
working-directory: port
bundler-cache: false

- name: Install the selected Ruby bundle
working-directory: port
env:
BUNDLE_FROZEN: 'true'
run: bundle install

- name: Install tmux for native MCP discovery
run: |
sudo apt-get update -qq
sudo apt-get install --no-install-recommends -y -qq tmux

- name: Export the selected Ruby source
working-directory: port
run: |
bundle exec ruby .docs-generator/scripts/export-docs \
--source "$GITHUB_WORKSPACE" \
--output "$GITHUB_WORKSPACE/docs/_build"
bundle exec ruby "$GITHUB_WORKSPACE/docs-generator/scripts/export-docs" \
--source "$GITHUB_WORKSPACE/port" \
--output "$GITHUB_WORKSPACE/port/docs/_build"

- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
with:
package_json_file: .site/package.json
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '26'
cache: pnpm
cache-dependency-path: .site/pnpm-lock.yaml
package_json_file: docs/package.json
- run: pnpm install --frozen-lockfile
working-directory: .site
working-directory: docs

- name: Build the selected Ruby documentation tree
working-directory: .site
working-directory: docs
env:
LIBTMUX_DOCS_PORT: ruby
LIBTMUX_DOCS_VERSION: ${{ matrix.version }}
Expand All @@ -246,13 +273,30 @@ jobs:
LIBTMUX_DOCS_RESOLVES_TO: ${{ matrix.resolvesTo }}
LIBTMUX_DOCS_SOURCE_REF: ${{ needs.identity.outputs.source-ref }}
LIBTMUX_DOCS_SOURCE_SHA: ${{ steps.source.outputs.sha }}
LIBTMUX_DOCS_CHECKOUT_RUBY: ${{ github.workspace }}
LIBTMUX_DOCS_INPUT_SNAPSHOT: ${{ runner.temp }}/build-inputs.json
run: ./scripts/build-site.sh --ports ruby --versions "${{ matrix.version }}" --skip-refs --skip-pagefind

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- id: content
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: docs-ruby-${{ matrix.version }}
path: .site/_site/en/ruby/${{ matrix.version }}
path: docs/_site/en/ruby/${{ matrix.version }}
if-no-files-found: error
retention-days: 1
include-hidden-files: true

- name: Describe the uploaded artifact
working-directory: docs
env:
ARTIFACT_ID: ${{ steps.content.outputs.artifact-id }}
ARTIFACT_DIGEST: ${{ steps.content.outputs.artifact-digest }}
ARTIFACT_NAME: docs-ruby-${{ matrix.version }}
SOURCE_SHA: ${{ steps.source.outputs.sha }}
run: node scripts/publication-provenance.mjs descriptor "$RUNNER_TEMP/publication.json"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: docs-ruby-${{ matrix.version }}-publication
path: ${{ runner.temp }}/publication.json
if-no-files-found: error
retention-days: 1

Expand All @@ -265,7 +309,7 @@ jobs:
permissions:
contents: read
id-token: write
uses: libtmux/docs/.github/workflows/reusable-deploy.yml@8fda4b89071621b9ed2c4722a68d61f6ecf9c1c4
uses: libtmux/docs/.github/workflows/reusable-deploy.yml@99532a7ec07ae3af3ef399941e81a1d6424720cb
with:
path-prefix: ruby/${{ matrix.version }}
artifact: docs-ruby-${{ matrix.version }}
Expand Down
47 changes: 47 additions & 0 deletions test/unit/docs_workflow_test.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,59 @@
# frozen_string_literal: true

require "minitest/autorun"
require "yaml"

class DocsWorkflowTest < Minitest::Test
def workflow
YAML.load_file(File.expand_path("../../.github/workflows/docs.yml", __dir__))
end

def test_preview_publication_uses_the_preview_role
workflow = File.read(File.expand_path("../../.github/workflows/docs.yml", __dir__))

assert_includes workflow,
"role-arn: ${{ matrix.environment == 'docs-preview' && secrets.LIBTMUX_DOCS_PREVIEW_ROLE_ARN || secrets.LIBTMUX_DOCS_ROLE_ARN }}"
end

def test_source_exporter_and_docs_use_separate_checkouts
build = workflow.fetch("jobs").fetch("build")
steps = build.fetch("steps")
checkouts = steps.select { |step| step.fetch("uses", "").start_with?("actions/checkout@") }
assert_equal %w[port docs-generator docs], checkouts.map { |step| step.fetch("with").fetch("path") }
assert_equal "${{ github.workspace }}/port", build.fetch("env").fetch("LIBTMUX_DOCS_CHECKOUT_RUBY")
assert_equal "${{ github.workspace }}/docs-generator", build.fetch("env").fetch("LIBTMUX_DOCS_GENERATOR_CHECKOUT")
snapshot = steps.index { |step| step.fetch("run", "").include?("publication-provenance.mjs snapshot") }
exporter = steps.index { |step| step.fetch("name", "").start_with?("Export the selected") }
assert snapshot && exporter && snapshot < exporter
assert_equal "port", steps.fetch(exporter).fetch("working-directory")
assert_includes steps.fetch(exporter).fetch("run"), '--source "$GITHUB_WORKSPACE/port"'
tree = steps.find { |step| step.fetch("name", "").start_with?("Build the selected") }
assert_equal "${{ runner.temp }}/build-inputs.json", tree.fetch("env").fetch("LIBTMUX_DOCS_INPUT_SNAPSHOT")
assert_equal "${{ steps.source.outputs.sha }}", tree.fetch("env").fetch("LIBTMUX_DOCS_SOURCE_SHA")
end

def test_descriptor_uses_the_exact_content_upload
jobs = workflow.fetch("jobs")
steps = jobs.fetch("build").fetch("steps")
content = steps.find { |step| step["id"] == "content" }.fetch("with")
assert_equal true, content.fetch("include-hidden-files")
descriptor = steps.find { |step| step.fetch("run", "").include?("publication-provenance.mjs descriptor") }
assert_equal "${{ steps.content.outputs.artifact-id }}", descriptor.fetch("env").fetch("ARTIFACT_ID")
assert_equal "${{ steps.content.outputs.artifact-digest }}", descriptor.fetch("env").fetch("ARTIFACT_DIGEST")
assert_equal content.fetch("name"), descriptor.fetch("env").fetch("ARTIFACT_NAME")
assert steps.any? { |step| step.dig("with", "name") == "#{content.fetch('name')}-publication" }
docs = steps.find { |step| step.dig("with", "repository") == "libtmux/docs" }
assert_match(/\A[0-9a-f]{40}\z/, docs.fetch("with").fetch("ref"))
assert jobs.fetch("publish").fetch("uses").end_with?("@#{docs.fetch('with').fetch('ref')}")
end

def test_arbitrary_source_builds_do_not_restore_caches
steps = workflow.fetch("jobs").fetch("build").fetch("steps")
ruby = steps.find { |step| step.fetch("uses", "").start_with?("ruby/setup-ruby@") }
assert_equal false, ruby.fetch("with").fetch("bundler-cache")
node = steps.find { |step| step.fetch("uses", "").start_with?("actions/setup-node@") }
refute node.fetch("with").key?("cache")
bundle = steps.find { |step| step["run"] == "bundle install" }
assert_equal "true", bundle.fetch("env").fetch("BUNDLE_FROZEN")
end
end
Loading