diff --git a/.envrc.example b/.envrc.example new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc.example @@ -0,0 +1 @@ +use flake diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000..431e9a6 --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "penumbra-guide" + } +} diff --git a/.github/workflows/firebase-hosting-merge.yml b/.github/workflows/firebase-hosting-merge.yml new file mode 100644 index 0000000..adf7977 --- /dev/null +++ b/.github/workflows/firebase-hosting-merge.yml @@ -0,0 +1,29 @@ +# This file was auto-generated by the Firebase CLI +# https://github.com/firebase/firebase-tools +# +# It will build the static site and deploy it to the live prod URL. + +name: Deploy to Firebase Hosting on merge +on: + push: + branches: + - main +jobs: + build_and_deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install nix + uses: DeterminateSystems/nix-installer-action@main + - name: load nix cache + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: build static docroot + run: nix develop --command just build + + - uses: FirebaseExtended/action-hosting-deploy@v0 + with: + repoToken: ${{ secrets.GITHUB_TOKEN }} + firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_PENUMBRA_GUIDE }} + channelId: live + projectId: penumbra-guide diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml new file mode 100644 index 0000000..1088350 --- /dev/null +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -0,0 +1,31 @@ +# This file was auto-generated by the Firebase CLI +# https://github.com/firebase/firebase-tools +# +# It will build the static site, deploy it to an ephemeral URL, and post a comment +# to the PR with that URL for review. + +name: Deploy to Firebase Hosting on PR +on: pull_request +permissions: + checks: write + contents: read + pull-requests: write +jobs: + build_and_preview: + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install nix + uses: DeterminateSystems/nix-installer-action@main + - name: load nix cache + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: build static docroot + run: nix develop --command just build + + - uses: FirebaseExtended/action-hosting-deploy@v0 + with: + repoToken: ${{ secrets.GITHUB_TOKEN }} + firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_PENUMBRA_GUIDE }} + projectId: penumbra-guide diff --git a/.gitignore b/.gitignore index 70eb913..59e779f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ yarn-error.log* # Local env files .env*.local +.envrc +.direnv/ # Vercel .vercel @@ -63,3 +65,6 @@ Thumbs.db # Nextra specific .nextra + +# Firebase static site hosting +.firebase/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..641942f --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Penumbra Guide + +This repo holds the end-user documentation for Penumbra, hosted at [https://guide.penumbra.zone](https://guide.penumbra.zone). + +## Contributing + +1. Install [nix](https://nixos.org/download/). +2. Run `nix develop --enable-experimental-features "nix-command flake"` +3. Run `just dev` for a livereload environment. + +## Directory layout + +The documentation source resides in `pages/`. Docs files are written in [Markdown](https://www.markdownguide.org/), +and served via [Nextra](https://nextra.site/). diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..9dcaab6 --- /dev/null +++ b/firebase.json @@ -0,0 +1,32 @@ +{ + "hosting": { + "public": "out", + "redirects": [ + { + "source": "/main/index.html", + "destination": "/", + "type": 302 + }, + { + "regex": "/main/pd(?P.*)", + "destination": "/node/pd:page", + "type": 302 + }, + { + "regex": "/main/pclientd(?P.*)", + "destination": "/node/pclientd:page", + "type": 302 + }, + { + "regex": "/main/(?P.*)", + "destination": "/:page", + "type": 302 + }, + { + "source": "/node/pd/join-testnet.html", + "destination": "/node/pd/join-network.html", + "type": 302 + } + ] + } +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..2684eab --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1721562059, + "narHash": "sha256-Tybxt65eyOARf285hMHIJ2uul8SULjFZbT9ZaEeUnP8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "68c9ed8bbed9dfce253cc91560bf9043297ef2fe", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..3694273 --- /dev/null +++ b/flake.nix @@ -0,0 +1,26 @@ +# in flake.nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem + (system: + let + pkgs = import nixpkgs { + inherit system ; + }; + in + with pkgs; + { + devShells.default = mkShell { + buildInputs = [ + firebase-tools + just + pnpm + ]; + }; + } + ); +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..de8c616 --- /dev/null +++ b/justfile @@ -0,0 +1,11 @@ +# display this help menu +list: + @just --list + +# build static site +build: + pnpm install && pnpm build + +# run dev env with livereload, for local editing +dev: + pnpm dev diff --git a/next.config.js b/next.config.js index d6a4679..850c094 100644 --- a/next.config.js +++ b/next.config.js @@ -3,7 +3,14 @@ const withNextra = require('nextra')({ themeConfig: './theme.config.jsx' }) -module.exports = withNextra() +module.exports = withNextra({ + // Attempt to generate static site, via https://nextjs.org/docs/pages/building-your-application/deploying/static-exports + output: 'export', + // Disable image optimization, as it doesn't work for SSG. + images: { + unoptimized: true, + }, +}) // If you have other Next.js configurations, you can pass them as the parameter: // module.exports = withNextra({ /* other next.js config */ }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c56103f..8ea2e68 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,13 @@ importers: dependencies: next: specifier: ^14.2.5 - version: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 14.2.5(react-dom@18.3.1)(react@18.3.1) nextra: specifier: ^2.13.4 - version: 2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.13.4(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) nextra-theme-docs: specifier: ^2.13.4 - version: 2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.13.4(next@14.2.5)(nextra@2.13.4)(react-dom@18.3.1)(react@18.3.1) react: specifier: ^18.3.1 version: 18.3.1 @@ -1408,9 +1408,9 @@ snapshots: '@braintree/sanitize-url@6.0.4': {} - '@headlessui/react@1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@headlessui/react@1.7.19(react-dom@18.3.1)(react@18.3.1)': dependencies: - '@tanstack/react-virtual': 3.8.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tanstack/react-virtual': 3.8.3(react-dom@18.3.1)(react@18.3.1) client-only: 0.0.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -1540,7 +1540,7 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.6.3 - '@tanstack/react-virtual@3.8.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-virtual@3.8.3(react-dom@18.3.1)(react@18.3.1)': dependencies: '@tanstack/virtual-core': 3.8.3 react: 18.3.1 @@ -2689,7 +2689,7 @@ snapshots: nanoid@3.3.7: {} - next-mdx-remote@4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-mdx-remote@4.4.1(react-dom@18.3.1)(react@18.3.1): dependencies: '@mdx-js/mdx': 2.3.0 '@mdx-js/react': 2.3.0(react@18.3.1) @@ -2700,19 +2700,19 @@ snapshots: transitivePeerDependencies: - supports-color - next-seo@6.5.0(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-seo@6.5.0(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): dependencies: - next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next-themes@0.2.1(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.2.1(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): dependencies: - next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.5(react-dom@18.3.1)(react@18.3.1): dependencies: '@next/env': 14.2.5 '@swc/helpers': 0.5.5 @@ -2737,9 +2737,9 @@ snapshots: - '@babel/core' - babel-plugin-macros - nextra-theme-docs@2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + nextra-theme-docs@2.13.4(next@14.2.5)(nextra@2.13.4)(react-dom@18.3.1)(react@18.3.1): dependencies: - '@headlessui/react': 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@headlessui/react': 1.7.19(react-dom@18.3.1)(react@18.3.1) '@popperjs/core': 2.11.8 clsx: 2.1.1 escape-string-regexp: 5.0.0 @@ -2748,18 +2748,18 @@ snapshots: git-url-parse: 13.1.1 intersection-observer: 0.12.2 match-sorter: 6.3.4 - next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-seo: 6.5.0(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-themes: 0.2.1(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - nextra: 2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(react-dom@18.3.1)(react@18.3.1) + next-seo: 6.5.0(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) + next-themes: 0.2.1(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) + nextra: 2.13.4(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) scroll-into-view-if-needed: 3.1.0 zod: 3.23.8 - nextra@2.13.4(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + nextra@2.13.4(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): dependencies: - '@headlessui/react': 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@headlessui/react': 1.7.19(react-dom@18.3.1)(react@18.3.1) '@mdx-js/mdx': 2.3.0 '@mdx-js/react': 2.3.0(react@18.3.1) '@napi-rs/simple-git': 0.1.17 @@ -2771,8 +2771,8 @@ snapshots: gray-matter: 4.0.3 katex: 0.16.11 lodash.get: 4.4.2 - next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-mdx-remote: 4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(react-dom@18.3.1)(react@18.3.1) + next-mdx-remote: 4.4.1(react-dom@18.3.1)(react@18.3.1) p-limit: 3.1.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1)