Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
18 changes: 15 additions & 3 deletions apps/api/src/fastify.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Fastify, { FastifyServerOptions } from "fastify";
import cors from "@fastify/cors";
import rateLimit from "@fastify/rate-limit";
import rawBody from "fastify-raw-body";
import formbody from "@fastify/formbody";
import { yoga } from "./yoga";
Expand Down Expand Up @@ -37,17 +38,28 @@ export async function buildApp(opts: FastifyServerOptions = {}) {
done(null)
);

// Integration APIs
await app.register(healthRouter);
await app.register(githubRouter);
await app.register(slackRouter);
await app.register(bullBoardRouter);

if (!isAppSelfHosted()) {
await app.register(stripeRouter);
}

await app.register(slackRouter);
await app.register(bullBoardRouter);
await app.register(deploymentsRouter);
// User-facing APIs. All routes registered inside this scope are rate limited.
await app.register(async (scope) => {
await scope.register(rateLimit, {
max: 100,
timeWindow: "1 minute",
keyGenerator: (request) => request.headers.authorization || request.ip,
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
Comment thread
waltergalvao marked this conversation as resolved.
Outdated
Comment thread
waltergalvao marked this conversation as resolved.
Outdated
});

await scope.register(deploymentsRouter);
});

// GraphQL
app.route({
url: yoga.graphqlEndpoint,
method: ["GET", "POST", "OPTIONS"],
Expand Down
5 changes: 2 additions & 3 deletions apps/docs/about/data-privacy-and-security.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Data-privacy & Security
icon: "shield-keyhole"
icon: "shield"
---

import GithubPermissions from "/snippets/github-permissions.mdx";
Expand Down Expand Up @@ -37,5 +37,4 @@ We are happy to answer any security questions from your organization. Our team i

## Report Vulnerabilities

Please report vulnerabilities directly to security@sweetr.dev - do not open an issue in our GitHub nor post it anywhere else that is public accessible.

Please report vulnerabilities directly to security@sweetr.dev - do not open an issue in our GitHub nor post it anywhere else that is publicly accessible.
4 changes: 2 additions & 2 deletions apps/docs/about/open-source.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: Open Source
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Page title contradicts the brand guidelines added in this same PR

The body of this page (correctly) now says Sweetr is "fair source, not open source", and the new BRAND_KIT.md explicitly states: "Never call Sweetr 'open source.' Use 'fair source', 'source-available', or 'built in the open' instead."

However, the page title (which also becomes the sidebar navigation label) still reads Open Source, which directly contradicts that rule.

Consider renaming to something like Fair Source or Source & License to stay consistent with the brand voice:

Suggested change
title: Open Source
title: Fair Source

icon: "gear-code"
icon: "brand-open-source"
---

At Sweetr, we are huge fans of open source and its community. We believe in the power of community-driven development and the positive impact it has on innovation and progress. Our source code is freely available for everyone, and we allow self-hosting to ensure accessibility and flexibility.

## License

Our projects are licensed under the <a href="https://fsl.software/" target="_blank" rel="nofollow">Functional Source License (FSL)</a>. While this license is not OSI-approved, it combines the benefits of open source with safeguards against harmful free-riding. The FSL ensures that the software remains open for use, modification, and distribution, but prevents commercial users to use our code to compete against us. After two years, the FSL license automatically converts to the Apache License.
Our projects are licensed under the <a href="https://fsl.software/" target="_blank" rel="nofollow">Functional Source License (FSL)</a>. While this license is not OSI-approved, it combines the benefits of open source with safeguards against harmful free-riding. The FSL ensures that the software remains open for use, modification, and distribution, but prevents commercial users from using our code to compete against us. After two years, the FSL license automatically converts to the Apache License.

We believe this license strikes a good balance between freedom for our users and sustainability to our business.

Expand Down
6 changes: 3 additions & 3 deletions apps/docs/about/principles.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: Principles
icon: "scale-balanced"
icon: "scale"
---

Our mission is to empower developers with tools that enhance productivity, well-being and promote continuous improvement. Our guiding principles reflect our commitment to excellence and innovation.

<CardGroup cols={1}>
<Card title="Developer-first" icon="brackets-curly">
<Card title="Developer-first" icon="brackets-angle">
Taking a human-centric bottom-up approach, everything we build is designed
with developers in mind. Each addition is carefully considered to avoid
enabling toxic managerial practices, aiming to create a space where
Expand All @@ -18,7 +18,7 @@ Our mission is to empower developers with tools that enhance productivity, well-
prone to them. We iterate on our products based on user feedback, emerging
trends, and our own convictions on what shapes a winning culture.
</Card>
<Card title="Simple and effective" icon="crosshairs">
<Card title="Simple and effective" icon="crosshair">
Our commitment is to deliver solutions that are both powerful and easy to
use. We design our tools with simplicity in mind, ensuring they are
intuitive and user-friendly.
Expand Down
30 changes: 30 additions & 0 deletions apps/docs/api-reference/authentication.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Authentication
description: Authenticate requests to the Sweetr API using API keys.
icon: "key"
---

All API requests must include a valid API key in the `Authorization` header using the Bearer scheme:

```bash
Authorization: Bearer YOUR_API_KEY
```

## Generating API keys

API keys are scoped to a workspace. To generate one:

1. Open the Sweetr dashboard.
2. Navigate to **Settings > Workspace**.
3. Scroll down to the **API** section.
4. Click **Regenerate** and copy the generated key.

<Warning>
API keys are only displayed once at creation time. Store them securely — for
example, as a secret in your CI/CD provider.
</Warning>

## Security best practices

- **Never commit API keys** to source control.
- **Use CI/CD secrets** (e.g., GitHub Actions secrets, GitLab CI variables) to inject keys at runtime.
84 changes: 84 additions & 0 deletions apps/docs/api-reference/deployments/create-deployment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: Create Deployment
api: "POST /v1/deployments"
---

Track a new deployment for an application. If the application doesn't exist, it will be created automatically.

The request is processed asynchronously. A `202 Accepted` response means the deployment has been queued for processing.

## Body

<ParamField body="repositoryFullName" type="string" required>
Full name of the GitHub repository (e.g., `owner/repo-name`). Max 255 characters.
</ParamField>

<ParamField body="environment" type="string" required>
Target environment name (e.g., `production`, `staging`). Created automatically if it doesn't exist. Max 255 characters.
</ParamField>

<ParamField body="app" type="string" required>
Application name. Created automatically if it doesn't exist. Max 255 characters.
</ParamField>

<ParamField body="version" type="string" required>
Version identifier for this deployment (e.g., `v1.2.3`, `build-456`). Max 70 characters.
</ParamField>

<ParamField body="commitHash" type="string" required>
The full Git commit SHA being deployed. Max 70 characters.
</ParamField>

<ParamField body="description" type="string">
A short description of the deployment. Max 255 characters.
</ParamField>

<ParamField body="author" type="string">
The person who triggered the deployment. Max 255 characters.
</ParamField>

<ParamField body="deployedAt" type="string">
ISO 8601 datetime of when the deployment occurred. Defaults to the current time if not provided.
</ParamField>

<ParamField body="monorepoPath" type="string">
Subdirectory path within the repository for monorepo setups. Max 255 characters.
</ParamField>

## Response

<ResponseField name="status" type="number">
`202` — The deployment has been accepted and queued for processing.
</ResponseField>

<RequestExample>
```bash cURL
curl -X POST https://api.sweetr.dev/v1/deployments \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
Comment thread
waltergalvao marked this conversation as resolved.
-d '{
"repositoryFullName": "acme/backend",
"environment": "production",
"app": "backend-api",
"version": "v1.4.2",
"commitHash": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"description": "Release v1.4.2",
"author": "jane-doe"
}'
```

```bash GitHub Actions
- name: Track deployment
run: |
curl -X POST https://api.sweetr.dev/v1/deployments \
-H "Authorization: Bearer ${{ secrets.SWEETR_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{
"repositoryFullName": "${{ github.repository }}",
"environment": "production",
"app": "my-app",
"version": "${{ github.sha }}",
"commitHash": "${{ github.sha }}"
}'
```
</RequestExample>
42 changes: 42 additions & 0 deletions apps/docs/api-reference/introduction.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: Introduction
description: Integrate your CI/CD pipeline with Sweetr using the REST API.
icon: "article"
---

The Sweetr API lets you programmatically send data to Sweetr from your CI/CD pipelines and external tools.

## Base URL

All API requests are made to:

```
https://api.sweetr.dev
```

## Available endpoints

<CardGroup cols={1}>
<Card
title="POST /v1/deployments"
icon="rocket"
href="/api-reference/deployments/create-deployment"
>
Track a new deployment for an application.
</Card>
</CardGroup>

## Related

<CardGroup cols={2}>
<Card
title="Authentication"
icon="key"
href="/api-reference/authentication"
/>
<Card
title="Rate Limits"
icon="gauge"
href="/api-reference/rate-limit"
/>
</CardGroup>
11 changes: 11 additions & 0 deletions apps/docs/api-reference/rate-limit.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Rate Limits
description: Understand the rate limits applied to the Sweetr API.
icon: "gauge"
---

All API endpoints are rate limited to **100 requests per minute**, scoped to your API key. Requests that exceed the limit receive a `429 Too Many Requests` response.

## Handling rate limits

If you hit a rate limit, wait before retrying. The recommended approach is exponential backoff — wait 1 second, then 2, then 4, and so on.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ customized independently.
<p>`Improves cycle time` `Improves time to approval`</p>
</Card>

<Card title="Slow merge" icon="code-merge" horizontal>
<Card title="Slow merge" icon="git-merge" horizontal>
Alert when an approved Pull Request has been waiting for merge for too long.
You can setup the minimum idle time to trigger the alert.
<br />
Expand All @@ -45,7 +45,7 @@ customized independently.
<p>`Improves failure rate`</p>
</Card>

<Card title="(Coming Soon) Hot Pull Request" icon="fire" horizontal>
<Card title="(Coming Soon) Hot Pull Request" icon="flame" horizontal>
Alert when a Pull Request has lot of comments or back-and-forth.
</Card>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Digests
description: Scheduled Slack digests to keep teams informed and accountable.
icon: "newspaper"
icon: "message"
---

import { PrBadge } from "/snippets/pr-badge.mdx";
Expand All @@ -24,7 +24,7 @@ Digests can be sent monthly, weekly, or daily. Digests are team scoped, and must
<img src="/images/digest-metrics.png" />
</Frame>

The metrics digest includes a summary of metrics found in [Team Insights](/features/team).
The metrics digest includes a summary of metrics found in [Team Insights](/metrics-and-insights/team/intro).

- Average Pull Request Size
- Average Cycle Time
Expand All @@ -40,7 +40,7 @@ Enabling this digest should help teams understand their flow, and areas for impr
<img src="/images/digest-wip.png" />
</Frame>

The work in progress digest includes a summary of all the team's open Pull Requests found in [Work in Progress](/features/wip).
The work in progress digest includes a summary of all the team's open Pull Requests found in [Work in Progress](/metrics-and-insights/wip).

Enabling this digest should help teams alignment, by bringing light to any PRs that may need attention.

Expand Down
78 changes: 78 additions & 0 deletions apps/docs/automations/incident-detection.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Incident Detection
description: Automatically create incident records from rollbacks, hotfixes and reverts.
icon: "circle-dot"
---

import { CtaGetStarted } from "/snippets/cta-get-started.mdx";

## Demo

<Frame>
<img src="/images/incident-detection.png" />
</Frame>

## How it works

Incident Detection automatically creates incidents when it detects problematic deployments. Incident Detection is enabled and pre-configured by default for every workspace. You can disable or customize the detection rules as needed.

### Rollback detection

Detects when a deployment reverts to a previously deployed version. Sweetr compares the commit history between deployments to identify rollbacks automatically.

| Incident field | Value |
| -------------------- | --------------------------------------------------------------- |
| **Cause deployment** | The first deployment after the version that was rolled back to. |
| **Fix deployment** | The rollback deployment itself. |
| **Detected at** | The time of the rollback deployment. |

For example, given deployments `A → B → C → D`, if you roll back to `B`:

- **Cause deployment**: `C` (the first deployment after `B`, where the problem was introduced)

### Hotfix detection

Detects incidents based on patterns in pull request titles, branch names, or labels. Configure regular expressions to match your team's conventions.

| Pattern | Description |
| ------------------ | -------------------------------------------------------- |
| **PR title regex** | Match pull request titles (e.g., `hotfix`, `emergency`). |
| **Branch regex** | Match branch names (e.g., `hotfix/*`). |
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
Comment thread
waltergalvao marked this conversation as resolved.
Outdated
| **PR label regex** | Match pull request labels. |

Comment on lines +30 to +37
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify that hotfix regex fields are optional.

At Line 30 and the table (Lines 32-36), this reads as if all regexes must be configured. Please add that each field can be left empty to disable that matcher.

✏️ Suggested doc patch
-Detects incidents based on patterns in pull request titles, branch names, or labels. Configure regular expressions to match your team's conventions.
+Detects incidents based on patterns in pull request titles, branch names, or labels. Configure regular expressions to match your team's conventions. Each regex is optional—leave it empty to skip that matcher.

Based on learnings: in apps/web/src/app/automations/settings/incident-detection/types.ts, empty strings are intentionally allowed for optional hotfix regex fields.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Detects incidents based on patterns in pull request titles, branch names, or labels. Configure regular expressions to match your team's conventions.
| Pattern | Description |
| ------------------ | -------------------------------------------------------- |
| **PR title regex** | Match pull request titles (e.g., `hotfix`, `emergency`). |
| **Branch regex** | Match branch names (e.g., `^hotfix/.+`). |
| **PR label regex** | Match pull request labels. |
Detects incidents based on patterns in pull request titles, branch names, or labels. Configure regular expressions to match your team's conventions. Each regex is optional—leave it empty to skip that matcher.
| Pattern | Description |
| ------------------ | -------------------------------------------------------- |
| **PR title regex** | Match pull request titles (e.g., `hotfix`, `emergency`). |
| **Branch regex** | Match branch names (e.g., `^hotfix/.+`). |
| **PR label regex** | Match pull request labels. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/automations/incident-detection.mdx` around lines 30 - 37, Update
the incident-detection docs to clarify that the regex fields are optional:
change the table entries for "PR title regex", "Branch regex", and "PR label
regex" to indicate each can be left empty to disable that matcher, and add one
short sentence under the table stating "Leave any regex field blank to disable
that matcher" (these correspond to the hotfix regex fields defined in types.ts).
Ensure the wording matches the implementation (empty string allowed) so readers
know leaving the field empty disables the matcher.

| Incident field | Value |
| -------------------- | -------------------------------------------------------- |
| **Cause deployment** | The deployment immediately before the hotfix deployment. |
| **Fix deployment** | The deployment containing the hotfix pull request. |
| **Detected at** | The time of the hotfix deployment. |

### Revert detection

Detects when a pull request is a revert of a previous change.

| Incident field | Value |
| -------------------- | ----------------------------------------------------------------------- |
| **Cause deployment** | The deployment that contained the original (now-reverted) pull request. |
| **Fix deployment** | The deployment containing the revert pull request. |
Comment thread
waltergalvao marked this conversation as resolved.
| **Detected at** | The time of the revert deployment. |

## Benefits

<Card horizontal title="Improves data accuracy" icon="database">
Precise failure rate on your DORA metrics. Remove manual work from incident
reporting.
</Card>

## Related

<CardGroup cols={2}>
<Card
title="DORA Metrics"
icon="chart-line"
href="/metrics-and-insights/dora"
/>
<Card title="Incidents" icon="flame" href="/platform/incidents" />
<Card title="Deployments" icon="rocket" href="/platform/deployments" />
</CardGroup>

<CtaGetStarted />
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: PR Size Labeler
description: Automatically label a Pull Request with its size.
icon: "ruler"
---

import { PrSize } from "/snippets/pr-size.mdx";
Expand Down
Loading