diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index fa24f06..762834e 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -21,6 +21,6 @@ updates: labels: [] open-pull-requests-limit: 15 groups: - x: + all-dependencies: patterns: - - "golang.org/x/*" + - "*" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..fdf23bb --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,46 @@ +name: OpenSSF Scorecard + +on: + branch_protection_rule: + schedule: + # Run weekly on Wednesdays at 7:27 UTC + - cron: "27 7 * * 3" + push: + branches: + - main + +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + security-events: write + id-token: write + + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Run analysis + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + results_file: results.sarif + results_format: sarif + repo_token: ${{ secrets.GITHUB_TOKEN }} + publish_results: true + + - name: Upload artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + - name: Upload to code-scanning + uses: github/codeql-action/upload-sarif@755f44910c12a3d7ca0d8c6e42c048b3362f7cec # v3.30.8 + with: + sarif_file: results.sarif diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml new file mode 100644 index 0000000..6487502 --- /dev/null +++ b/.github/workflows/security.yaml @@ -0,0 +1,110 @@ +name: security + +on: + push: + branches: + - main + pull_request: + schedule: + # Run every day at 10:00 UTC (6:00 AM ET / 3:00 AM PT) + - cron: "0 10 * * *" + workflow_dispatch: + +permissions: + contents: read + +# Cancel in-progress runs for pull requests when developers push +# additional changes +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + codeql: + name: CodeQL Analysis + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Setup Go + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version-file: "go.mod" + + - name: Initialize CodeQL + uses: github/codeql-action/init@755f44910c12a3d7ca0d8c6e42c048b3362f7cec # v3.30.8 + with: + languages: go + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@755f44910c12a3d7ca0d8c6e42c048b3362f7cec # v3.30.8 + with: + category: "/language:go" + + trivy: + name: Trivy Docker Image Scan + runs-on: ubuntu-latest + permissions: + security-events: write + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Setup Go + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version-file: "go.mod" + + - name: Build binary for linux/amd64 + run: make bin/code-marketplace-linux-amd64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build Docker image + id: build + run: | + docker buildx bake \ + -f ./docker-bake.hcl \ + --set "*.platform=linux/amd64" \ + --set "*.tags=code-marketplace:scan" \ + --load + echo "image=code-marketplace:scan" >> "$GITHUB_OUTPUT" + + - name: Run Trivy vulnerability scanner (table output for logs) + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1 + with: + image-ref: ${{ steps.build.outputs.image }} + format: "table" + severity: "LOW,MEDIUM,HIGH,CRITICAL" + + - name: Run Trivy vulnerability scanner (SARIF output for GitHub) + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1 + with: + image-ref: ${{ steps.build.outputs.image }} + format: "sarif" + output: "trivy-results.sarif" + severity: "LOW,MEDIUM,HIGH,CRITICAL" + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@755f44910c12a3d7ca0d8c6e42c048b3362f7cec # v3.30.8 + with: + sarif_file: "trivy-results.sarif" + category: "Trivy" + + - name: Upload Trivy scan results as artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: trivy-results + path: trivy-results.sarif + retention-days: 7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c39ce7..30ae068 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + - Update the Kubernetes Deployment `spec.strategy.type` field to be of type `Recreate` in order to properly handle upgrades/restarts as the default deployment creates a PVC of type `ReadWriteOnce` and could only be assigned to one replica. diff --git a/Makefile b/Makefile index 942ce2a..1aa5c42 100644 --- a/Makefile +++ b/Makefile @@ -27,11 +27,36 @@ upload: TAG=$(shell git describe --always) -build: - CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o bin/code-marketplace-mac-amd64 ./cmd/marketplace/main.go - CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o bin/code-marketplace-mac-arm64 ./cmd/marketplace/main.go - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o bin/code-marketplace-linux-amd64 ./cmd/marketplace/main.go - CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o bin/code-marketplace-linux-arm64 ./cmd/marketplace/main.go - CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o bin/code-marketplace-windows-amd64 ./cmd/marketplace/main.go - CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o bin/code-marketplace-windows-arm64 ./cmd/marketplace/main.go +# Individual build targets for each OS/arch combination +bin/code-marketplace-mac-amd64: $(wildcard **/*.go) go.mod go.sum + mkdir -p bin + CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o $@ ./cmd/marketplace/main.go + +bin/code-marketplace-mac-arm64: $(wildcard **/*.go) go.mod go.sum + mkdir -p bin + CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o $@ ./cmd/marketplace/main.go + +bin/code-marketplace-linux-amd64: $(wildcard **/*.go) go.mod go.sum + mkdir -p bin + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o $@ ./cmd/marketplace/main.go + +bin/code-marketplace-linux-arm64: $(wildcard **/*.go) go.mod go.sum + mkdir -p bin + CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o $@ ./cmd/marketplace/main.go + +bin/code-marketplace-windows-amd64: $(wildcard **/*.go) go.mod go.sum + mkdir -p bin + CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o $@ ./cmd/marketplace/main.go + +bin/code-marketplace-windows-arm64: $(wildcard **/*.go) go.mod go.sum + mkdir -p bin + CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags "-X github.com/coder/code-marketplace/buildinfo.tag=$(TAG)" -o $@ ./cmd/marketplace/main.go + +# Main build target - builds all platforms +build: bin/code-marketplace-mac-amd64 \ + bin/code-marketplace-mac-arm64 \ + bin/code-marketplace-linux-amd64 \ + bin/code-marketplace-linux-arm64 \ + bin/code-marketplace-windows-amd64 \ + bin/code-marketplace-windows-arm64 .PHONY: build diff --git a/README.md b/README.md index 3c6c2d2..4caf02f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,35 @@ This marketplace reads extensions from file storage and provides an API for editors to consume. It does not have a frontend or any mechanisms for extension authors to add or update extensions in the marketplace. +## Development + +### Requirements + +- Go 1.21 or later +- GNU Make 4.3 or later (for recursive glob support in build targets) + +### Building from source + +Build all platform binaries: + +```console +make build +``` + +Build a specific platform: + +```console +make bin/code-marketplace-linux-amd64 +``` + +Available targets: +- `bin/code-marketplace-mac-amd64` +- `bin/code-marketplace-mac-arm64` +- `bin/code-marketplace-linux-amd64` +- `bin/code-marketplace-linux-arm64` +- `bin/code-marketplace-windows-amd64` +- `bin/code-marketplace-windows-arm64` + ## Deployment The marketplace is a single binary. Deployment involves running the binary, @@ -219,7 +248,7 @@ using code-marketplace with VS Code and VSCodium: - [VSCodium](https://github.com/VSCodium/vscodium/blob/master/docs/index.md#howto-switch-marketplace) - ``` + ```console export VSCODE_GALLERY_SERVICE_URL="https:///api export VSCODE_GALLERY_ITEM_URL="https:///item" # Or set a product.json file in `~/.config/VSCodium/product.json`