Documents & Static Content: The Repo โ SharePoint Pipeline
Lesson 10: Documents & Static Content โ The Repo โ SharePoint Pipeline
You asked the sharpest question of the course: can a GitHub repo act as the document repository that feeds SharePoint? Yes โ with one crucial framing decision that determines whether your life is easy or miserable: decide the system of record per artifact type, then publish one way.
Where documents should live (the consensus)
Concretely: PDFs, Word/Excel finals, and official materials belong in SharePoint libraries. Code, templates, scripts, and the markdown source of documents belong in git. Binaries that only exist for distribution (release artifacts) can be pushed from CI and forgotten.
The mechanisms: verified commands
Uploading a file into a library with metadata is a solved problem in both tools. The essential set:
| Operation | CLI for Microsoft 365 | PnP PowerShell |
|---|---|---|
| Create folder | m365 spo folder add --webUrl <site> --folder "/Shared Documents" --name "Policies" | Add-PnPFolder -Name "Policies" -Folder "Shared Documents" |
| Upload file | m365 spo file add --webUrl <site> --folder "/Shared Documents/Policies" --path ./policy.pdf --name policy.pdf | Add-PnPFile -Path ./policy.pdf -Folder "Shared Documents/Policies" |
| Set metadata | m365 spo listitem set --webUrl <site> --listId <guid> --id <item> --values "Category='Policy';Owner='Legal'" | Add-PnPFile โฆ -Values @{ Category = "Policy" } (or Set-PnPListItem after upload) |
| Check in (required-checkout libraries) | โ | Set-PnPFileCheckedIn -Url "/sites/x/Shared Documents/policy.pdf" -CheckInType Major |
Add-PnPFile -Values / content-type-aware upload) so nothing lands as a broken, incomplete item. If you're publishing a docs folder, keep the repo's folder structure mirrored 1:1 into the library โ it makes the mapping trivial and reviewable.
An end-to-end "docs folder โ library" pipeline
Triggered only when docs/ changes, this workflow walks every file in the folder and publishes it to Shared Documents/<repo-folder> using the PnP PowerShell OIDC action from Lesson 8 (no certificate secret needed):
name: Publish docs to SharePoint
on:
push:
branches: [ main ]
paths: [ 'docs/**' ] # runs only when the docs folder changes
permissions:
id-token: write
contents: read
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Publish docs via PnP PowerShell
uses: anoopt/action-pnp-powershell-with-oidc@v1.3.0
with:
TENANT_ID: ${{ secrets.TENANT_ID }}
TENANT_NAME: ${{ secrets.TENANT_NAME }}
CLIENT_ID: ${{ secrets.CLIENT_ID }}
SITE_URL: "https://contoso.sharepoint.com/sites/intranet"
PNP_POWERSHELL_SCRIPT: |
$root = "Shared Documents/Published Docs"
$files = Get-ChildItem -Path "./docs" -Recurse -File
foreach ($file in $files) {
# mirror the repo subfolder structure inside the library
$rel = $file.FullName.Substring((Get-Location).Path.Length + 1)
$target = Join-Path $root (Split-Path $rel -Parent)
Resolve-PnPFolder -SiteRelativeFolder $target | Out-Null
Add-PnPFile -Path $file.FullName -Folder $target `
-FileName $file.Name -Values @{ Source = "github" }
}
Same shape with CLI for Microsoft 365: run m365 login --authType certificate โฆ (Lesson 8's flags), then loop m365 spo folder add + m365 spo file add per file. Prefer the scripted route when you need metadata, content types, or exact behavior; it's fully under your control and uses the same auth you already set up.
Marketplace actions for repo โ library sync
| Action | What it does | Caveats |
|---|---|---|
| SharePoint Mirror Sync (MarkusMcNugen) | Smart folder sync with hash-based change detection, glob patterns, markdown โ HTML conversion | Least-active maintenance; verify it against your tenant before trusting it in prod |
| Upload File to Sharepoint (cringdahl) | Glob-pattern file uploads, client ID/secret auth, sovereign clouds | Simple uploads only; simple auth story |
| Publish to Sharepoint (obrassard + forks) | Zips repo and uploads archive | โ ๏ธ Original used ACS auth, retired April 2026 โ only use the OIDC fork (UASI) |
| PnP PowerShell with OIDC (anoopt) | Runs any PnP PowerShell against a site โ the general-purpose escape hatch | Needs Entra federated credential setup |
Rule of thumb: scripted CLI/PnP for control, Mirror Sync for "keep this folder in sync," and treat any action with deprecated auth as radioactive.
Static content for pages โ and the "is SharePoint a website host?" question
"Static content" for SharePoint usually means images, CSS, JS, or HTML that pages and web parts reference. Your options, in order of fit:
- Bundled with SPFx (Lesson 3โ5): assets travel inside the
.sppkg. Best for component assets โ no external hosting at all. - Document library + SharePoint CDN (intranet): enable the library as a CDN origin (
m365 spo cdn origin add --originUrl "<site>/Shared Documents/cdn" --type Private; also a Public type) and reference assets by CDN URL. Private is right for internal content;m365 spo cdn get / policymanage it. - External host (public): GitHub Pages, Azure Static Web Apps, or blob storage + CDN. Use these when the content must be reachable outside your tenant.
Deciding what goes where
| Artifact | System of record | How it reaches SharePoint |
|---|---|---|
| SPFx code, templates, site scripts, page recipes, workflow YAML | GitHub repo | GitHub Actions (Lessons 8โ9) |
| Markdown/HTML doc sources that change with code | GitHub repo | CI renders/publishes to a library (this lesson) |
| Final documents & official files (PDF, Office) | SharePoint library | Authored there, or one-way CI publish from repo sources |
| Images/static assets for pages | Library + CDN origin (intranet) or external CDN (public) | Upload via the same file commands |
| Public static website | GitHub Pages / Azure SWA | Not SharePoint โ deploy to the static host |
.sppkg), structure (PnP templates/site scripts), pages (recipes), and content (published files). Every piece is versioned, reviewed, and machine-deployed โ and every piece respects the line between what git owns and what SharePoint owns.
๐ง Knowledge Check
1. Which command pair uploads a file to a document library with PnP PowerShell and sets its metadata in the same step?
2. What is the recommended direction of a repo โ SharePoint content publish?
3. Your team needs a public documentation website generated from a repo. Best call?