Skip to content

Commit

Permalink
Start on CI section (anthonyshew#79)
Browse files Browse the repository at this point in the history
Starrrrrting it up.
  • Loading branch information
anthonyshew authored Sep 18, 2023
1 parent d4e805d commit 70c490b
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 135 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- name: Run Prettier
run: turbo format

eslint:
name: ESLint
timeout-minutes: 15
Expand Down
1 change: 0 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
public-hoist-pattern[]=*prisma*
auto-install-peers=true
legacy-peer-deps=true
node-linker=hoisted
2 changes: 1 addition & 1 deletion apps/maestros/app/(maestros)/monorepos/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function Page({ params }: { params: { slug: string[] } }) {
{/* @ts-expect-error Don't care, we shippin'! */}
<MDXContent components={mdxComponents} />
</div>
<div className="sticky top-0 hidden xl:block">
<div className="sticky top-0 hidden max-w-sm xl:block">
<div className="flex flex-col gap-2 ml-6">
{headings.length > 0 ? <p>On this page</p> : null}
{headings.map((rawHeading) => {
Expand Down
6 changes: 3 additions & 3 deletions apps/maestros/app/(maestros)/monorepos/email-list/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export const revalidate = 0;

const Page = async () => {
const session = await getServerSession(authOptions);

const isAnthony = session?.user?.email === 'anthonyshew@gmail.com';

if (!isAnthony) {
Expand All @@ -17,9 +16,10 @@ const Page = async () => {
const emails = peeps.map((peep) => peep.email);

return (
<div>
<main className="relative flex flex-col justify-start overflow-x-hidden flex-auto h-[calc(100vh-3.5rem)] px-8 py-8 md:px-12 overflow-auto mt-14 sm:py-8 lg:py-14">
<p>Count: {emails.length}</p>
<pre>{JSON.stringify(emails, null, 2)}</pre>
</div>
</main>
);
};

Expand Down
2 changes: 1 addition & 1 deletion apps/maestros/content/maestros/lessons/basics/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ In a monorepo, we're building one repository that handles all of our application

## Workspaces are like mini-projects

Every application and package that you build will be in its own workspace. The key is to think of your workspaces as independent, small projects in your repository whose purpose is to straightforwardly share code to other parts of your repository.
Every application and package that you build will be in its own workspace. The key is to think of your workspaces as independent, small projects in your repository whose purpose is to straightforwardly share code to other parts of your repository. This includes dependencies and source code that is required to develop and build that workspace.

In this way, you'll start thinking of your monorepo in self-contained slices that expose an API to the outside world. This should sound familiar if you're used to writing modular code. In a monorepo, we can encourage ourselves and our teammates to use the workspace boundary as a module boundary.

Expand Down
1 change: 0 additions & 1 deletion apps/maestros/content/maestros/lessons/ci-cd/caching.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
title: Cache means fast
sidebarOrderPosition: 0
unpublished: true
ogDescription: Using caching in your monorepo
---

Expand Down
9 changes: 9 additions & 0 deletions apps/maestros/content/maestros/lessons/ci-cd/deployment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Deploy to Vercel
sidebarOrderPosition: 3
ogDescription: Deploy to Vercel from a monorepo
---

import { UnderConstruction } from '../../UnderConstruction';

<UnderConstruction />
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
---
title: Ignoring unnecessary work
title: Feature flags
sidebarOrderPosition: 2
unpublished: true
ogDescription: Ignoring unnecessary work in a monorepo
ogDescription: Using feature flags in a monorepo
---

import { UnderConstruction } from '../../UnderConstruction';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
title: GitHub Actions
sidebarOrderPosition: 1
unpublished: true
ogDescription: Using GitHub Actions in a monorepo
---

Expand Down
44 changes: 43 additions & 1 deletion apps/maestros/content/maestros/lessons/ci-cd/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,46 @@ sidebarOrderPosition: 6
ogDescription: Handling CI/CD in a monorepo
---

Developing an app is good fun but, at the end of it all, shipping is what matters.
Developing an app is great fun but, at the end of it all, shipping is what matters.

Continuous deployment and continuous integration can be done in a lot of different ways. In Maestros, we'll discuss simple, powerful patterns to get web applications online to get you started. As your skills grow into more bespoke system, you'll have a good foundation to work from.

On this page, we'll discuss the high-level process of getting an application out to production in a fast, maintainable, and predictable way.

## General process

The conventional process for getting code out to production in a modern CI/CD process follows this general pattern:

1. Developer writes code.
2. Developer commits code to git and creates a pull request to the main branch of the codebase.
3. Automated checks are ran against the newly committed code. Additionally, one or more reviewers are asked to read through the code.
4. Once code passes all automated checks and has been reviewed, it is merged and deployed to production.

## Common objections

In a monorepo, specifically, issues can arise in this process if you aren't using good tooling. Let's talk about these potential problems below and discuss how the techniques in Maestros solve them.

### Release management

A common misconception is that constantly putting new code on the mainline means that you will be constantly releasing new code to the hot paths of your application. If you're working on a new feature, you want to release it when it is complete instead of the first time that you write code for it.

To account for this, we use [feature flags](/monorepos/ci-cd/feature-flags). In a modern CI/CD process, you (nearly) always want to be merging into main through [trunk-based development](https://www.atlassian.com/continuous-delivery/continuous-integration/trunk-based-development). This allows you to:

- Develop in small batches
- Learn about merge conflicts faster (and reduce them in general)
- Test code sooner
- Ship faster

We'll discuss what this looks like more on the [Feature Flags page](/monorepos/ci-cd/feature-flags).

### Slower feedback loops

A common concern with monorepos is that there's simply more code in the codebase to run checks against. That means that checks will run slower since there is more work to do for more code.

This is a very valid concern. Our developers deserve tight feedback loops. Waiting an hour for checks to run against millions of lines of code should be considered unacceptable.

The good news is that we can easily resolve this concern with Turborepo. [With caching](/monorepos/ci-cd/caching), we can ensure that we never do the same work twice.

## Tools for the job

As mentioned before, we're going to administer a straightforward pipeline using [GitHub Actions](/monorepos/ci-cd/github-actions) and [deploying to Vercel](/monorepos/ci-cd/deployment). There are absolutely other actions providers, platforms, and tooling that you can use if you prefer others (and we hope to add more in the future!).
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ ogDescription: Monorepo package managers

**We will be using pnpm throughout Maestros.** If you need to use a different package manager, we'll leave it to you to adjust accordingly.

- [pnpm](/monorepos/padckage-managers/pnpm)
- [yarn](/monorepos/padckage-managers/yarn)
- [npm](/monorepos/padckage-managers/npm)
- [pnpm](/monorepos/package-managers/pnpm)
- [yarn](/monorepos/package-managers/yarn)
- [npm](/monorepos/package-managers/npm)

Your package manager lays the foundation of your repository. It has two core responsibilities in your monorepo:

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"eslint": "^8.47.0",
"prettier": "^2.8.0",
"prettier-plugin-packagejson": "^2.4.3",
"turbo": "^1.10.13"
"turbo": "^1.10.14"
},
"packageManager": "pnpm@8.6.5",
"engines": {
Expand Down
3 changes: 3 additions & 0 deletions packages/analytics/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ export default defineConfig((options: Options) => ({
splitting: true,
treeshake: true,
...options,
banner: {
js: '"use client"',
},
}));
34 changes: 17 additions & 17 deletions packages/db/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL")
directUrl = env("POSTGRES_URL_NON_POOLING")
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL")
directUrl = env("POSTGRES_URL_NON_POOLING")
shadowDatabaseUrl = env("POSTGRES_URL_NON_POOLING")
}

generator client {
provider = "prisma-client-js"
provider = "prisma-client-js"
}

model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
Expand Down Expand Up @@ -52,4 +52,4 @@ model VerificationToken {
expires DateTime
@@unique([identifier, token])
}
}
Loading

0 comments on commit 70c490b

Please sign in to comment.