Skip to content

Commit 693f992

Browse files
feat: initial import
0 parents  commit 693f992

35 files changed

Lines changed: 2066 additions & 0 deletions

.env.development.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
GITHUB_CLIENT_ID=your_github_oauth_client_id
2+
GITHUB_CLIENT_SECRET=your_github_oauth_client_secret
3+
GITHUB_AUTH_ISSUER=https://your_unique_authentication_issuer
4+
JWT_PRIVATE_KEY_PATH=./private-key.pem
5+
JWT_PUBLIC_KEY_PATH=./public-key.pem
6+
JWT_KEY_ID=your-api-key-1

.env.production.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
GITHUB_CLIENT_ID=your_github_oauth_client_id
2+
GITHUB_CLIENT_SECRET=your_github_oauth_client_secret
3+
GITHUB_AUTH_ISSUER=https://your_unique_authentication_issuer

.env.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
GITHUB_CLIENT_ID=test-client-id
2+
GITHUB_CLIENT_SECRET=test-client-secret
3+
GITHUB_AUTH_ISSUER=https://api.juno.build/auth/github
4+
JWT_PRIVATE_KEY_PATH=./test-private-key.pem
5+
JWT_PUBLIC_KEY_PATH=./test-public-key.pem
6+
JWT_KEY_ID=juno-key-1

.github/actions/prepare/action.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Prepare
2+
3+
description: Checkout and install dependencies
4+
5+
runs:
6+
using: composite
7+
steps:
8+
- name: Setup Bun
9+
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
10+
11+
- name: Install dependencies
12+
shell: bash
13+
run: bun install --frozen-lockfile

.github/workflows/build.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
build-and-test:
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
13+
with:
14+
persist-credentials: false
15+
16+
- name: Set up Docker Buildx
17+
uses: docker/setup-buildx-action@v3
18+
19+
- name: Cache Docker layers
20+
uses: actions/cache@v4
21+
with:
22+
path: /tmp/.buildx-cache
23+
key: ${{ runner.os }}-buildx-${{ github.sha }}
24+
restore-keys: |
25+
${{ runner.os }}-buildx-
26+
27+
- name: Build Docker image
28+
uses: docker/build-push-action@v6
29+
with:
30+
context: .
31+
push: false
32+
load: true
33+
tags: juno-api:test
34+
cache-from: type=local,src=/tmp/.buildx-cache
35+
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
36+
37+
- name: Run container
38+
run: |
39+
docker run -d --name juno-api-test \
40+
-p 3000:3000 \
41+
-e GITHUB_CLIENT_ID=test-client-id \
42+
-e GITHUB_CLIENT_SECRET=test-client-secret \
43+
-e GITHUB_AUTH_ISSUER=https://api.juno.build/auth/github \
44+
juno-api:test
45+
46+
- name: Wait for container to be ready
47+
run: |
48+
timeout 30 sh -c 'until curl -f http://localhost:3000/v1/auth/certs 2>/dev/null; do sleep 1; done'
49+
50+
- name: Test JWKS endpoint
51+
run: |
52+
response=$(curl -s http://localhost:3000/v1/auth/certs)
53+
echo "$response" | jq -e '.keys[0].kid' | grep -q "juno-api-"
54+
echo "$response" | jq -e '.keys[0].n'
55+
echo "$response" | jq -e '.keys[0].e == "AQAB"'
56+
echo "✅ JWKS endpoint working"
57+
58+
- name: Check container logs
59+
if: always()
60+
run: docker logs juno-api-test
61+
62+
- name: Cleanup
63+
if: always()
64+
run: docker rm -f juno-api-test
65+
66+
# Move cache to avoid unbounded growth
67+
- name: Move cache
68+
run: |
69+
rm -rf /tmp/.buildx-cache
70+
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

.github/workflows/checks.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Checks
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
13+
with:
14+
persist-credentials: false
15+
16+
- name: Prepare
17+
uses: ./.github/actions/prepare
18+
19+
- name: Build
20+
run: bun run build
21+
22+
format:
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
28+
with:
29+
persist-credentials: false
30+
31+
- name: Prepare
32+
uses: ./.github/actions/prepare
33+
34+
- name: Format
35+
run: bun format:check
36+
37+
lint:
38+
runs-on: ubuntu-latest
39+
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
43+
with:
44+
persist-credentials: false
45+
46+
- name: Prepare
47+
uses: ./.github/actions/prepare
48+
49+
- name: Lint
50+
run: bun lint
51+
52+
test:
53+
runs-on: ubuntu-latest
54+
55+
steps:
56+
- name: Checkout
57+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
58+
with:
59+
persist-credentials: false
60+
61+
- name: Prepare
62+
uses: ./.github/actions/prepare
63+
64+
- name: Test
65+
run: bun test
66+
67+
may-merge:
68+
needs: ['format', 'lint', 'test', 'build']
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Cleared for merging
72+
run: echo OK

.github/workflows/publish.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Publish Docker image
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
push_to_registry:
9+
name: Push Docker image to Docker Hub
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
include:
14+
- image_name: junobuild/api
15+
16+
steps:
17+
- name: Check out the repo
18+
uses: actions/checkout@v4
19+
20+
- name: Log in to Docker Hub
21+
uses: docker/login-action@v2
22+
with:
23+
username: ${{ secrets.DOCKER_USERNAME }}
24+
password: ${{ secrets.DOCKER_TOKEN }}
25+
26+
- name: Extract metadata (tags, labels) for Docker
27+
id: meta
28+
uses: docker/metadata-action@v4
29+
with:
30+
images: ${{ matrix.image_name }}
31+
tags: |
32+
type=semver,pattern={{major}}
33+
type=semver,pattern={{version}}
34+
35+
- name: Build and push Docker image for ${{ matrix.image_name }}
36+
uses: docker/build-push-action@v5
37+
with:
38+
context: .
39+
platforms: linux/amd64
40+
file: ./Dockerfile
41+
push: true
42+
tags: ${{ steps.meta.outputs.tags }}
43+
labels: ${{ steps.meta.outputs.labels }}

.gitignore

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# Various IDEs and Editors
4+
.vscode/
5+
.idea/
6+
**/*~
7+
8+
# Mac OSX temporary files
9+
.DS_Store
10+
**/.DS_Store
11+
12+
# dependencies
13+
/node_modules
14+
/.pnp
15+
.pnp.js
16+
17+
# testing
18+
/coverage
19+
20+
# next.js
21+
/.next/
22+
/out/
23+
24+
# production
25+
/build
26+
27+
# misc
28+
*.pem
29+
30+
# debug
31+
npm-debug.log*
32+
yarn-debug.log*
33+
yarn-error.log*
34+
35+
# local env files
36+
.env.local
37+
.env.development.local
38+
.env.test.local
39+
.env.production.local
40+
41+
# vercel
42+
.vercel
43+
44+
**/*.trace
45+
**/*.zip
46+
**/*.tar.gz
47+
**/*.tgz
48+
**/*.log
49+
package-lock.json
50+
**/*.bun

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"useTabs": true,
3+
"singleQuote": true,
4+
"trailingComma": "none",
5+
"printWidth": 100,
6+
"plugins": ["prettier-plugin-organize-imports"]
7+
}

Dockerfile

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# use the official Bun image
2+
# see all versions at https://hub.docker.com/r/oven/bun/tags
3+
FROM oven/bun:1 AS base
4+
WORKDIR /usr/src/app
5+
6+
# install dependencies into temp directory
7+
# this will cache them and speed up future builds
8+
FROM base AS install
9+
RUN mkdir -p /temp/dev
10+
COPY package.json bun.lock /temp/dev/
11+
RUN cd /temp/dev && bun install --frozen-lockfile
12+
13+
# install with --production (exclude devDependencies)
14+
RUN mkdir -p /temp/prod
15+
COPY package.json bun.lock /temp/prod/
16+
RUN cd /temp/prod && bun install --frozen-lockfile --production
17+
18+
# copy node_modules from temp directory
19+
# then copy all (non-ignored) project files into the image
20+
FROM base AS prerelease
21+
COPY --from=install /temp/dev/node_modules node_modules
22+
23+
# copy required resources
24+
COPY src src
25+
COPY test test
26+
COPY biome.json biome.json
27+
COPY bunfig.toml bunfig.toml
28+
COPY package.json package.json
29+
COPY test-setup.ts test-setup.ts
30+
COPY tsconfig.json tsconfig.json
31+
32+
# tests & build
33+
ENV NODE_ENV=production
34+
RUN bun run build
35+
36+
# build final image
37+
FROM base AS release
38+
39+
RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y \
40+
openssl \
41+
&& rm -rf /var/lib/apt/lists/*
42+
43+
COPY --from=install /temp/prod/node_modules node_modules
44+
COPY --from=prerelease /usr/src/app/build/server .
45+
46+
# Add entrypoint script
47+
COPY entrypoint.sh .
48+
RUN chmod +x entrypoint.sh
49+
50+
# Prepare folder for generating the keys on start
51+
RUN mkdir -p /usr/src/app/keys && chown -R bun:bun /usr/src/app/keys
52+
53+
# run the app
54+
USER bun
55+
EXPOSE 3000/tcp
56+
57+
CMD ["./entrypoint.sh"]

0 commit comments

Comments
 (0)