Skip to content

Commit 8285743

Browse files
authored
Merge pull request #10 from MrPunyapal/feat/private-source-auth
Support private repositories in remote sources
2 parents 8b697cb + 946a428 commit 8285743

20 files changed

Lines changed: 484 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
> Changes in **0.1.4 and after** — every release from `0.1.4` through `0.2.1`.
44
> (`chore: regenerate docs` and merge commits are omitted.)
55
6+
## Unreleased
7+
8+
### Features
9+
- **Private remote sources** — sync from private Git repositories by adding `'token' => '${ENV_VAR}'` (and optionally `'username'`) to a `docsmith.sources.php` entry. Tokens resolve from the environment at sync time; without an explicit token, `DOCSMITH_TOKEN` is used for any host and `GITHUB_TOKEN` / `GH_TOKEN` only for github.com hosts (never sent to third-party hosts). Requires [mrpunyapal/git-reader](https://github.com/MrPunyapal/git-reader) 0.2.0.
10+
611
## 0.3.0-beta.1 — 2026-08-22
712

813
### Features

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"require": {
77
"php": "^8.3",
88
"league/commonmark": "^2.7",
9-
"mrpunyapal/git-reader": "^0.1",
9+
"mrpunyapal/git-reader": "^0.2",
1010
"phiki/phiki": "^2.2"
1111
},
1212
"require-dev": {

docs/export/docs.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,8 @@ Plain builds remain fully deterministic and offline. If no `docsmith.sources.php
596596
| `ref` | yes | Branch name, tag name, or an advertised tip SHA. Annotated tags resolve to their commit. |
597597
| `path` | no | Subdirectory to extract. Empty or `/` means the whole tree. `..` is rejected. |
598598
| `target` | yes | Directory name under the markdown root (`[A-Za-z0-9._-]+`). Must be unique across sources. |
599+
| `token` | no | Access token for private repositories. `'${ENV_VAR}'` reads the named environment variable (recommended). |
600+
| `username` | no | Username used with the token. Defaults to `x-access-token`. |
599601

600602
### Caching and determinism
601603

@@ -612,7 +614,27 @@ Materialization is hardened by default:
612614
- Per-file (20 MB), total-size (200 MB), and file-count (20 000) budgets guard against oversized or hostile repositories.
613615
- Extraction writes to a staging directory and swaps atomically, so failures never leave half-updated targets.
614616

615-
Private repositories are **not** supported yet; authentication attempts fail with a clear message.
617+
## Private repositories
618+
619+
Private repositories are supported — pass a token in `docsmith.sources.php`:
620+
621+
```php
622+
return [
623+
[
624+
'repository' => 'https://github.com/acme/private-docs.git',
625+
'ref' => 'main',
626+
'path' => 'docs',
627+
'target' => 'private-docs',
628+
'token' => '${ACME_PAT}', // read from the ACME_PAT environment variable
629+
'username' => 'doc-bot', // optional; defaults to x-access-token
630+
],
631+
];
632+
```
633+
634+
- **`'token' => '${ENV_VAR_NAME}'`** is the recommended form: DocSmith reads the variable from the environment at sync time and fails with a clear message if it is unset. A literal token string also works, but hardcoding secrets in a committed file is discouraged.
635+
- **Automatic fallbacks** — if no `token` key is present, DocSmith uses `DOCSMITH_TOKEN` for any HTTPS host, and `GITHUB_TOKEN` / `GH_TOKEN` only for repositories on github.com. GitHub tokens are never sent to third-party hosts, and fallback tokens are never attached to plain-HTTP URLs.
636+
- **Never commit tokens.** Keep them in your shell profile or `.env`, and let CI inject them via repository secrets.
637+
616638

617639
## Programmatic use
618640

@@ -1175,6 +1197,8 @@ jobs:
11751197
# Syncs remote sources (incremental when docsmith.sources.lock.json
11761198
# matches) and builds in one step.
11771199
- run: php bin/docsmith build --sync
1200+
env:
1201+
ACME_PAT: ${{ secrets.ACME_PAT }} # only needed for private sources
11781202

11791203
- uses: actions/upload-pages-artifact@v3
11801204
with:

docs/llms-full.txt

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/remote-sources/index.html

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ <h2 id="source-options">Source options</h2>
115115
<td>yes</td>
116116
<td>Directory name under the markdown root (<code>[A-Za-z0-9._-]+</code>). Must be unique across sources.</td>
117117
</tr>
118+
<tr>
119+
<td><code>token</code></td>
120+
<td>no</td>
121+
<td>Access token for private repositories. <code>'${ENV_VAR}'</code> reads the named environment variable (recommended).</td>
122+
</tr>
123+
<tr>
124+
<td><code>username</code></td>
125+
<td>no</td>
126+
<td>Username used with the token. Defaults to <code>x-access-token</code>.</td>
127+
</tr>
118128
</tbody>
119129
</table></div>
120130
<h3 id="caching-and-determinism">Caching and determinism</h3>
@@ -128,7 +138,24 @@ <h2 id="safety">Safety</h2>
128138
<li>Per-file (20 MB), total-size (200 MB), and file-count (20 000) budgets guard against oversized or hostile repositories.</li>
129139
<li>Extraction writes to a staging directory and swaps atomically, so failures never leave half-updated targets.</li>
130140
</ul>
131-
<p>Private repositories are <strong>not</strong> supported yet; authentication attempts fail with a clear message.</p>
141+
<h2 id="private-repositories">Private repositories</h2>
142+
<p>Private repositories are supported — pass a token in <code>docsmith.sources.php</code>:</p>
143+
<pre class="phiki language-php github-light phiki-themes github-dark" data-language="php" style="background-color: #fff;color: #24292e;--phiki-dark-background-color: #24292e;--phiki-dark-color: #e1e4e8;"><code><span class="line"><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">return</span><span class="token"> </span><span class="token">[</span><span class="token">
144+
</span></span><span class="line"><span class="token"> </span><span class="token">[</span><span class="token">
145+
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">repository</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token"> </span><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">=&gt;</span><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">https://github.com/acme/private-docs.git</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token">,</span><span class="token">
146+
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">ref</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token"> </span><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">=&gt;</span><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">main</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token">,</span><span class="token">
147+
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">path</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token"> </span><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">=&gt;</span><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">docs</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token">,</span><span class="token">
148+
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">target</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token"> </span><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">=&gt;</span><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">private-docs</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token">,</span><span class="token">
149+
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">token</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token"> </span><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">=&gt;</span><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">${ACME_PAT}</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6a737d;--phiki-dark-color: #6a737d;">//</span><span class="token" style="color: #6a737d;--phiki-dark-color: #6a737d;"> read from the ACME_PAT environment variable</span><span class="token" style="color: #6a737d;--phiki-dark-color: #6a737d;">
150+
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">username</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token"> </span><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">=&gt;</span><span class="token"> </span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">doc-bot</span><span class="token" style="color: #032f62;--phiki-dark-color: #9ecbff;">'</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6a737d;--phiki-dark-color: #6a737d;">//</span><span class="token" style="color: #6a737d;--phiki-dark-color: #6a737d;"> optional; defaults to x-access-token</span><span class="token" style="color: #6a737d;--phiki-dark-color: #6a737d;">
151+
</span></span><span class="line"><span class="token"> </span><span class="token">]</span><span class="token">,</span><span class="token">
152+
</span></span><span class="line"><span class="token">]</span><span class="token">;</span><span class="token">
153+
</span></span></code></pre>
154+
<ul>
155+
<li><strong><code>'token' =&gt; '${ENV_VAR_NAME}'</code></strong> is the recommended form: DocSmith reads the variable from the environment at sync time and fails with a clear message if it is unset. A literal token string also works, but hardcoding secrets in a committed file is discouraged.</li>
156+
<li><strong>Automatic fallbacks</strong> — if no <code>token</code> key is present, DocSmith uses <code>DOCSMITH_TOKEN</code> for any HTTPS host, and <code>GITHUB_TOKEN</code> / <code>GH_TOKEN</code> only for repositories on github.com. GitHub tokens are never sent to third-party hosts, and fallback tokens are never attached to plain-HTTP URLs.</li>
157+
<li><strong>Never commit tokens.</strong> Keep them in your shell profile or <code>.env</code>, and let CI inject them via repository secrets.</li>
158+
</ul>
132159
<h2 id="programmatic-use">Programmatic use</h2>
133160
<pre class="phiki language-php github-light phiki-themes github-dark" data-language="php" style="background-color: #fff;color: #24292e;--phiki-dark-background-color: #24292e;--phiki-dark-color: #e1e4e8;"><code><span class="line"><span class="token" style="color: #d73a49;--phiki-dark-color: #f97583;">use</span><span class="token"> </span><span class="token" style="color: #005cc5;--phiki-dark-color: #79b8ff;">Docsmith</span><span class="token" style="color: #005cc5;--phiki-dark-color: #79b8ff;">\</span><span class="token" style="color: #005cc5;--phiki-dark-color: #79b8ff;">RemoteSources</span><span class="token" style="color: #005cc5;--phiki-dark-color: #79b8ff;">\</span><span class="token" style="color: #005cc5;--phiki-dark-color: #79b8ff;">RemoteSources</span><span class="token">;</span><span class="token">
134161
</span></span><span class="line"><span class="token">
@@ -147,7 +174,7 @@ <h2 id="programmatic-use">Programmatic use</h2>
147174
</article>
148175
<nav class="pager" aria-label="Page navigation"><a class="pager-link" href="../docs-hub/"><span>Previous</span><strong>Docs Hub</strong></a><a class="pager-link pager-link-next" href="../workflows/"><span>Next</span><strong>Workflows</strong></a></nav>
149176
</main>
150-
<aside class="toc-sidebar" data-docsmith-toc><p class="toc-title">On this page</p><nav class="toc-links"><a class="toc-link toc-link-level-2" href="#works-with-any-build" data-docsmith-toc-link="works-with-any-build">Works with any build</a><a class="toc-link toc-link-level-2" href="#how-it-works" data-docsmith-toc-link="how-it-works">How it works</a><a class="toc-link toc-link-level-2" href="#commands" data-docsmith-toc-link="commands">Commands</a><a class="toc-link toc-link-level-2" href="#source-options" data-docsmith-toc-link="source-options">Source options</a><a class="toc-link toc-link-level-3" href="#caching-and-determinism" data-docsmith-toc-link="caching-and-determinism">Caching and determinism</a><a class="toc-link toc-link-level-2" href="#safety" data-docsmith-toc-link="safety">Safety</a><a class="toc-link toc-link-level-2" href="#programmatic-use" data-docsmith-toc-link="programmatic-use">Programmatic use</a></nav></aside>
177+
<aside class="toc-sidebar" data-docsmith-toc><p class="toc-title">On this page</p><nav class="toc-links"><a class="toc-link toc-link-level-2" href="#works-with-any-build" data-docsmith-toc-link="works-with-any-build">Works with any build</a><a class="toc-link toc-link-level-2" href="#how-it-works" data-docsmith-toc-link="how-it-works">How it works</a><a class="toc-link toc-link-level-2" href="#commands" data-docsmith-toc-link="commands">Commands</a><a class="toc-link toc-link-level-2" href="#source-options" data-docsmith-toc-link="source-options">Source options</a><a class="toc-link toc-link-level-3" href="#caching-and-determinism" data-docsmith-toc-link="caching-and-determinism">Caching and determinism</a><a class="toc-link toc-link-level-2" href="#safety" data-docsmith-toc-link="safety">Safety</a><a class="toc-link toc-link-level-2" href="#private-repositories" data-docsmith-toc-link="private-repositories">Private repositories</a><a class="toc-link toc-link-level-2" href="#programmatic-use" data-docsmith-toc-link="programmatic-use">Programmatic use</a></nav></aside>
151178
</div>
152179
<div class="search-overlay" data-docsmith-search-overlay hidden role="dialog" aria-label="Search documentation">
153180
<div class="search-overlay-backdrop" data-docsmith-search-overlay-close></div>

0 commit comments

Comments
 (0)