Skip to content

Commit 21b85d5

Browse files
authored
Merge pull request #28 from cruxstack/refactor/v1
refactor!: adopt github-app-setup-go, update dependencies, and fix security and sync bugs
2 parents 6d61846 + 2f8a70e commit 21b85d5

79 files changed

Lines changed: 9540 additions & 7524 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.devcontainer/devcontainer.json‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "github-ops-app",
3+
"image": "mcr.microsoft.com/devcontainers/base:bookworm",
4+
"features": {
5+
"ghcr.io/devcontainers/features/go:1": {
6+
"version": "1.27"
7+
},
8+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
9+
},
10+
"forwardPorts": [8080],
11+
"postCreateCommand": "go mod download",
12+
"customizations": {
13+
"vscode": {
14+
"extensions": [
15+
"editorconfig.editorconfig",
16+
"github.vscode-github-actions",
17+
"golang.go"
18+
],
19+
"settings": {
20+
"editor.formatOnSave": true,
21+
"go.lintTool": "golangci-lint-v2",
22+
"[markdown]": {
23+
"editor.rulers": [80]
24+
}
25+
}
26+
}
27+
}
28+
}

‎.dockerignore‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
.local/
1+
.git
2+
.github
3+
.devcontainer
4+
.worktrees
5+
.local
26
.env
3-
dist/
4-
tmp/
5-
.git/
7+
dist
8+
release
9+
tmp
10+
coverage.out
11+
.DS_Store

‎.env.example‎

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,69 @@
1-
# debug
2-
APP_DEBUG_ENABLED=false
1+
# every value may instead be an ssm parameter arn, such as
2+
# arn:aws:ssm:us-east-1:123456789012:parameter/github-ops-app/slack-token
33

4-
# admin token for /server/* and /scheduled/* endpoints (optional)
5-
# when set, requests to these endpoints require "Authorization: Bearer <token>"
6-
# APP_ADMIN_TOKEN=your-secret-admin-token
4+
# logging: debug, info, warn, or error (default: info)
5+
# APP_LOG_LEVEL=info
6+
7+
# server (cmd/server only)
8+
# APP_LISTEN_ADDR=:8080
9+
# routes are served under this path, such as an api gateway stage (optional)
10+
# APP_BASE_PATH=/prod
11+
# external url of the service, including APP_BASE_PATH; used by the installer
12+
# APP_PUBLIC_URL=https://github-ops.example.com
13+
14+
# admin token for /server/* and /scheduled/*, at least 16 characters; the
15+
# admin endpoints are disabled when it is unset
16+
# APP_ADMIN_TOKEN=change-me-to-a-long-random-string
717

818
# github app (required)
19+
APP_GITHUB_ORG=acme
920
APP_GITHUB_APP_ID=123456
10-
APP_GITHUB_APP_PRIVATE_KEY_PATH=./.local/private-key.pem
11-
APP_GITHUB_INSTALLATION_ID=987654
12-
APP_GITHUB_ORG=cruxstack
13-
APP_GITHUB_WEBHOOK_SECRET=your-webhook-secret-here
21+
APP_GITHUB_APP_PRIVATE_KEY_PATH=./.local/github-private-key.pem
22+
# or the key itself, with literal newlines or \n escapes
23+
# APP_GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
24+
APP_GITHUB_WEBHOOK_SECRET=change-me
25+
# looked up from the organization when unset
26+
# APP_GITHUB_INSTALLATION_ID=987654
27+
# api url for github enterprise server
28+
# APP_GITHUB_BASE_URL=https://github.example.com/api/v3
29+
30+
# github app installer (optional): serves /setup to create the app from a
31+
# manifest and saves its credentials; disable it once the app is created
32+
# GITHUB_APP_INSTALLER_ENABLED=true
33+
# STORAGE_MODE=envfile # envfile or aws-ssm
34+
# STORAGE_DIR=./.env # env file the envfile mode writes
35+
# AWS_SSM_PARAMETER_PREFIX=/github-ops-app/
36+
# AWS_SSM_KMS_KEY_ID=alias/github-ops-app
1437

15-
# github pr compliance (optional)
38+
# pr compliance (optional)
1639
APP_PR_COMPLIANCE_ENABLED=true
17-
APP_PR_MONITORED_BRANCHES=main,master
40+
# branch names or glob patterns
41+
APP_PR_MONITORED_BRANCHES=main,master,release/*
1842

19-
# okta (optional)
20-
APP_OKTA_DOMAIN=company.okta.com
43+
# okta group sync (optional; setting any okta value requires all of them)
44+
APP_OKTA_DOMAIN=acme.okta.com
2145
APP_OKTA_CLIENT_ID=0oaxxxxxxxxxxxxxxxxxxxxx
2246
APP_OKTA_PRIVATE_KEY_PATH=./.local/okta-private-key.pem
47+
# APP_OKTA_PRIVATE_KEY_ID=kid-from-okta
2348
# APP_OKTA_SCOPES=okta.groups.read,okta.users.read
24-
25-
# okta sync rules
2649
APP_OKTA_GITHUB_USER_FIELD=githubUsername
27-
APP_OKTA_SYNC_RULES=[{"name":"sync-eng","enabled":true,"okta_group_pattern":"^github-eng-.*","github_team_prefix":"eng-","strip_prefix":"github-eng-","sync_members":true,"create_team_if_missing":true}]
28-
# APP_OKTA_SYNC_SAFETY_THRESHOLD=0.5 # Prevent mass removal if more than 50% would be removed (default: 0.5)
50+
APP_OKTA_SYNC_RULES=[{"name":"sync-eng","okta_group_pattern":"^github-eng-.*","strip_prefix":"github-eng-","github_team_prefix":"eng-","create_team_if_missing":true}]
51+
# refuse to remove more than this share of a team's members (default: 0.5)
52+
# APP_OKTA_SYNC_SAFETY_THRESHOLD=0.5
53+
# APP_OKTA_ORPHANED_USER_NOTIFICATIONS=true
2954

30-
# security alerts monitoring (optional)
55+
# stale security alerts (optional)
3156
# APP_SECURITY_ALERTS_ENABLED=true
32-
# APP_SECURITY_ALERTS_MIN_AGE_DAYS=30 # only report alerts older than N days (default: 30)
33-
# APP_SECURITY_ALERTS_MIN_SEVERITY=high # minimum severity: critical, high, medium, low (default: high)
57+
# APP_SECURITY_ALERTS_MIN_AGE_DAYS=30
58+
# APP_SECURITY_ALERTS_MIN_SEVERITY=high
3459

35-
# slack configuration (optional)
60+
# slack (optional; the token and channel are required together)
3661
APP_SLACK_TOKEN=xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3762
APP_SLACK_CHANNEL=C01234ABCDE
38-
# optional: per-notification-type channels (fall back to APP_SLACK_CHANNEL)
63+
# per notification type; each falls back to APP_SLACK_CHANNEL
3964
# APP_SLACK_CHANNEL_PR_BYPASS=C01234ABCDE
4065
# APP_SLACK_CHANNEL_OKTA_SYNC=C01234ABCDE
4166
# APP_SLACK_CHANNEL_ORPHANED_USERS=C01234ABCDE
4267
# APP_SLACK_CHANNEL_SECURITY_ALERTS=C01234ABCDE
43-
# optional: custom footer note for PR bypass notifications (supports Slack mrkdwn)
68+
# footer for pr bypass notifications, in slack mrkdwn
4469
# APP_SLACK_FOOTER_NOTE_PR_BYPASS=_Please review the <https://example.com/policy|security policy>._
45-
46-
# api gateway base path (optional, for lambda deployments with stage prefix)
47-
# APP_BASE_PATH=v1
48-
49-
# server port (optional, for cmd/server only, default: 8080)
50-
# APP_PORT=8080

‎.github/.dependabot.yaml‎

Lines changed: 0 additions & 11 deletions
This file was deleted.

‎.github/dependabot.yaml‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
groups:
8+
github-actions:
9+
patterns: ["*"]
10+
11+
- package-ecosystem: "gomod"
12+
directory: "/"
13+
schedule:
14+
interval: "weekly"
15+
groups:
16+
go-modules:
17+
patterns: ["*"]
18+
19+
# base images in the Dockerfile
20+
- package-ecosystem: "docker"
21+
directory: "/"
22+
schedule:
23+
interval: "weekly"
24+
groups:
25+
docker:
26+
patterns: ["*"]

‎.github/workflows/ci.yaml‎

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,86 @@ on:
55
branches:
66
- main
77
pull_request:
8-
branches:
9-
- main
108

119
permissions:
1210
contents: read
1311

12+
concurrency:
13+
group: ci-${{ github.ref }}
14+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
15+
1416
jobs:
1517
lint:
1618
runs-on: ubuntu-latest
1719
steps:
1820
- name: Checkout Code
19-
uses: actions/checkout@v4
20-
21+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22+
with:
23+
persist-credentials: false
2124
- name: Setup Go
22-
uses: actions/setup-go@v5
25+
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
2326
with:
24-
go-version: '1.24'
25-
26-
- name: Run go vet
27-
run: go vet ./...
28-
29-
- name: Check formatting
30-
run: |
31-
unformatted=$(gofmt -l .)
32-
if [ -n "$unformatted" ]; then
33-
echo "The following files are not formatted:"
34-
echo "$unformatted"
35-
exit 1
36-
fi
27+
go-version-file: go.mod
28+
- name: Check go.mod is tidy
29+
run: go mod tidy -diff
30+
- name: Lint
31+
run: make lint
3732

3833
test:
3934
runs-on: ubuntu-latest
4035
steps:
4136
- name: Checkout Code
42-
uses: actions/checkout@v4
43-
37+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
38+
with:
39+
persist-credentials: false
4440
- name: Setup Go
45-
uses: actions/setup-go@v5
41+
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
4642
with:
47-
go-version: '1.24'
48-
49-
- name: Run unit tests
43+
go-version-file: go.mod
44+
- name: Test
5045
run: make test
5146

52-
- name: Run integration tests
53-
run: make test-verify-verbose
47+
vuln:
48+
runs-on: ubuntu-latest
49+
steps:
50+
- name: Checkout Code
51+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
52+
with:
53+
persist-credentials: false
54+
- name: Setup Go
55+
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
56+
with:
57+
go-version-file: go.mod
58+
- name: Check for known vulnerabilities
59+
run: make vuln
5460

5561
build:
5662
runs-on: ubuntu-latest
63+
strategy:
64+
matrix:
65+
goarch: [amd64, arm64]
5766
steps:
5867
- name: Checkout Code
59-
uses: actions/checkout@v4
60-
68+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
69+
with:
70+
persist-credentials: false
6171
- name: Setup Go
62-
uses: actions/setup-go@v5
72+
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
6373
with:
64-
go-version: '1.24'
65-
74+
go-version-file: go.mod
75+
- name: Build Server
76+
run: make build GOOS=linux GOARCH=${{ matrix.goarch }}
6677
- name: Build Lambda
67-
run: GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -C cmd/lambda -o ../../dist/bootstrap
78+
run: make build-lambda GOARCH=${{ matrix.goarch }}
79+
80+
image:
81+
runs-on: ubuntu-latest
82+
steps:
83+
- name: Checkout Code
84+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
85+
with:
86+
persist-credentials: false
87+
- name: Setup Buildx
88+
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
89+
- name: Build Container Image
90+
run: docker buildx build --platform linux/amd64,linux/arm64 --build-arg VERSION=ci .

‎.github/workflows/release.yaml‎

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,64 @@ on:
88
permissions:
99
contents: write
1010

11+
concurrency:
12+
group: release
13+
cancel-in-progress: false
14+
1115
jobs:
1216
release:
1317
runs-on: ubuntu-latest
1418
steps:
1519
- name: Checkout Code
16-
uses: actions/checkout@v3
17-
- name: Bump Version
20+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21+
with:
22+
persist-credentials: false
23+
- name: Setup Go
24+
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
25+
with:
26+
go-version-file: go.mod
27+
cache: false
28+
# dry_run only computes the version; the release step creates the tag
29+
# after the artifacts build, so a failed build leaves no tag behind
30+
- name: Compute Version
1831
id: tag_version
19-
uses: mathieudutour/github-tag-action@v6.1
32+
uses: mathieudutour/github-tag-action@af99e60ce8132224b8e6ebab5023449fe256ed46 # v7.0.0
2033
with:
2134
github_token: ${{ secrets.GITHUB_TOKEN }}
35+
dry_run: true
2236
default_bump: minor
23-
custom_release_rules: bug:patch:Fixes,chore:patch:Chores,docs:patch:Documentation,feat:minor:Features,refactor:minor:Refactors,test:patch:Tests,ci:patch:Development,dev:patch:Development
37+
# a custom rule that matches a commit's type wins over the default
38+
# "breaking change -> major" rule, so types that carry breaking
39+
# changes (feat, fix, refactor) must not be listed here. feat and
40+
# fix use the default rules, and refactor uses default_bump.
41+
custom_release_rules: bug:patch:Fixes,chore:patch:Chores,docs:patch:Documentation,test:patch:Tests,ci:patch:Development,dev:patch:Development
42+
- name: Build Artifacts
43+
if: steps.tag_version.outputs.new_tag != ''
44+
env:
45+
VERSION: ${{ steps.tag_version.outputs.new_tag }}
46+
run: |
47+
mkdir -p release
48+
for arch in amd64 arm64; do
49+
make build GOOS=linux GOARCH="$arch" VERSION="$VERSION"
50+
tar -czf "release/github-ops-app_linux_${arch}.tar.gz" -C dist github-ops-app
51+
make build-lambda GOARCH="$arch" VERSION="$VERSION"
52+
(cd dist && zip -X -q "../release/github-ops-app_lambda_${arch}.zip" bootstrap)
53+
done
54+
(cd release && sha256sum *.tar.gz *.zip > checksums.txt)
55+
- name: Setup Buildx
56+
if: steps.tag_version.outputs.new_tag != ''
57+
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
58+
- name: Build Container Image
59+
if: steps.tag_version.outputs.new_tag != ''
60+
env:
61+
VERSION: ${{ steps.tag_version.outputs.new_tag }}
62+
run: docker buildx build --platform linux/amd64,linux/arm64 --build-arg VERSION="$VERSION" .
2463
- name: Create Release
25-
uses: ncipollo/release-action@v1.12.0
64+
if: steps.tag_version.outputs.new_tag != ''
65+
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
2666
with:
2767
tag: ${{ steps.tag_version.outputs.new_tag }}
68+
commit: ${{ github.sha }}
2869
name: ${{ steps.tag_version.outputs.new_tag }}
2970
body: ${{ steps.tag_version.outputs.changelog }}
71+
artifacts: release/*

‎.github/workflows/semantic-check.yaml‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ jobs:
1515
name: Semantic Commit Message Check
1616
runs-on: ubuntu-latest
1717
steps:
18-
- name: Checkout Code
19-
uses: actions/checkout@v3
20-
- uses: amannn/action-semantic-pull-request@v5.2.0
18+
- uses: amannn/action-semantic-pull-request@2252a14e810aa9b85c2d560bd7070c802206ecf6 # v6.1.2
2119
name: Check PR for Semantic Commit Message
2220
env:
2321
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)