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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ jobs:
# Only a stable release changes what /releases/latest resolves to, so a
# pre-release would rebuild the site to byte-identical output.
#
# Dispatched against main on purpose: the github-pages environment only
# Dispatched against main on purpose: the website environment only
# permits `main` to deploy, so docs.yml's old `on: release` trigger ran
# with a tag ref and failed its deploy every time. See docs.yml.
if: ${{ steps.release.outputs.is_prerelease == 'false' }}
Expand Down
48 changes: 28 additions & 20 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ on:
#
# That rebuild is a `workflow_dispatch` fired by build.yml once the release is
# published, NOT an `on: release` trigger. A release event runs with
# github.ref = refs/tags/vX.Y.Z, and the github-pages environment only allows
# `main` to deploy, so the deploy job failed on every stable release (it never
# github.ref = refs/tags/vX.Y.Z, and the deploy environment only allows `main`
# to deploy, so the deploy job failed on every stable release (it never
# surfaced earlier because pre-releases skipped the build entirely). Dispatching
# against main both satisfies that policy and publishes main's docs rather than
# the release branch's older snapshot.
Expand Down Expand Up @@ -119,33 +119,41 @@ jobs:
exit 1
fi
- name: Upload artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: website-build
path: website/build
# v4 stopped bundling dotfiles by default. Nothing in website/build
# is hidden today — the deployed artifact from 7c4827b9 was checked
# and contains no dot-entries at all, so this changes nothing now
# (Docusaurus only writes a `.nojekyll` on its own `deploy` command,
# not in a plain `build`). It is set so that stays true by accident
# rather than by omission: a `.well-known/` for domain verification
# or security.txt is the realistic case, and under the v4+ default it
# would vanish from the deploy silently. `.git` and `.github` are
# excluded regardless of this flag.
retention-days: 7
# Off by default since v4. Nothing in website/build is hidden today,
# but a `.well-known/` for domain verification or security.txt is the
# realistic case, and it would vanish from the deploy silently.
include-hidden-files: true

# The site is a Cloudflare Worker with static assets only (website/wrangler.jsonc).
# The token lives in the `website` environment, which only `main` may deploy
# from, so neither a PR nor a dispatch on another branch can read it.
deploy:
name: Deploy to GitHub Pages
name: Deploy to Cloudflare
runs-on: ubuntu-latest
needs: build
if: >-
(github.event_name == 'push' && github.ref == 'refs/heads/main')
|| (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
pages: write
id-token: write
name: website
url: https://getopenscreen.com
steps:
- id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
sparse-checkout: website/wrangler.jsonc
sparse-checkout-cone-mode: false
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: website-build
path: website/build
- name: Deploy
working-directory: website
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: npx --yes wrangler@4.145.0 deploy
4 changes: 2 additions & 2 deletions technical-documentation/engineering/ci-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ flowchart TD
CI --> BuildSmoke[Vite build]
CI --> Semantic[semantic PR title]
Docs["docs.yml<br/>website changes or dispatch"] --> DocsBuild[website build artifact]
DocsBuild --> DocsDeploy[GitHub Pages deploy on main]
DocsBuild --> DocsDeploy[Cloudflare deploy on main]
end

subgraph T2["Tier 2 — native and release builds"]
Expand Down Expand Up @@ -138,4 +138,4 @@ Each workflow needs variables or credentials, and where it checks for them decid

Release platform artifacts have 30-day Actions retention. `publish-release` copies the NSIS installer, two architecture-specific DMGs when present, and Linux packages into the GitHub release. It intentionally does not download the independently uploaded Store artifact. A stable published release then fans out to Homebrew, WinGet, and AUR.

Diagnostic artifacts remain Actions-only for 14 days. Whisper archives remain Actions-only for 30 days and are used as a binary-refresh output rather than being downloaded by the release workflow. The website build artifact flows only into GitHub Pages deployment.
Diagnostic artifacts remain Actions-only for 14 days. Whisper archives remain Actions-only for 30 days and are used as a binary-refresh output rather than being downloaded by the release workflow. The website build artifact flows only into the Cloudflare deployment, which reads its token from the `website` environment, restricted to `main`.
2 changes: 2 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ node_modules/
build/
.docusaurus/
.cache-loader/
# wrangler dev's local state
.wrangler/

# Generated files
.bundle-stats
Expand Down
8 changes: 3 additions & 5 deletions website/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# OpenScreen docs site

Docusaurus 3 site. Lives in `website/` inside the monorepo. Deployed to GitHub Pages via `.github/workflows/docs.yml`.
Docusaurus 3 site. Lives in `website/` inside the monorepo. Deployed to Cloudflare (a Worker serving static assets, `wrangler.jsonc`) via `.github/workflows/docs.yml`. `www-redirect/` is a separate Worker that sends www.getopenscreen.com to the apex; it is deployed by hand.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Develop

```sh
cd website
npm install
npm run dev # http://localhost:3000/openscreen/
npm run dev # http://localhost:3000/
```

## Build
Expand All @@ -25,6 +25,4 @@ npm run typecheck

## Notes

- Site URL: <https://getopenscreen.github.io/openscreen/>
- The base URL is `/openscreen/` because the org-level Pages site hosts multiple projects.
- Docs migration from `docs/` (root) → `website/docs/` happens in a follow-up PR. For now only the intro page is published.
- Site URL: <https://getopenscreen.com/>, served from the domain root (`baseUrl: "/"`).
18 changes: 10 additions & 8 deletions website/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,13 @@ export default async function createConfig(): Promise<Config> {
tagline: "A free, open-source screen recorder and editor.",
favicon: "img/logo-icon.png",

// Pages serves this from the custom domain's root, not from
// getopenscreen.github.io/openscreen/, so baseUrl has to be "/" — a project
// baseUrl would prefix every asset URL with a path the server has nothing at.
// Served from the custom domain's root, so baseUrl has to be "/": a
// project baseUrl would prefix every asset URL with a path the server has
// nothing at.
url: SITE_URL,
baseUrl: "/",

// Every page is emitted as <route>/index.html, and GitHub Pages 301s the
// Every page is emitted as <route>/index.html, and Cloudflare redirects the
// extensionless form to the trailing-slash one. Leaving this unset makes
// Docusaurus advertise the pre-redirect URL in both <link rel="canonical">
// and sitemap.xml, so every indexed URL costs a crawler an extra hop to a
Expand Down Expand Up @@ -439,11 +439,13 @@ export default async function createConfig(): Promise<Config> {
// for a renamed tag: a translated build has no blog, so that copy
// would be the only thing under /fr/blog/, a page nothing links to,
// redirecting a French URL to an English one. /fr/discord/ would be
// a second, unlinked copy of the invite redirect, and crawlers read
// llms.txt and robots.txt at the root only. The rest (img, video)
// stays: pages resolve images through the locale's baseUrl.
// a second, unlinked copy of the invite redirect, crawlers read
// llms.txt and robots.txt at the root only, and Cloudflare reads
// _headers there only, serving any other copy as a public file. The
// rest (img, video) stays: pages resolve images through the locale's
// baseUrl.
if (LOCALE !== "en") {
for (const entry of [BLOG_PATH, "discord", "llms.txt", "robots.txt"]) {
for (const entry of [BLOG_PATH, "discord", "llms.txt", "robots.txt", "_headers"]) {
await rm(path.join(outDir, entry), { recursive: true, force: true });
}
}
Expand Down
2 changes: 1 addition & 1 deletion website/i18n/TRANSLATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The site is translated into `fr`, `es`, `pt-BR`, `ja`, `zh-CN`, `zh-TW` and `de`

## What is translated, and what is not

- **Translated:** everything but the blog: the landing page, `/download/`, the docs, the comparison, platform and feature pages (`src/pages/**/*.mdx`), the navbar, the docs sidebar, the footer and the theme (404 page, pagination, "last updated"…). The translated 404 page only shows after a click inside the site: GitHub Pages answers every missing URL, `/fr/…` included, with the English one.
- **Translated:** everything but the blog: the landing page, `/download/`, the docs, the comparison, platform and feature pages (`src/pages/**/*.mdx`), the navbar, the docs sidebar, the footer and the theme (404 page, pagination, "last updated"…). A missing URL under `/<locale>/` gets that locale's 404 page.
- **English only:** the blog, a dated development journal. A translated build does not contain it, and links to it from translated pages go to the English blog (see below).
- **The build enforces it:** a locale missing any doc or `.mdx` page fails `npm run build`, because Docusaurus would otherwise publish the English file under `/<locale>/` marked as your language.

Expand Down
7 changes: 7 additions & 0 deletions website/static/_headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Read by Cloudflare at the root of the deployed build (website/wrangler.jsonc).
# Docusaurus puts a content hash in the name of every file under assets/, so a
# cached copy can never go stale.
/assets/*
Cache-Control: public, max-age=31536000, immutable
/:locale/assets/*
Cache-Control: public, max-age=31536000, immutable
21 changes: 21 additions & 0 deletions website/wrangler.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Cloudflare Workers config for getopenscreen.com, deployed by .github/workflows/docs.yml.
// Assets only, no Worker script: Cloudflare serves static assets without counting
// them against the Workers request quota.
{
"name": "getopenscreen-website",
// An identifier, not a credential: the API token in CI is the secret.
"account_id": "49f0ef8f15d646deb80a7e7d675a4910",
"compatibility_date": "2026-10-01",
"assets": {
"directory": "./build",
// The nearest 404.html, so /fr/missing/ gets the French page, not the English one.
"not_found_handling": "404-page"
},
// A route on the proxied apex, not a custom domain: Cloudflare will not attach a
// custom domain over existing DNS records (error 100117). With a route, the move off
// GitHub Pages was only switching those records to proxied, with no gap.
"routes": [{ "pattern": "getopenscreen.com/*", "zone_name": "getopenscreen.com" }],
// The site has one address; a workers.dev copy would be a duplicate of it.
"workers_dev": false,
"preview_urls": false
}
11 changes: 11 additions & 0 deletions website/www-redirect/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// www.getopenscreen.com only: every request goes to the same path on the apex, as
// GitHub Pages did. Deployed by hand (`npx wrangler deploy` in this folder); it has no
// reason to change with the site.
export default {
fetch(request) {
const url = new URL(request.url);
url.protocol = "https:";
url.hostname = "getopenscreen.com";
return Response.redirect(url.toString(), 301);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},
};
11 changes: 11 additions & 0 deletions website/www-redirect/wrangler.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Redirects www to the apex (index.js). The site itself is ../wrangler.jsonc.
{
"name": "getopenscreen-www-redirect",
"account_id": "49f0ef8f15d646deb80a7e7d675a4910",
"main": "index.js",
"compatibility_date": "2026-10-01",
"workers_dev": false,
"preview_urls": false,
// A route, like the site's: the www record only has to be proxied.
"routes": [{ "pattern": "www.getopenscreen.com/*", "zone_name": "getopenscreen.com" }]
}
Loading