Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9b72c40
pushing README.md changes
tjtreem Sep 22, 2025
760cb12
Merge pull request #1 from tjtreem/addtests
tjtreem Sep 22, 2025
5cfa3cc
first workflow(.yml)
tjtreem Sep 22, 2025
063aea3
first workflow(.yml) revised
tjtreem Sep 22, 2025
ae50899
updated and fixed the workflow job error
tjtreem Sep 22, 2025
28f6e8b
intentional test fail
tjtreem Sep 23, 2025
e7c371a
fix: restore valid test
tjtreem Sep 23, 2025
5bd505c
Merge pull request #2 from tjtreem/addtests
tjtreem Sep 23, 2025
3cba3df
adding coverage
tjtreem Sep 23, 2025
723b36d
Merge pull request #3 from tjtreem/addtests
tjtreem Sep 23, 2025
a8416b3
added testing badge to README.md
tjtreem Sep 23, 2025
2e604de
Merge pull request #4 from tjtreem/addtests
tjtreem Sep 23, 2025
a556ed5
added formatting check to ci workflow
tjtreem Sep 24, 2025
45202cf
added staticcheck to ci workflow
tjtreem Sep 24, 2025
e0ea29d
added staticcheck to ci workflow with corrected main.go file
tjtreem Sep 24, 2025
ddc8dbe
Merge pull request #5 from tjtreem/addtests
tjtreem Sep 24, 2025
0cbc46d
changes
tjtreem Sep 24, 2025
4602d2f
Merge pull request #6 from tjtreem/addtests
tjtreem Sep 24, 2025
eee1797
added gosec with code failure
tjtreem Sep 25, 2025
1739f5b
Merge pull request #7 from tjtreem/addtests
tjtreem Sep 25, 2025
cc92dde
gosec with updated and corrected code
tjtreem Sep 25, 2025
cb81003
gosec with updated and corrected code
tjtreem Sep 25, 2025
5efceec
gosec with updated and corrected code
tjtreem Sep 25, 2025
2b21051
gosec with updated and corrected code
tjtreem Sep 25, 2025
9540598
Merge pull request #8 from tjtreem/addtests
tjtreem Sep 25, 2025
c843ca7
added cd workflow
tjtreem Sep 25, 2025
c4a4d63
Merge pull request #9 from tjtreem/addtests
tjtreem Sep 25, 2025
a908d1e
added cd workflow
tjtreem Sep 25, 2025
d133583
Merge pull request #10 from tjtreem/addtests
tjtreem Sep 25, 2025
2b9ff04
added cd workflow
tjtreem Sep 25, 2025
85a7c14
Merge pull request #11 from tjtreem/addtests
tjtreem Sep 25, 2025
d639665
added cd workflow
tjtreem Sep 25, 2025
f1ec6da
Merge pull request #12 from tjtreem/addtests
tjtreem Sep 25, 2025
9e51d4d
added cd workflow
tjtreem Sep 25, 2025
5466ce6
Merge pull request #13 from tjtreem/addtests
tjtreem Sep 25, 2025
53517f4
modified cd.yml to include Google cloud build
tjtreem Sep 26, 2025
a9c06f1
modified cd workflow for Cloud build and deployment
tjtreem Sep 27, 2025
c74580d
added migrations to cd workflow
tjtreem Sep 27, 2025
d8d50d6
new push
tjtreem Sep 27, 2025
df3b735
fixes to cloud build
tjtreem Sep 27, 2025
e9d497b
debug changes
tjtreem Sep 27, 2025
109b6f3
debugging
tjtreem Sep 28, 2025
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
72 changes: 72 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: cd

on:
push:
branches: [main]

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest

env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Install goose
run: |
curl -fsSL https://raw.githubusercontent.com/pressly/goose/master/install.sh | sh

- id: 'auth'
uses: 'google-github-actions/auth@v2'
with:
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'

- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v3'

- name: Configure gcloud defaults
run: |
gcloud config set project notely-473217
gcloud config set run/region us-central1

- name: Set IMAGE_TAG
run: |
SHORT_SHA="$(echo ${{github.sha}} | head -c 8)"
echo "IMAGE_TAG=$SHORT_SHA" >> "$GITHUB_ENV"

- name: Build and push image (Cloud Build)
run: |
gcloud builds submit \
--tag us-central1-docker.pkg.dev/notely-473217/notely-ar-repo/notely:${IMAGE_TAG} .

- name: Debug DB URL presence
run: |
[ -n "$DATABASE_URL" ] && echo "DATABASE_URL is set" || echo "DATABASE_URL is MISSING"

- name: Run DB migrations
run: |
export PATH="$PWD/bin:$PATH"
chmod +x scripts/migrateup.sh
./scripts/migrateup.sh

- name: Deploy to Cloud Run
run: |
gcloud run deploy notely \
--image us-central1-docker.pkg.dev/notely-473217/notely-ar-repo/notely:${IMAGE_TAG} \
--allow-unauthenticated \
--max-instances=4

# Optional: ensure unauthenticated access if first deploy
- name: Ensure public invoker (optional)
continue-on-error: true
run: |
gcloud run services add-iam-policy-binding notely \
--member="allUsers" \
--role="roles/run.invoker"



54 changes: 54 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: ci

on:
pull_request:
branches: [main]
push:
branches: [addtests]

jobs:
tests:
name: Tests
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "stable"

- name: Run tests
run: go test -cover ./...

- name: Install gosec
run: go install github.com/securego/gosec/v2/cmd/gosec@latest

- name: Check gosec
run: gosec ./...

style:
name: Style
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "stable"

- name: Run formatting check
run: test -z "$(gofmt -l .)"

- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@latest

- name: Run staticcheck
run: staticcheck ./...


18 changes: 13 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
FROM --platform=linux/amd64 debian:stable-slim
# Build stage
FROM golang:1.22 AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o notely .

RUN apt-get update && apt-get install -y ca-certificates

ADD notely /usr/bin/notely

CMD ["notely"]
# Run stage
FROM debian:stable-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=build /app/notely /usr/bin/notely
EXPOSE 8080
CMD ["/usr/bin/notely"]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# learn-cicd-starter (Notely)

![Testing Badge](https://github.com/tjtreem/learn-cicd-starter/actions/workflows/ci.yml/badge.svg)

This repo contains the starter code for the "Notely" application for the "Learn CICD" course on [Boot.dev](https://boot.dev).

## Local Development
Expand All @@ -21,3 +23,9 @@ go build -o notely && ./notely
*This starts the server in non-database mode.* It will serve a simple webpage at `http://localhost:8080`.

You do *not* need to set up a database or any interactivity on the webpage yet. Instructions for that will come later in the course!


Tim Treem's version of Boot.Dev's Notely app.



3 changes: 3 additions & 0 deletions handler_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"net/http"
"time"
"log"

"github.com/bootdotdev/learn-cicd-starter/internal/database"
"github.com/google/uuid"
Expand Down Expand Up @@ -37,7 +38,9 @@ func (cfg *apiConfig) handlerUsersCreate(w http.ResponseWriter, r *http.Request)
Name: params.Name,
ApiKey: apiKey,
})

if err != nil {
log.Printf("create user failed: %v", err)
respondWithError(w, http.StatusInternalServerError, "Couldn't create user", err)
return
}
Expand Down
55 changes: 55 additions & 0 deletions internal/auth/get_api_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package auth

import (
"errors"
"net/http"
"testing"
)

type testCase struct {
name string
setHeader bool
headerVal string
wantKey string
wantErr error
}

func TestGetAPIKey(t *testing.T) {
cases := []testCase{
{name: "no header", setHeader: false, wantErr: ErrNoAuthHeaderIncluded},
{name: "empty header", setHeader: true, headerVal: "", wantErr: ErrNoAuthHeaderIncluded},
{name: "valid", setHeader: true, headerVal: "ApiKey my-secret", wantKey: "my-secret", wantErr: nil},
{name: "wrong prefix", setHeader: true, headerVal: "Bearer token", wantErr: errors.New("any")},
{name: "missing key", setHeader: true, headerVal: "ApiKey", wantErr: errors.New("any")},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
headers := http.Header{}
if tc.setHeader {
headers.Set("Authorization", tc.headerVal)
}

got, err := GetAPIKey(headers)

if tc.wantErr != nil {
// For the specific missing-header error:
if errors.Is(tc.wantErr, ErrNoAuthHeaderIncluded) && !errors.Is(err, ErrNoAuthHeaderIncluded) {
t.Fatalf("expected ErrNoAuthHeaderIncluded, got %v", err)
}
// For generic malformed cases just ensure err != nil
if errors.Is(tc.wantErr, ErrNoAuthHeaderIncluded) && err == nil {
t.Fatalf("expected error, got nil")
}
return
}

if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got != tc.wantKey {
t.Fatalf("want key %q, got %q", tc.wantKey, got)
}
})
}
}
7 changes: 6 additions & 1 deletion json.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,10 @@ func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
return
}
w.WriteHeader(code)
w.Write(dat)

n, err := w.Write(dat)
if err != nil {
log.Printf("respondWithJSON: write error after %d bytes: %v", n, err)
return
}
}
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"net/http"
"os"
"time"

"github.com/go-chi/chi"
"github.com/go-chi/cors"
Expand Down Expand Up @@ -89,10 +90,12 @@ func main() {

router.Mount("/v1", v1Router)
srv := &http.Server{
Addr: ":" + port,
Handler: router,
Addr: ":" + port,
Handler: router,
ReadHeaderTimeout: 1 * time.Second,
}

log.Printf("Serving on port: %s\n", port)
log.Fatal(srv.ListenAndServe())

}
11 changes: 4 additions & 7 deletions scripts/migrateup.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/bin/bash

if [ -f .env ]; then
source .env
fi

cd sql/schema
goose turso $DATABASE_URL up
set -euo pipefail
cd "$(dirname "$0")/../sql/schema"
echo "Running: goose turso <REDACTED> up"
goose turso "$DATABASE_URL" up
2 changes: 1 addition & 1 deletion static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</head>

<body class="section">
<h1>Notely</h1>
<h1>Welcome to Notely</h1>

<div id="userCreationContainer" class="section">
<input id="nameField" type="text" placeholder="Enter your name">
Expand Down
42 changes: 21 additions & 21 deletions vendor/github.com/go-chi/chi/chi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions vendor/github.com/go-chi/chi/context.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading