Skip to content

Commit 132444b

Browse files
committed
docs: fix ZCP dark mode and sidebar, embed coding agents video, add GitHub lifecycle automation
1 parent b26519d commit 132444b

8 files changed

Lines changed: 210 additions & 220 deletions

File tree

apps/docs/.env.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ AI_ASSISTANT_URL=
77
AI_API_ASSISTANT_TOKEN=
88
AI_WEBSITE_ID=
99
AI_API_ASSISTANT_RECAPTCHA_SITE_KEY=
10-
CLOUDINARY_CLOUD_NAME=
10+
CLOUDINARY_CLOUD_NAME=
11+
GTAG_TRACKING_ID=

apps/docs/content/features/coding-agents.mdx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ import IntroAgentVisual from '@site/src/components/IntroAgentVisual';
99

1010
Zerops was built on the idea of **environment parity** — giving developers the full development lifecycle, from remote development to highly available production, with the observability and developer tools for maximum flexibility, and sensible defaults so the configs stay reasonable. Turns out that's **exactly what coding agents need** to produce and iterate on production-ready applications.
1111

12+
<div className="w-full flex justify-center my-4">
13+
<iframe
14+
width="560"
15+
height="315"
16+
src="https://www.youtube.com/embed/spdmTicsIgg?si=laZjTGhiytJRkqoJ"
17+
title="YouTube video player"
18+
frameBorder="0"
19+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
20+
referrerPolicy="strict-origin-when-cross-origin"
21+
allowFullScreen
22+
className="w-full max-w-[560px] aspect-video rounded-xl"
23+
/>
24+
</div>
25+
1226
<br/>
1327

1428
## What is it

apps/docs/content/references/github-integration.mdx

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,25 +106,25 @@ As an alternative to direct integration, you can use GitHub Actions to manage yo
106106
1. **Create Workflow Configuration**
107107

108108
Create a new file at `.github/workflows/deploy.yaml` in your repository:
109-
109+
110110
Basic example:
111111

112112
```yaml
113113
name: Deploy to Zerops
114-
114+
115115
on:
116116
push:
117117
branches:
118118
- main
119-
119+
120120
jobs:
121121
deploy:
122122
runs-on: ubuntu-latest
123-
123+
124124
steps:
125125
- name: Checkout code
126126
uses: actions/checkout@v7
127-
127+
128128
- name: Deploy with Zerops
129129
uses: zeropsio/actions@main
130130
with:
@@ -133,14 +133,14 @@ As an alternative to direct integration, you can use GitHub Actions to manage yo
133133
```
134134
135135
Example with tag matching:
136-
136+
137137
```yaml
138138
name: Deploy to Zerops on Tag
139139

140140
on:
141141
push:
142142
tags:
143-
- 'v[0-9]+\.[0-9]+\.[0-9]+' # Example: v1.0.0, v2.3.4
143+
- 'v[0-9]+\.[0-9]+\.[0-9]+' # Example: v1.0.0, v2.3.4
144144

145145
jobs:
146146
deploy:
@@ -179,3 +179,34 @@ Keep your access token secure and never commit it directly to your repository. T
179179
:::
180180

181181
For more information about GitHub Actions, refer to the [official GitHub Actions documentation](https://docs.github.com/en/actions).
182+
183+
---
184+
185+
## Advanced: Full Lifecycle Automation
186+
187+
:::tip Reference repository
188+
A complete, working example of this pattern is available at [zerops-showcase-deploy](https://github.com/zeropsio/zerops-showcase-deploy), a deployment orchestrator built entirely on GitHub Actions and the Zerops API, no Zerops CLI required. Clone it as a starting point for your own multi-environment pipeline.
189+
:::
190+
191+
The workflow above deploys a single service on push to one branch. This reference repo extends that into a full lifecycle: every feature branch gets its own isolated environment, every PR gets a preview, and stage and prod stay permanent with their data intact across deploys.
192+
193+
### What it sets up
194+
195+
| You do this | Pipeline creates | Lifetime |
196+
| --------------------------- | -------------------------------------------------- | --------------------------- |
197+
| Push to a feature branch | A full isolated environment | Until the branch is deleted |
198+
| Open/update a PR to `stage` | A full isolated preview environment | Until the PR is closed |
199+
| Merge a PR into `stage` | Redeploys app code to the shared stage environment | Permanent, data preserved |
200+
| Push/merge to `main` | Redeploys app code to production | Permanent, data preserved |
201+
202+
Permanent environments keep their databases, caches, queues, and storage across every deploy, only the application code gets updated. Ephemeral environments are created from scratch and torn down automatically when no longer needed, so every developer gets their own isolated copy of the full stack without manual cleanup.
203+
204+
PR previews require a `stage` branch as the pull request target; the repo's setup guide covers creating it.
205+
206+
### How it differs from the basic workflow above
207+
208+
The basic GitHub Actions setup deploys one service to one Zerops project. This pattern manages entire **projects** programmatically instead: it checks whether a project for a given branch or PR already exists, creates one from an import template if not, and deploys to it. The key safeguard is that it never deletes or recreates infrastructure on permanent environments, only ephemeral ones get torn down. This is a reference implementation, not a Zerops-managed service, so you own the repo, the GitHub Actions minutes, and the Zerops API calls it makes on your behalf.
209+
210+
:::tip Full setup guide
211+
Required secrets, customizing the project template for your own services, and the complete workflow reference are all covered in the [repo's README](https://github.com/zeropsio/zerops-showcase-deploy#readme).
212+
:::

apps/docs/docusaurus.config.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { themes as prismThemes } from "prism-react-renderer"
44
const reverseSidebar = require("./src/utils/reverse-sidebar")
55
const excludeSidebarResults = require("./src/utils/exclude-sidebar-results")
66

7+
const gtagTrackingId = process.env.GTAG_TRACKING_ID
8+
79
/** @type {import('@medusajs/docs').MedusaDocusaurusConfig} */
810
const config = {
911
title: "Zerops",
@@ -250,9 +252,13 @@ const config = {
250252
theme: {
251253
customCss: require.resolve("./src/css/custom.css"),
252254
},
253-
gtag: {
254-
trackingID: "xxx",
255-
},
255+
...(gtagTrackingId
256+
? {
257+
gtag: {
258+
trackingID: gtagTrackingId,
259+
},
260+
}
261+
: {}),
256262
sitemap: {
257263
filename: "sitemap-docs.xml",
258264
ignorePatterns: ["/guides/**"],

apps/docs/sidebars.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ module.exports = {
633633
{
634634
type: 'category',
635635
label: 'Remote or local setup',
636+
collapsed: true,
636637
link: {
637638
type: 'doc',
638639
id: 'zcp/setup/choose-workspace',
@@ -657,6 +658,7 @@ module.exports = {
657658
{
658659
type: 'category',
659660
label: 'Build and ship',
661+
collapsed: true,
660662
link: {
661663
type: 'doc',
662664
id: 'zcp/workflows/build-with-zcp',
@@ -681,6 +683,7 @@ module.exports = {
681683
{
682684
type: 'category',
683685
label: 'Security',
686+
collapsed: true,
684687
link: {
685688
type: 'doc',
686689
id: 'zcp/security/trust-model',
@@ -705,6 +708,7 @@ module.exports = {
705708
{
706709
type: 'category',
707710
label: 'Reference',
711+
collapsed: true,
708712
link: {
709713
type: 'doc',
710714
id: 'zcp/reference/index',

apps/docs/src/css/custom.css

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -576,13 +576,27 @@ html[data-theme='dark'] .zcp-agent-flow__node--proof {
576576
}
577577

578578
html[data-theme='dark'] .zcp-lifecycle-stage {
579+
background: rgba(24, 24, 27, 0.72);
580+
border-color: rgba(63, 63, 70, 0.8);
581+
color: #f8fafc;
582+
}
583+
584+
html[data-theme='dark'] .zcp-lifecycle-stage h3 {
579585
color: #f8fafc;
580586
}
581587

582588
html[data-theme='dark'] .zcp-lifecycle-stage p {
583589
color: #cbd5e1;
584590
}
585591

592+
html[data-theme='dark'] .zcp-lifecycle-stage li {
593+
color: #cbd5e1;
594+
}
595+
596+
html[data-theme='dark'] .zcp-lifecycle-stage::after {
597+
color: #9ca3af;
598+
}
599+
586600
html[data-theme='dark'] .zcp-lifecycle-stage--infra {
587601
background: rgba(20, 83, 45, 0.22);
588602
}
@@ -697,13 +711,91 @@ html[data-theme='dark'] .zcp-lifecycle-stage--delivery {
697711
.zcp-claim-callout { grid-column: 1 / -1; padding: 1.15rem 1.25rem; }
698712
}
699713

700-
html[data-theme='dark'] .zcp-claim-card { color: #f8fafc; }
714+
html[data-theme='dark'] .zcp-claim-card {
715+
background: rgba(24, 24, 27, 0.72);
716+
border-color: rgba(63, 63, 70, 0.8);
717+
color: #f8fafc;
718+
}
719+
720+
html[data-theme='dark'] .zcp-claim-card h3 {
721+
color: #f8fafc;
722+
}
723+
724+
html[data-theme='dark'] .zcp-claim-card a {
725+
color: #93c5fd;
726+
}
727+
701728
html[data-theme='dark'] .zcp-claim-card p,
702-
html[data-theme='dark'] .zcp-claim-card span { color: #cbd5e1; }
703-
html[data-theme='dark'] .zcp-claim-card--services { background: rgba(20, 83, 45, 0.22); }
704-
html[data-theme='dark'] .zcp-claim-card--deploy { background: rgba(76, 29, 149, 0.22); }
705-
html[data-theme='dark'] .zcp-claim-card--stack { background: rgba(30, 58, 138, 0.22); }
706-
html[data-theme='dark'] .zcp-claim-card--handover { background: rgba(120, 53, 15, 0.2); }
729+
html[data-theme='dark'] .zcp-claim-card span {
730+
color: #cbd5e1;
731+
}
732+
733+
html[data-theme='dark'] .zcp-claim-card--services { background: rgba(20, 83, 45, 0.22); border-color: rgba(50, 132, 90, 0.35); }
734+
html[data-theme='dark'] .zcp-claim-card--deploy { background: rgba(76, 29, 149, 0.22); border-color: rgba(113, 87, 217, 0.35); }
735+
html[data-theme='dark'] .zcp-claim-card--stack { background: rgba(30, 58, 138, 0.22); border-color: rgba(45, 114, 217, 0.35); }
736+
html[data-theme='dark'] .zcp-claim-card--handover { background: rgba(120, 53, 15, 0.2); border-color: rgba(196, 127, 23, 0.35); }
737+
738+
/* ZCP mermaid flowcharts (how-it-works classDef nodes) */
739+
740+
html[data-theme='dark'] .mermaid .node.user > rect,
741+
html[data-theme='dark'] .mermaid .node.user > polygon,
742+
html[data-theme='dark'] .mermaid .node.user > path {
743+
fill: rgba(30, 58, 138, 0.35) !important;
744+
stroke: #60a5fa !important;
745+
}
746+
747+
html[data-theme='dark'] .mermaid .node.zcpbox > rect,
748+
html[data-theme='dark'] .mermaid .node.zcpbox > polygon,
749+
html[data-theme='dark'] .mermaid .node.zcpbox > path {
750+
fill: rgba(20, 83, 45, 0.3) !important;
751+
stroke: #4ade80 !important;
752+
}
753+
754+
html[data-theme='dark'] .mermaid .node.work > rect,
755+
html[data-theme='dark'] .mermaid .node.work > polygon,
756+
html[data-theme='dark'] .mermaid .node.work > path {
757+
fill: rgba(120, 53, 15, 0.28) !important;
758+
stroke: #fbbf24 !important;
759+
}
760+
761+
html[data-theme='dark'] .mermaid .node.done > rect,
762+
html[data-theme='dark'] .mermaid .node.done > polygon,
763+
html[data-theme='dark'] .mermaid .node.done > path {
764+
fill: rgba(76, 29, 149, 0.28) !important;
765+
stroke: #a78bfa !important;
766+
}
767+
768+
html[data-theme='dark'] .mermaid .node.stop > rect,
769+
html[data-theme='dark'] .mermaid .node.stop > polygon,
770+
html[data-theme='dark'] .mermaid .node.stop > path {
771+
fill: rgba(127, 29, 29, 0.28) !important;
772+
stroke: #f87171 !important;
773+
}
774+
775+
html[data-theme='dark'] .mermaid .node.user .label,
776+
html[data-theme='dark'] .mermaid .node.zcpbox .label,
777+
html[data-theme='dark'] .mermaid .node.work .label,
778+
html[data-theme='dark'] .mermaid .node.done .label,
779+
html[data-theme='dark'] .mermaid .node.stop .label {
780+
color: #f8fafc !important;
781+
}
782+
783+
html[data-theme='dark'] .mermaid .node.user .label span,
784+
html[data-theme='dark'] .mermaid .node.zcpbox .label span,
785+
html[data-theme='dark'] .mermaid .node.work .label span,
786+
html[data-theme='dark'] .mermaid .node.done .label span,
787+
html[data-theme='dark'] .mermaid .node.stop .label span {
788+
color: #f8fafc !important;
789+
}
790+
791+
html[data-theme='dark'] .mermaid .node.user .label code,
792+
html[data-theme='dark'] .mermaid .node.zcpbox .label code,
793+
html[data-theme='dark'] .mermaid .node.work .label code,
794+
html[data-theme='dark'] .mermaid .node.done .label code,
795+
html[data-theme='dark'] .mermaid .node.stop .label code {
796+
background: rgba(15, 23, 42, 0.55);
797+
color: #e2e8f0;
798+
}
707799

708800
/* gap objection cards */
709801

apps/docs/src/theme/DocSidebarItem/Category/index.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
isSamePath,
1515
} from '@docusaurus/theme-common/internal';
1616
import Link from '@docusaurus/Link';
17+
import { useLocation } from '@docusaurus/router';
1718
import { translate } from '@docusaurus/Translate';
1819
import useIsBrowser from '@docusaurus/useIsBrowser';
1920
import DocSidebarItems from '@theme/DocSidebarItems';
@@ -46,6 +47,42 @@ function useAutoExpandActiveCategory({
4647
}, [isActive, wasActive, collapsed, updateCollapsed]);
4748
}
4849

50+
// Collapse a category when navigation leaves it (e.g. Reference → Overview).
51+
function useAutoCollapseInactiveCategory({
52+
isActive,
53+
collapsed,
54+
updateCollapsed,
55+
collapsible,
56+
}: {
57+
isActive: boolean;
58+
collapsed: boolean;
59+
updateCollapsed: (b: boolean) => void;
60+
collapsible: boolean;
61+
}) {
62+
const { pathname } = useLocation();
63+
const wasActive = usePrevious(isActive);
64+
const previousPathname = usePrevious(pathname);
65+
useEffect(() => {
66+
if (!collapsible || collapsed || isActive) {
67+
return;
68+
}
69+
const routeChanged =
70+
previousPathname !== undefined && previousPathname !== pathname;
71+
const justBecameInactive = !isActive && wasActive;
72+
if (justBecameInactive || routeChanged) {
73+
updateCollapsed(true);
74+
}
75+
}, [
76+
isActive,
77+
wasActive,
78+
collapsed,
79+
updateCollapsed,
80+
collapsible,
81+
pathname,
82+
previousPathname,
83+
]);
84+
}
85+
4986
/**
5087
* When a collapsible category has no link, we still link it to its first child
5188
* during SSR as a temporary fallback. This allows to be able to navigate inside
@@ -134,6 +171,12 @@ export default function DocSidebarItemCategory({
134171
setCollapsed(toCollapsed);
135172
};
136173
useAutoExpandActiveCategory({ isActive, collapsed, updateCollapsed });
174+
useAutoCollapseInactiveCategory({
175+
isActive,
176+
collapsed,
177+
updateCollapsed,
178+
collapsible,
179+
});
137180
useEffect(() => {
138181
if (
139182
collapsible &&

0 commit comments

Comments
 (0)