upcontent 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +61 -0
- package/.github/workflows/deploy.yml +59 -0
- package/.github/workflows/reusable-pages.yml +74 -0
- package/.upcontent/config.json +82 -0
- package/.upcontent/favicon.svg +4 -0
- package/.upcontent/logo.svg +6 -0
- package/.upcontent/portal.css +139 -0
- package/Makefile +29 -0
- package/README.md +114 -2
- package/SHOWCASE.mdx +163 -0
- package/astro.config.mjs +125 -0
- package/customization/config-json.md +92 -0
- package/customization/content.md +48 -0
- package/customization/environment.md +43 -0
- package/customization/index.md +33 -0
- package/customization/navigation.md +57 -0
- package/customization/site-identity.md +43 -0
- package/customization/theme.md +47 -0
- package/deployment/github-pages.md +46 -0
- package/deployment/index.md +24 -0
- package/deployment/static-hosts.md +34 -0
- package/getting-started/consumer-repository.md +156 -0
- package/getting-started/first-build.md +78 -0
- package/guides/authoring-content.md +105 -0
- package/guides/validate-your-site.md +53 -0
- package/package.json +33 -3
- package/scripts/upcontent-cli.mjs +113 -0
- package/scripts/verify-external-build.mjs +24 -0
- package/src/components/MermaidLoader.astro +290 -0
- package/src/components/PaletteShowcase.astro +122 -0
- package/src/components/StructuredDataCopy.astro +22 -0
- package/src/content/__mocks__/astro-content.ts +7 -0
- package/src/content/__mocks__/astro-loaders.ts +3 -0
- package/src/content.config.test.ts +163 -0
- package/src/content.config.ts +90 -0
- package/src/lib/content-blocklist.test.ts +47 -0
- package/src/lib/content-blocklist.ts +55 -0
- package/src/lib/doc-links.test.ts +62 -0
- package/src/lib/doc-links.ts +31 -0
- package/src/lib/mermaid-render.test.ts +42 -0
- package/src/lib/mermaid-render.ts +24 -0
- package/src/lib/portal-config.test.ts +143 -0
- package/src/lib/portal-config.ts +176 -0
- package/src/lib/product-identity.ts +2 -0
- package/src/lib/rehype-callouts.test.ts +69 -0
- package/src/lib/rehype-callouts.ts +61 -0
- package/src/lib/remark-strip-duplicate-title.test.ts +73 -0
- package/src/lib/remark-strip-duplicate-title.ts +37 -0
- package/src/lib/remark-structured-data-preview.test.ts +104 -0
- package/src/lib/remark-structured-data-preview.ts +66 -0
- package/src/lib/remark-wiki-links.test.ts +102 -0
- package/src/lib/remark-wiki-links.ts +110 -0
- package/src/lib/sidebar.test.ts +142 -0
- package/src/lib/sidebar.ts +113 -0
- package/src/lib/structured-data-tree.test.ts +75 -0
- package/src/lib/structured-data-tree.ts +55 -0
- package/src/overrides/Footer.astro +114 -0
- package/src/overrides/Head.astro +20 -0
- package/src/pages/index.astro +20 -0
- package/src/styles/callouts.css +29 -0
- package/src/styles/structured-data-preview.css +95 -0
- package/test-fixtures/external-consumer/.upcontent/config.json +26 -0
- package/test-fixtures/external-consumer/.upcontent/favicon.svg +4 -0
- package/test-fixtures/external-consumer/.upcontent/logo.svg +4 -0
- package/test-fixtures/external-consumer/.upcontent/theme.css +4 -0
- package/test-fixtures/external-consumer/.upcontent-renderer/README.md +3 -0
- package/test-fixtures/external-consumer/README.md +6 -0
- package/test-fixtures/external-consumer/forbidden.md +5 -0
- package/tsconfig.json +7 -0
- package/vitest.config.ts +18 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: Validate portal
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: validate-${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
validate:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- name: Check out repository
|
|
19
|
+
uses: actions/checkout@v5
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
|
|
23
|
+
- name: Set up pnpm
|
|
24
|
+
uses: pnpm/action-setup@v4
|
|
25
|
+
with:
|
|
26
|
+
version: 10.20.0
|
|
27
|
+
|
|
28
|
+
- name: Set up Node.js
|
|
29
|
+
uses: actions/setup-node@v5
|
|
30
|
+
with:
|
|
31
|
+
node-version: 22
|
|
32
|
+
cache: pnpm
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: pnpm install --frozen-lockfile
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: pnpm test
|
|
39
|
+
|
|
40
|
+
- name: Run Astro diagnostics
|
|
41
|
+
run: pnpm check
|
|
42
|
+
|
|
43
|
+
- name: Build golden consumer
|
|
44
|
+
run: make build CONTENT_PATH=.
|
|
45
|
+
|
|
46
|
+
- name: Check golden artifact
|
|
47
|
+
run: |
|
|
48
|
+
test -f dist/index.html
|
|
49
|
+
test -f dist/pagefind/pagefind.js
|
|
50
|
+
test -f dist/upcontent-assets/favicon.svg
|
|
51
|
+
|
|
52
|
+
- name: Build external consumer fixture
|
|
53
|
+
run: make check-external
|
|
54
|
+
|
|
55
|
+
- name: Check diff hygiene
|
|
56
|
+
env:
|
|
57
|
+
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
|
|
58
|
+
run: |
|
|
59
|
+
git diff --check "$BASE_SHA" HEAD
|
|
60
|
+
git diff --exit-code
|
|
61
|
+
test -z "$(git status --porcelain --untracked-files=all)"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Deploy documentation portal
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- name: Check out repository
|
|
22
|
+
uses: actions/checkout@v5
|
|
23
|
+
|
|
24
|
+
- name: Set up Pages
|
|
25
|
+
id: pages
|
|
26
|
+
uses: actions/configure-pages@v5
|
|
27
|
+
|
|
28
|
+
- name: Set up pnpm
|
|
29
|
+
uses: pnpm/action-setup@v4
|
|
30
|
+
with:
|
|
31
|
+
version: 10.20.0
|
|
32
|
+
|
|
33
|
+
- name: Set up Node.js
|
|
34
|
+
uses: actions/setup-node@v5
|
|
35
|
+
with:
|
|
36
|
+
node-version: 22
|
|
37
|
+
cache: pnpm
|
|
38
|
+
|
|
39
|
+
- name: Install dependencies
|
|
40
|
+
run: pnpm install --frozen-lockfile
|
|
41
|
+
|
|
42
|
+
- name: Build static portal
|
|
43
|
+
run: make build CONTENT_PATH=. REPO_URL="https://github.com/${{ github.repository }}" BASE_PATH="${{ steps.pages.outputs.base_path }}" SITE_URL="${{ steps.pages.outputs.origin }}"
|
|
44
|
+
|
|
45
|
+
- name: Upload static artifact
|
|
46
|
+
uses: actions/upload-pages-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
path: dist
|
|
49
|
+
|
|
50
|
+
deploy:
|
|
51
|
+
environment:
|
|
52
|
+
name: github-pages
|
|
53
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
needs: build
|
|
56
|
+
steps:
|
|
57
|
+
- name: Deploy to GitHub Pages
|
|
58
|
+
id: deployment
|
|
59
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Reusable Upcontent Pages build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
portal-repository:
|
|
7
|
+
description: Repository containing the Upcontent renderer.
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
default: lumamontes/upcontent
|
|
11
|
+
portal-ref:
|
|
12
|
+
description: Tag, branch, or commit of the Upcontent renderer.
|
|
13
|
+
required: false
|
|
14
|
+
type: string
|
|
15
|
+
default: main
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
pages: write
|
|
20
|
+
id-token: write
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
build:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- name: Check out consumer repository
|
|
27
|
+
uses: actions/checkout@v5
|
|
28
|
+
|
|
29
|
+
- name: Check out Upcontent renderer
|
|
30
|
+
uses: actions/checkout@v5
|
|
31
|
+
with:
|
|
32
|
+
repository: ${{ inputs.portal-repository }}
|
|
33
|
+
ref: ${{ inputs.portal-ref }}
|
|
34
|
+
path: .upcontent-renderer
|
|
35
|
+
|
|
36
|
+
- name: Set up Pages
|
|
37
|
+
id: pages
|
|
38
|
+
uses: actions/configure-pages@v5
|
|
39
|
+
|
|
40
|
+
- name: Set up pnpm
|
|
41
|
+
uses: pnpm/action-setup@v4
|
|
42
|
+
with:
|
|
43
|
+
version: 10.20.0
|
|
44
|
+
|
|
45
|
+
- name: Set up Node.js
|
|
46
|
+
uses: actions/setup-node@v5
|
|
47
|
+
with:
|
|
48
|
+
node-version: 22
|
|
49
|
+
cache: pnpm
|
|
50
|
+
cache-dependency-path: .upcontent-renderer/pnpm-lock.yaml
|
|
51
|
+
|
|
52
|
+
- name: Install renderer dependencies
|
|
53
|
+
working-directory: .upcontent-renderer
|
|
54
|
+
run: pnpm install --frozen-lockfile
|
|
55
|
+
|
|
56
|
+
- name: Build portal
|
|
57
|
+
working-directory: .upcontent-renderer
|
|
58
|
+
run: make build CONTENT_PATH="${{ github.workspace }}" REPO_URL="https://github.com/${{ github.repository }}" BASE_PATH="${{ steps.pages.outputs.base_path }}" SITE_URL="${{ steps.pages.outputs.origin }}"
|
|
59
|
+
|
|
60
|
+
- name: Upload static artifact
|
|
61
|
+
uses: actions/upload-pages-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
path: .upcontent-renderer/dist
|
|
64
|
+
|
|
65
|
+
deploy:
|
|
66
|
+
environment:
|
|
67
|
+
name: github-pages
|
|
68
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
needs: build
|
|
71
|
+
steps:
|
|
72
|
+
- name: Deploy to GitHub Pages
|
|
73
|
+
id: deployment
|
|
74
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"site": {
|
|
3
|
+
"title": "Upcontent",
|
|
4
|
+
"description": "Create a beautiful, customizable Starlight portal from your documentation repository.",
|
|
5
|
+
"url": "https://lumamontes.github.io/upcontent",
|
|
6
|
+
"logo": {
|
|
7
|
+
"src": ".upcontent/logo.svg",
|
|
8
|
+
"alt": "",
|
|
9
|
+
"replacesTitle": false
|
|
10
|
+
},
|
|
11
|
+
"favicon": ".upcontent/favicon.svg"
|
|
12
|
+
},
|
|
13
|
+
"repo": {
|
|
14
|
+
"url": "https://github.com/lumamontes/upcontent"
|
|
15
|
+
},
|
|
16
|
+
"theme": {
|
|
17
|
+
"customCss": [".upcontent/portal.css"]
|
|
18
|
+
},
|
|
19
|
+
"starlight": {
|
|
20
|
+
"social": [
|
|
21
|
+
{
|
|
22
|
+
"icon": "github",
|
|
23
|
+
"label": "GitHub",
|
|
24
|
+
"href": "https://github.com/lumamontes/upcontent"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"tableOfContents": {
|
|
28
|
+
"minHeadingLevel": 2,
|
|
29
|
+
"maxHeadingLevel": 3
|
|
30
|
+
},
|
|
31
|
+
"lastUpdated": true,
|
|
32
|
+
"pagination": true,
|
|
33
|
+
"expressiveCode": {
|
|
34
|
+
"styleOverrides": {
|
|
35
|
+
"borderRadius": "0.6rem"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"navigation": {
|
|
40
|
+
"roots": [
|
|
41
|
+
"README.md",
|
|
42
|
+
"getting-started",
|
|
43
|
+
"guides",
|
|
44
|
+
"customization",
|
|
45
|
+
"deployment",
|
|
46
|
+
"SHOWCASE.mdx"
|
|
47
|
+
],
|
|
48
|
+
"blocklist": {
|
|
49
|
+
"prefixes": [
|
|
50
|
+
".git/",
|
|
51
|
+
".scratch/",
|
|
52
|
+
".agents/",
|
|
53
|
+
".claude/",
|
|
54
|
+
".cursor/",
|
|
55
|
+
".codex/",
|
|
56
|
+
".opencode/",
|
|
57
|
+
"node_modules/",
|
|
58
|
+
"dist/",
|
|
59
|
+
".astro/",
|
|
60
|
+
"src/",
|
|
61
|
+
"server/",
|
|
62
|
+
"docs/agents/",
|
|
63
|
+
"docs/",
|
|
64
|
+
"test-fixtures/",
|
|
65
|
+
"external-consumer/",
|
|
66
|
+
"workflows/"
|
|
67
|
+
],
|
|
68
|
+
"exact": [
|
|
69
|
+
"AGENTS.md",
|
|
70
|
+
"CLAUDE.md",
|
|
71
|
+
"CONTEXT.md",
|
|
72
|
+
"PRODUCT.md"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"labelOverrides": {
|
|
76
|
+
"docs": "Project Docs"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"content": {
|
|
80
|
+
"titleField": "heading"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Upcontent</title>
|
|
3
|
+
<desc id="desc">Upcontent mark.</desc>
|
|
4
|
+
<rect width="56" height="56" x="8" y="8" rx="16" fill="#0f766e"/>
|
|
5
|
+
<path d="M20 24h32v8H20zm0 16h24v8H20z" fill="#fff"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
@import '@fontsource/poppins/400.css';
|
|
2
|
+
@import '@fontsource/poppins/500.css';
|
|
3
|
+
@import '@fontsource/poppins/600.css';
|
|
4
|
+
@import '@fontsource/poppins/700.css';
|
|
5
|
+
|
|
6
|
+
/* The consumer owns this identity and can replace it without changing the renderer. */
|
|
7
|
+
:root {
|
|
8
|
+
--sl-color-accent: #0f766e;
|
|
9
|
+
--sl-color-accent-high: #115e59;
|
|
10
|
+
--sl-color-accent-low: #ccfbf1;
|
|
11
|
+
--sl-color-text-accent: #0f766e;
|
|
12
|
+
--sl-color-bg: #f8faf7;
|
|
13
|
+
--sl-color-bg-nav: #f8faf7;
|
|
14
|
+
--sl-color-bg-sidebar: #eef4f1;
|
|
15
|
+
--sl-color-bg-inline-code: #e3eeea;
|
|
16
|
+
--sl-color-hairline-light: #d8e5df;
|
|
17
|
+
--sl-font: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
18
|
+
--sl-font-mono: 'SFMono-Regular', Consolas, monospace;
|
|
19
|
+
--sl-text-5xl: 3.35rem;
|
|
20
|
+
--sl-content-width: 48rem;
|
|
21
|
+
--sl-line-height: 1.72;
|
|
22
|
+
--up-sidebar-active: rgba(15, 118, 110, 0.08);
|
|
23
|
+
--up-sidebar-hover: rgba(15, 118, 110, 0.07);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:root[data-theme='light'] {
|
|
27
|
+
--sl-color-accent: #0f766e;
|
|
28
|
+
--sl-color-accent-high: #115e59;
|
|
29
|
+
--sl-color-accent-low: #ccfbf1;
|
|
30
|
+
--sl-color-text-accent: #0f766e;
|
|
31
|
+
--sl-color-bg: #f8faf7;
|
|
32
|
+
--sl-color-bg-nav: #f8faf7;
|
|
33
|
+
--sl-color-bg-sidebar: #eef4f1;
|
|
34
|
+
--sl-color-bg-inline-code: #e3eeea;
|
|
35
|
+
--sl-color-hairline-light: #d8e5df;
|
|
36
|
+
--up-sidebar-active: rgba(15, 118, 110, 0.08);
|
|
37
|
+
--up-sidebar-hover: rgba(15, 118, 110, 0.07);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
:root[data-theme='dark'] {
|
|
41
|
+
--sl-color-accent: #5eead4;
|
|
42
|
+
--sl-color-accent-high: #99f6e4;
|
|
43
|
+
--sl-color-accent-low: #134e4a;
|
|
44
|
+
--sl-color-text-accent: #99f6e4;
|
|
45
|
+
--sl-color-bg: #0d191a;
|
|
46
|
+
--sl-color-bg-nav: #102324;
|
|
47
|
+
--sl-color-bg-sidebar: #0f2021;
|
|
48
|
+
--sl-color-bg-inline-code: #173334;
|
|
49
|
+
--sl-color-hairline-light: #274445;
|
|
50
|
+
--up-sidebar-active: rgba(94, 234, 212, 0.09);
|
|
51
|
+
--up-sidebar-hover: rgba(94, 234, 212, 0.08);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.site-title {
|
|
55
|
+
font-size: 1.15rem;
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
letter-spacing: -0.025em;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sl-container > h1,
|
|
61
|
+
.sl-markdown-content h1 {
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
letter-spacing: -0.035em;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.sl-markdown-content h2 {
|
|
67
|
+
margin-top: 2.6em;
|
|
68
|
+
padding-top: 0.7em;
|
|
69
|
+
border-top: 1px solid var(--sl-color-hairline-light);
|
|
70
|
+
letter-spacing: -0.035em;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.sl-markdown-content :not(pre) > code {
|
|
74
|
+
border: 1px solid var(--sl-color-hairline-light);
|
|
75
|
+
border-radius: 0.25rem;
|
|
76
|
+
padding: 0.12em 0.35em;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.sl-markdown-content blockquote {
|
|
80
|
+
border-inline-start-color: var(--sl-color-accent);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.header {
|
|
84
|
+
border-bottom: 1px solid var(--sl-color-hairline-light);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.sl-markdown-content a:not(.sl-link-button) {
|
|
88
|
+
text-decoration-thickness: 0.08em;
|
|
89
|
+
text-underline-offset: 0.18em;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.sidebar-content .top-level > li + li {
|
|
93
|
+
margin-top: 0.3rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.sidebar-content .top-level > li > details > summary {
|
|
97
|
+
color: var(--sl-color-text);
|
|
98
|
+
font-weight: 600;
|
|
99
|
+
letter-spacing: 0.005em;
|
|
100
|
+
padding-block: 0.35rem;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.sidebar-content .top-level > li > details > summary .caret {
|
|
104
|
+
color: var(--sl-color-gray-3);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sidebar-content ul ul {
|
|
108
|
+
margin-top: 0.2rem;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.sidebar-content ul ul li {
|
|
112
|
+
border-inline-start-color: var(--sl-color-hairline-light);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.sidebar-content a {
|
|
116
|
+
border-radius: 0.45rem;
|
|
117
|
+
padding-block: 0.42rem;
|
|
118
|
+
transition: background-color 140ms ease, color 140ms ease;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.sidebar-content a:hover,
|
|
122
|
+
.sidebar-content a:focus-visible {
|
|
123
|
+
background: var(--up-sidebar-hover);
|
|
124
|
+
color: var(--sl-color-text);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.sidebar-content a[aria-current='page'],
|
|
128
|
+
.sidebar-content a[aria-current='page']:hover,
|
|
129
|
+
.sidebar-content a[aria-current='page']:focus-visible {
|
|
130
|
+
background: var(--up-sidebar-active);
|
|
131
|
+
color: var(--sl-color-text-accent);
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@media (min-width: 50em) {
|
|
136
|
+
.sl-markdown-content h1 {
|
|
137
|
+
max-width: 15ch;
|
|
138
|
+
}
|
|
139
|
+
}
|
package/Makefile
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
CONTENT_PATH ?= $(HOME)/www/my-content-repo
|
|
2
|
+
REPO_URL ?=
|
|
3
|
+
BASE_PATH ?=
|
|
4
|
+
SITE_URL ?=
|
|
5
|
+
|
|
6
|
+
.PHONY: dev build preview check-external
|
|
7
|
+
|
|
8
|
+
define prepare-content
|
|
9
|
+
@test -d "$(CONTENT_PATH)" || (printf 'Content path does not exist: %s\n' "$(CONTENT_PATH)" >&2; exit 1)
|
|
10
|
+
@rm -f src/content/docs
|
|
11
|
+
@ln -s "$(abspath $(CONTENT_PATH))" src/content/docs
|
|
12
|
+
endef
|
|
13
|
+
|
|
14
|
+
dev:
|
|
15
|
+
$(prepare-content)
|
|
16
|
+
REPO_URL=$(REPO_URL) BASE_PATH=$(BASE_PATH) SITE_URL=$(SITE_URL) pnpm exec astro dev
|
|
17
|
+
|
|
18
|
+
build:
|
|
19
|
+
$(prepare-content)
|
|
20
|
+
REPO_URL=$(REPO_URL) BASE_PATH=$(BASE_PATH) SITE_URL=$(SITE_URL) pnpm exec astro build
|
|
21
|
+
|
|
22
|
+
preview:
|
|
23
|
+
$(MAKE) build CONTENT_PATH="$(CONTENT_PATH)" REPO_URL="$(REPO_URL)" BASE_PATH="$(BASE_PATH)" SITE_URL="$(SITE_URL)"
|
|
24
|
+
pnpm exec astro preview
|
|
25
|
+
|
|
26
|
+
check-external:
|
|
27
|
+
$(MAKE) build CONTENT_PATH="$(CURDIR)/test-fixtures/external-consumer" REPO_URL="https://github.com/example/external-consumer"
|
|
28
|
+
@test -f dist/readme/index.html
|
|
29
|
+
node scripts/verify-external-build.mjs
|
package/README.md
CHANGED
|
@@ -1,3 +1,115 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
heading: Upcontent
|
|
3
|
+
description: Turn a documentation repository into a fast, searchable, customizable static portal.
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
Upcontent turns a Markdown repository into a documentation site that is ready to share.
|
|
7
|
+
|
|
8
|
+
It is for software teams that already have documentation, but need a better way to publish it: clear navigation, search, useful rendering for technical content, consumer-owned branding, and a repeatable static build.
|
|
9
|
+
|
|
10
|
+
## The short version
|
|
11
|
+
|
|
12
|
+
Upcontent gives a documentation repository:
|
|
13
|
+
|
|
14
|
+
- A responsive [Starlight](https://starlight.astro.build/) portal with navigation, search, themes, and table of contents
|
|
15
|
+
- A `.upcontent/config.json` file for identity, navigation, rendering, and content boundaries
|
|
16
|
+
- Custom CSS for the consumer's own brand
|
|
17
|
+
- Rendered callouts, Mermaid diagrams, JSON, YAML, CSV, and wiki links
|
|
18
|
+
- A static `dist/` directory that can be deployed to GitHub Pages or any static host
|
|
19
|
+
- Build checks that catch broken wiki links and excluded content before publication
|
|
20
|
+
|
|
21
|
+
The source repository remains the source of truth. Upcontent does not require a database, a companion server, or a new authoring system.
|
|
22
|
+
|
|
23
|
+
## Is this the right tool?
|
|
24
|
+
|
|
25
|
+
Upcontent is a good fit when:
|
|
26
|
+
|
|
27
|
+
- Your documentation already lives in Markdown or MDX.
|
|
28
|
+
- Your team wants to keep writing in Git.
|
|
29
|
+
- You want the portal to be owned and deployed by the documentation repository.
|
|
30
|
+
- You need more than raw Markdown, but do not need a dynamic application.
|
|
31
|
+
- You want branding and navigation without maintaining a custom docs frontend.
|
|
32
|
+
|
|
33
|
+
It is not the right fit when your site needs runtime authentication, server-rendered personalization, or review comments inside the published portal.
|
|
34
|
+
|
|
35
|
+
## Get started
|
|
36
|
+
|
|
37
|
+
### Publish an existing documentation repository
|
|
38
|
+
|
|
39
|
+
If your Markdown already lives in a GitHub repository, run the bootstrap command from that repository's root:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
pnpm dlx upcontent init
|
|
43
|
+
pnpm dlx upcontent dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The first command creates `.upcontent/` and a GitHub Pages workflow. The second starts a local portal using the repository you are already in. You do not need to clone the Upcontent renderer into your documentation repository.
|
|
47
|
+
|
|
48
|
+
See [Set up a consumer repository](getting-started/consumer-repository/) for the generated structure and configuration.
|
|
49
|
+
|
|
50
|
+
### Explore this repository locally
|
|
51
|
+
|
|
52
|
+
Clone this repository, then start the included golden consumer. This path is for exploring Upcontent itself:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
git clone https://github.com/lumamontes/upcontent.git
|
|
56
|
+
cd upcontent
|
|
57
|
+
pnpm install
|
|
58
|
+
make dev CONTENT_PATH=.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Then open the local URL printed by Astro. The [capability showcase](showcase/) is the fastest way to see the complete rendering and customization surface.
|
|
62
|
+
|
|
63
|
+
The generated consumer configuration looks like this:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"site": {
|
|
68
|
+
"title": "Engineering Docs",
|
|
69
|
+
"description": "Documentation for the engineering team.",
|
|
70
|
+
"logo": {
|
|
71
|
+
"src": ".upcontent/logo.svg",
|
|
72
|
+
"alt": "Engineering Docs"
|
|
73
|
+
},
|
|
74
|
+
"favicon": ".upcontent/favicon.svg"
|
|
75
|
+
},
|
|
76
|
+
"repo": {
|
|
77
|
+
"url": "https://github.com/acme/engineering-docs"
|
|
78
|
+
},
|
|
79
|
+
"theme": {
|
|
80
|
+
"customCss": [".upcontent/theme.css"]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Follow [Set up a consumer repository](getting-started/consumer-repository/) for the complete setup, then use [Customization](customization/) to shape the portal.
|
|
86
|
+
|
|
87
|
+
## See the full path
|
|
88
|
+
|
|
89
|
+
- [First build](getting-started/first-build/): run the portal locally and generate static output.
|
|
90
|
+
- [Consumer repository](getting-started/consumer-repository/): prepare content, assets, and configuration.
|
|
91
|
+
- [Customization](customization/): configure identity, theme, navigation, content, JSON, and environment variables.
|
|
92
|
+
- [Authoring content](guides/authoring-content/): write pages that are clear and easy to scan.
|
|
93
|
+
- [Deployment](deployment/): publish the generated files to GitHub Pages or another static host.
|
|
94
|
+
- [Capability showcase](showcase/): inspect all supported content and rendering features in one page.
|
|
95
|
+
|
|
96
|
+
## Build for production
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
make build CONTENT_PATH=/path/to/your-consumer-repo
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The generated site is written to `dist/` and includes the Pagefind search index.
|
|
103
|
+
|
|
104
|
+
Before publishing, run:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
pnpm test
|
|
108
|
+
pnpm check
|
|
109
|
+
make build CONTENT_PATH=.
|
|
110
|
+
make check-external
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Built on Astro and Starlight
|
|
114
|
+
|
|
115
|
+
Upcontent uses the official [Astro](https://astro.build/) framework and [Starlight](https://starlight.astro.build/) documentation theme as its rendering foundation. Upcontent adds the consumer-repository contract, content integrity checks, configuration surface, and deployment workflow around them.
|