diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..74e8d6fb9f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.yaml] +indent_size = 2 diff --git a/.github/workflows/build-website.yaml b/.github/workflows/build-website.yaml new file mode 100644 index 0000000000..1f5916bcc8 --- /dev/null +++ b/.github/workflows/build-website.yaml @@ -0,0 +1,132 @@ +name: Build website + +on: + workflow_call: + workflow_dispatch: + +jobs: + build-docs: + name: Build docs (${{ matrix.kind }}) + runs-on: ubuntu-latest + strategy: + matrix: + kind: [internal, public] + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: time-rs/time + + - name: Cache cargo output + uses: Swatinem/rust-cache@v2 + + - name: Install toolchain + uses: dtolnay/rust-toolchain@nightly + + - name: Generate documentation + run: cargo doc -p time --all-features ${{ matrix.kind == 'internal' && '--document-private-items' || '' }} + env: + RUSTDOCFLAGS: --cfg __time_03_docs ${{ matrix.kind == 'internal' && '--document-hidden-items' || '' }} -Zunstable-options --generate-link-to-definition + + - name: Upload artifact + uses: actions/upload-artifact@v4 + id: docs-upload + with: + name: ${{ matrix.kind }}-docs + path: target/doc/ + retention-days: 1 + if-no-files-found: error + compression-level: 9 + + build-book: + name: Build book + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: time-rs/book + + - name: Check for typos + uses: crate-ci/typos@master + + - name: Install mdbook + uses: taiki-e/install-action@mdbook + + - name: Build diagrams + run: | + pip install -r diagrams/requirements.txt + mkdir src/diagrams + python diagrams/diagrams.py + + - name: Build book + run: mdbook build + + - name: Upload artifact + uses: actions/upload-artifact@v4 + id: book-upload + with: + name: book + path: book/ + retention-days: 1 + if-no-files-found: error + compression-level: 9 + + deploy: + name: Deploy + runs-on: ubuntu-latest + needs: [build-docs, build-book] + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: | + website + + - name: Download internal docs + uses: actions/download-artifact@v4 + with: + name: internal-docs + path: website/internal-api + + - name: Download public docs + uses: actions/download-artifact@v4 + with: + name: public-docs + path: website/api + + - name: Download book + uses: actions/download-artifact@v4 + with: + name: book + path: website/book + + - name: Upload website + uses: actions/upload-pages-artifact@v3 + with: + path: website + + - name: Deploy + id: deployment + uses: actions/deploy-pages@v4 + + - name: Delete artifacts + uses: geekyeggo/delete-artifact@v4 + with: + name: | + internal-docs + public-docs + book + github-pages + failOnError: false + if: always() + continue-on-error: true diff --git a/.github/workflows/trigger-deploy.yaml b/.github/workflows/trigger-deploy.yaml new file mode 100644 index 0000000000..f2fe3a65c8 --- /dev/null +++ b/.github/workflows/trigger-deploy.yaml @@ -0,0 +1,28 @@ +name: Deploy + +env: + REPO: time-rs/time-rs.github.io + WORKFLOW: build-website.yaml + GH_TOKEN: ${{ secrets.WEBSITE_PUBLISHING }} + +on: + workflow_call: + workflow_dispatch: + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + permissions: + actions: write + + steps: + - name: Trigger deploy + id: trigger + run: | + gh workflow run --repo ${{ env.REPO }} ${{ env.WORKFLOW }} + sleep 3 # Let the run be created + echo "RUN_ID=$(gh run list --repo ${{ env.REPO }} --json databaseId --workflow ${{ env.WORKFLOW }} --limit 1 | jq -r '.[0].databaseId')" >> "$GITHUB_OUTPUT" + + - name: Wait for deployment + run: gh run watch --repo ${{ env.REPO }} ${{ steps.trigger.outputs.RUN_ID }} --interval 1 --exit-status diff --git a/website/icons/book.svg b/website/icons/book.svg new file mode 100644 index 0000000000..501abcc847 --- /dev/null +++ b/website/icons/book.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/icons/code.svg b/website/icons/code.svg new file mode 100644 index 0000000000..86c95a2cdc --- /dev/null +++ b/website/icons/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/icons/cogs.svg b/website/icons/cogs.svg new file mode 100644 index 0000000000..7aa51009e8 --- /dev/null +++ b/website/icons/cogs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/icons/github.svg b/website/icons/github.svg new file mode 100644 index 0000000000..53bd7b2d2a --- /dev/null +++ b/website/icons/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/icons/logo.svg b/website/icons/logo.svg new file mode 100644 index 0000000000..74c2070b21 --- /dev/null +++ b/website/icons/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000000..0a26489b90 --- /dev/null +++ b/website/index.html @@ -0,0 +1,43 @@ + + + + + + + time-rs + + + + + +
+
+ + time-rs +
+ +
+ + GitHub + +
+
+ +
+ + +
Book
+
+ + +
Public API
+
+ + +
Internal API
+
+
+ + + + \ No newline at end of file diff --git a/website/styles.css b/website/styles.css new file mode 100644 index 0000000000..324c3d94f3 --- /dev/null +++ b/website/styles.css @@ -0,0 +1,111 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +:root { + --foreground: #000; + --background: #eee; + + color: var(--foreground); + background-color: var(--background); + + height: 100%; + width: 100%; + padding: 1.5rem; +} + +@media screen and (prefers-color-scheme: dark) { + :root { + --foreground: #fff; + --background: #000; + } + + img:not(.no-invert) { + filter: invert(1); + } +} + +body { + height: 100%; + width: 100%; + font-size: 2rem; + font-family: monospace; + text-align: center; + + display: grid; + grid-template: auto / repeat(3, 1fr); + grid-auto-rows: 1fr; + gap: 2rem; +} + +header, +main { + display: contents; +} + +.branding { + grid-row: 1; + grid-column: 1 / -1; +} + +a { + color: unset; + text-decoration: none; + transition: 150ms; +} + +a .hover-underline::after { + content: ''; + display: block; + width: 0; + margin: 0 auto; + border-bottom: 1px solid var(--foreground); + transition: width 200ms; +} + +a:hover .hover-underline::after { + width: 100%; + transition: width 200ms; +} + +header img { + height: 2.5rem; + vertical-align: text-bottom; +} + +header .right-box { + grid-row: 1; + grid-column: -2 / -1; + text-align: right; + font-size: 0; +} + +header .right-box a:not(:first-of-type) { + margin-left: 2rem; +} + +main a { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; +} + +main img { + max-height: 8rem; + max-width: min(8rem, 25vw); +} + +@media (max-width: 800px) { + body { + grid-template: auto auto / 1fr; + } + + header .right-box { + grid-row: 2; + text-align: center; + } +}