-
Notifications
You must be signed in to change notification settings - Fork 23
docs: add documentation versioning support #834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -102,17 +102,79 @@ jobs: | |
| - name: Publish package to PyPI | ||
| uses: pypa/gh-action-pypi-publish@release/v1 | ||
|
|
||
| version_docs: | ||
| name: Version docs | ||
| needs: [release_prepare, changelog_update, pypi_publish] | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| env: | ||
| NODE_VERSION: 22 | ||
| PYTHON_VERSION: 3.14 | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} | ||
|
|
||
| - name: Set up Node | ||
| uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: ${{ env.NODE_VERSION }} | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v6 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
|
|
||
| - name: Set up uv package manager | ||
| uses: astral-sh/setup-uv@v7 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
|
|
||
| - name: Install Python dependencies | ||
| run: uv run poe install-dev | ||
|
|
||
| - name: Install website dependencies | ||
| run: | | ||
| cd website | ||
| corepack enable | ||
| yarn install | ||
|
|
||
| - name: Snapshot the current version | ||
| run: | | ||
| cd website | ||
| VERSION="$(python -c "import tomllib, pathlib; print(tomllib.loads(pathlib.Path('../pyproject.toml').read_text())['project']['version'])")" | ||
| MAJOR_MINOR="$(echo "$VERSION" | cut -d. -f1-2)" | ||
| export MAJOR_MINOR | ||
| # Remove existing version if present (patch releases override) | ||
| rm -rf "versioned_docs/version-${MAJOR_MINOR}" | ||
| rm -rf "versioned_sidebars/version-${MAJOR_MINOR}-sidebars.json" | ||
| jq 'map(select(. != env.MAJOR_MINOR))' versions.json > tmp.json && mv tmp.json versions.json | ||
| # Build API reference and create version snapshots | ||
| bash build_api_reference.sh | ||
| npx docusaurus docs:version "$MAJOR_MINOR" | ||
| npx docusaurus api:version "$MAJOR_MINOR" | ||
|
|
||
| - name: Commit and push versioned docs | ||
| uses: EndBug/add-and-commit@v9 | ||
| with: | ||
| add: "website/versioned_docs website/versioned_sidebars website/versions.json" | ||
| message: "docs: version ${{ needs.release_prepare.outputs.version_number }} docs [skip ci]" | ||
| default_author: github_actions | ||
|
|
||
| doc_release: | ||
| name: Doc release | ||
| needs: [changelog_update, pypi_publish] | ||
| needs: [changelog_update, pypi_publish, version_docs] | ||
| permissions: | ||
| contents: write | ||
| pages: write | ||
| id-token: write | ||
| uses: ./.github/workflows/_release_docs.yaml | ||
| with: | ||
| # Use the ref from the changelog update to include the updated changelog. | ||
| ref: ${{ needs.changelog_update.outputs.changelog_commitish }} | ||
| # Use the default branch ref to include both changelog and versioned docs. | ||
| ref: ${{ github.ref }} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as GitHub docs are concerned (link), If I understand correctly, this will be the commit that this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, thanks, fixed - now it uses |
||
| secrets: inherit | ||
|
|
||
| trigger_docker_build: | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How are these changes connected to the rest of the PR? IIRC this is done automatically by
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting, this should follow the same pattern as in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I tried a bit more, they are gone and I'll remove them from the Client's docs as well, thanks! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,21 @@ | ||
| #!/bin/bash | ||
|
|
||
| # On macOS, sed requires a space between -i and '' to specify no backup should be done | ||
| # On Linux, sed requires no space between -i and '' to specify no backup should be done | ||
| sed_no_backup() { | ||
| if [[ $(uname) = "Darwin" ]]; then | ||
| sed -i '' "$@" | ||
| else | ||
| sed -i'' "$@" | ||
| fi | ||
| } | ||
|
|
||
| # Create docspec dump of this package's source code through pydoc-markdown | ||
| pydoc-markdown --quiet --dump > docspec-dump.jsonl | ||
| sed_no_backup "s#${PWD}/..#REPO_ROOT_PLACEHOLDER#g" docspec-dump.jsonl | ||
|
|
||
| # Generate import shortcuts from the modules | ||
| python generate_module_shortcuts.py | ||
|
|
||
| # Transform the docspec dumps into Typedoc-compatible docs tree | ||
| node transformDocs.js |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| loaders: | ||
| - type: python | ||
| search_path: [../src] | ||
| processors: | ||
| - type: filter | ||
| skip_empty_modules: true | ||
| - type: crossref | ||
| renderer: | ||
| type: docusaurus | ||
| docs_base_path: docs | ||
| relative_output_path: reference | ||
| relative_sidebar_path: sidebar.json | ||
| sidebar_top_level_label: null |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| import React from 'react'; | ||
| import { useVersions, useActiveDocContext, useDocsVersionCandidates } from '@docusaurus/plugin-content-docs/client'; | ||
| import { useDocsPreferredVersion } from '@docusaurus/theme-common'; | ||
| import { translate } from '@docusaurus/Translate'; | ||
| import { useLocation } from '@docusaurus/router'; | ||
| import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; | ||
| import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; | ||
| import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; | ||
|
|
||
| const getVersionMainDoc = (version) => version.docs.find((doc) => doc.id === version.mainDocId); | ||
|
|
||
| function getApiLinks(props, pathname, baseUrl) { | ||
| if (!pathname.startsWith(`${baseUrl}reference`)) { | ||
| return []; | ||
| } | ||
|
|
||
| try { | ||
| return JSON.parse(props['data-api-links']); | ||
| } catch { | ||
| return []; | ||
| } | ||
| } | ||
|
|
||
| /* eslint-disable react/prop-types */ | ||
| export default function DocsVersionDropdownNavbarItem({ | ||
| mobile, | ||
| docsPluginId, | ||
| dropdownActiveClassDisabled, | ||
| dropdownItemsBefore, | ||
| dropdownItemsAfter, | ||
| ...props | ||
| }) { | ||
| const { search, hash, pathname } = useLocation(); | ||
| const { siteConfig } = useDocusaurusContext(); | ||
| const baseUrl = siteConfig.baseUrl.endsWith('/') ? siteConfig.baseUrl : `${siteConfig.baseUrl}/`; | ||
| const apiLinks = getApiLinks(props, pathname, baseUrl); | ||
|
|
||
| const activeDocContext = useActiveDocContext(docsPluginId); | ||
| const versions = useVersions(docsPluginId); | ||
| const { savePreferredVersionName } = useDocsPreferredVersion(docsPluginId); | ||
| const versionLinks = versions.map((version, idx) => { | ||
| // We try to link to the same doc, in another version | ||
| // When not possible, fallback to the "main doc" of the version | ||
| const versionDoc = activeDocContext.alternateDocVersions[version.name] ?? getVersionMainDoc(version); | ||
| return { | ||
| label: version.label, | ||
| // preserve ?search#hash suffix on version switches | ||
| to: `${apiLinks[idx] ?? versionDoc.path}${search}${hash}`, | ||
| isActive: () => version === activeDocContext.activeVersion, | ||
| onClick: () => savePreferredVersionName(version.name), | ||
| }; | ||
| }); | ||
| const items = [...dropdownItemsBefore, ...versionLinks, ...dropdownItemsAfter]; | ||
| const dropdownVersion = useDocsVersionCandidates(docsPluginId)[0]; | ||
| // Mobile dropdown is handled a bit differently | ||
| const dropdownLabel = | ||
| mobile && items.length > 1 | ||
| ? translate({ | ||
| id: 'theme.navbar.mobileVersionsDropdown.label', | ||
| message: 'Versions', | ||
| description: 'The label for the navbar versions dropdown on mobile view', | ||
| }) | ||
| : dropdownVersion.label; | ||
| let dropdownTo = mobile && items.length > 1 ? undefined : getVersionMainDoc(dropdownVersion).path; | ||
|
|
||
| if (dropdownTo && pathname.startsWith(`${baseUrl}reference`)) { | ||
| dropdownTo = versionLinks.find((v) => v.label === dropdownVersion.label)?.to; | ||
| } | ||
|
|
||
| // We don't want to render a version dropdown with 0 or 1 item. If we build | ||
| // the site with a single docs version (onlyIncludeVersions: ['1.0.0']), | ||
| // We'd rather render a button instead of a dropdown | ||
| if (items.length <= 1) { | ||
| return ( | ||
| <DefaultNavbarItem | ||
| {...props} | ||
| mobile={mobile} | ||
| label={dropdownLabel} | ||
| to={dropdownTo} | ||
| isActive={dropdownActiveClassDisabled ? () => false : undefined} | ||
| /> | ||
| ); | ||
| } | ||
| return ( | ||
| <DropdownNavbarItem | ||
| {...props} | ||
| mobile={mobile} | ||
| label={dropdownLabel} | ||
| to={dropdownTo} | ||
| items={items} | ||
| isActive={dropdownActiveClassDisabled ? () => false : undefined} | ||
| /> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we can explicitly checkout the
needs.changelog_update.outputs.changelog_commitish, to prevent race conditions or other mishaps?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, checkout now explicitly uses
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}