Skip to content
11 changes: 9 additions & 2 deletions .github/workflows/deploy-cloudrun.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,16 @@

name: Build and Deploy to Cloud Run with KRM


on:
pull_request:
branches:
- main
workflow_dispatch:
push:
branches:
- jarrpa/dev/cloudy
- main
- jarrpa/2026-pittsburgh

env:
PROJECT_ID: oceanic-gecko-338300
Expand All @@ -76,12 +82,13 @@ jobs:

- name: Google Auth
id: auth
uses: 'google-github-actions/auth@v0'
uses: 'google-github-actions/auth@v3'
with:
token_format: 'access_token'
workload_identity_provider: '${{ vars.WIF_PROVIDER }}' # e.g. - projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
service_account: '${{ vars.WIF_SERVICE_ACCOUNT }}' # e.g. - my-service-account@my-project.iam.gserviceaccount.com


# NOTE: Alternative option - authentication via credentials json
# - name: Google Auth
# id: auth
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/deploy-cloudrun/cloud-run-service.template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: ${SERVICE}
spec:
template:
spec:
containerConcurrency: 80
timeoutSeconds: 60
serviceAccountName: ${SERVICE_ACCOUNT}
containers:
- name: backend-service
image: ${IMAGE}
args:
- test
ports:
- name: http1
containerPort: 8080
resources:
limits:
cpu: 1000m
memory: 1Gi
volumeMounts:
- name: run
mountPath: /app/run
- name: conf
mountPath: /app/conf
startupProbe:
timeoutSeconds: 240
periodSeconds: 240
failureThreshold: 3
tcpSocket:
port: 8080
volumes:
- name: run
csi:
driver: gcsfuse.run.googleapis.com
volumeAttributes:
bucketName: ${RUN_BUCKET_NAME}
- name: conf
csi:
driver: gcsfuse.run.googleapis.com
volumeAttributes:
bucketName: ${CONF_BUCKET_NAME}
traffic:
- percent: 100
latestRevision: true
1 change: 1 addition & 0 deletions internal/cert_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func VerifyCertificate(certificate string) (string, bool) {
scanErr := result.Scan(&certificateRole)

if scanErr != nil {
LogError(scanErr, "error verifying certificate")
return "none", false
}

Expand Down
2 changes: 1 addition & 1 deletion internal/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func userInSchedule(database *sql.DB, uuid string) bool {

// Wipes the json file
func WipeSchedule() {
schedPath := filepath.Join(CachedConfigs.RuntimeDirectory, "json")
schedPath := filepath.Join(CachedConfigs.RuntimeDirectory, "schedule.json")
file, openErr := OpenWithPermissions(schedPath)

if openErr != nil {
Expand Down
20 changes: 14 additions & 6 deletions internal/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,15 +369,15 @@ func handleLoginRequest(writer http.ResponseWriter, request *http.Request) {
Path: "/",
HttpOnly: true,
Secure: secureCookies,
SameSite: http.SameSiteStrictMode,
SameSite: http.SameSiteNoneMode,
})
http.SetCookie(writer, &http.Cookie{
Name: "certificate",
Value: fmt.Sprintf("%v", cert),
Path: "/",
HttpOnly: true,
Secure: secureCookies,
SameSite: http.SameSiteStrictMode,
SameSite: http.SameSiteNoneMode,
})

if role == "super" {
Expand All @@ -404,7 +404,7 @@ func handleLogoutRequest(writer http.ResponseWriter, request *http.Request) {
MaxAge: -1,
HttpOnly: true,
Secure: secureCookies,
SameSite: http.SameSiteStrictMode,
SameSite: http.SameSiteNoneMode,
})

// clear certificate cookie
Expand All @@ -415,7 +415,7 @@ func handleLogoutRequest(writer http.ResponseWriter, request *http.Request) {
MaxAge: -1,
HttpOnly: true,
Secure: secureCookies,
SameSite: http.SameSiteStrictMode,
SameSite: http.SameSiteNoneMode,
})

httpResponsef(writer, "Problem writing http response to logout request", "Logged out")
Expand Down Expand Up @@ -546,9 +546,13 @@ func handleScoreChange(writer http.ResponseWriter, request *http.Request) {
// The okCode parameter exists because some requests require a 200 response even before acting. This is honestly just trial and error to determine.
func handleWithCORS(handler http.HandlerFunc, okCode bool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", CachedConfigs.FrontendDomain)
allowOrigin := CachedConfigs.FrontendDomain
if r.Header.Get("Origin") != "" {
allowOrigin = r.Header.Get("Origin")
}
w.Header().Set("Access-Control-Allow-Origin", allowOrigin)
w.Header().Set("Access-Control-Allow-Methods", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, username, uuid, displayName, Filename, userInput, color, type")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, username, uuid, displayName, Filename, userInput, color, type")
w.Header().Set("Access-Control-Expose-Headers", "Role")
w.Header().Set("Access-Control-Allow-Credentials", "true")

Expand Down Expand Up @@ -838,10 +842,14 @@ func getAuthFromCookies(request *http.Request) RequestAuth {

if c, err := request.Cookie("uuid"); err == nil && c != nil {
auth.UUID = c.Value
} else if err != nil {
LogError(err, "error getting request cookie 'uuid'")
}

if c, err := request.Cookie("certificate"); err == nil && c != nil {
auth.Certificate = c.Value
} else if err != nil {
LogError(err, "error getting request cookie 'certificate'")
}

role, ok := VerifyCertificate(auth.Certificate)
Expand Down
4 changes: 2 additions & 2 deletions internal/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -748,10 +748,10 @@ func configCustomEvent(configs GeneralConfigs) CustomEventConfigs {
}

if configs.CustomEventConfigs.CustomSchedule {
LogMessagef("Using %s/json as the match schedule! Please make that it meets your non-TBA event schedule manually.", CachedConfigs.RuntimeDirectory)
LogMessagef("Using %s/schedule.json as the match schedule! Please make that it meets your non-TBA event schedule manually.", CachedConfigs.RuntimeDirectory)
} else {
WipeSchedule()
LogMessage("Not using a ")
LogMessage("Not using a schedule")
}

configs.CustomEventConfigs.Configured = true
Expand Down
10 changes: 6 additions & 4 deletions internal/sheet_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,18 @@ var Srv *sheets.Service
func SetupSheetsAPI(creds []byte) {
ctx := context.Background()

config, err := google.ConfigFromJSON(creds, "https://www.googleapis.com/auth/spreadsheets")
client, err := google.DefaultClient(context.Background(), sheets.SpreadsheetsScope)
if err != nil {
FatalError(err, "Unable to parse client secret file to config: %v")
}
client := getClient(config)

Srv, err = sheets.NewService(ctx, option.WithHTTPClient(client))
if err != nil {
FatalError(err, "Unable to retrieve Sheets client: %v")
}
LogMessagef("Client retrieved for: %v", Srv.UserAgent)
LogMessagef("Client retrieved for: %v", Srv.BasePath)

SpreadsheetId = CachedConfigs.SpreadSheetID
LogMessagef("Using SpreadsheetId: %v", CachedConfigs.SpreadSheetID)
}

// Writes team data from multi-scouting to a specified line
Expand Down Expand Up @@ -256,6 +255,9 @@ func IsSheetValid(id string) bool {
spreadsheetId := id
readRange := "RawData!A1:1"
_, err := Srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Do()
if err != nil {
LogErrorf(err, "Failed to read from %q on sheet %q", readRange, spreadsheetId)
}
return err == nil
}

Expand Down
2 changes: 1 addition & 1 deletion internal/user_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func GetUUID(username string, createIfNot bool) (string, bool) {
}

if !userExists {
NewUser(username, "") //Empty UUID for assignment later
NewUser(username, uuid.New().String()) //Empty UUID for assignment later
}

var userId string
Expand Down