Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 0 additions & 13 deletions .cspell.json

This file was deleted.

3 changes: 0 additions & 3 deletions .dockerfilelintrc

This file was deleted.

5 changes: 4 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
node_modules
npm-debug.log

credentials.json
.git
.github
*.md
6 changes: 3 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ updates:
- package-ecosystem: "docker"
directory: "/" # Location of package manifests
schedule:
interval: "daily"
interval: "weekly"
- package-ecosystem: "npm"
directory: "/" # Location of package manifests
schedule:
interval: "daily"
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/" # default location of `.github/workflows`
schedule:
interval: "daily"
interval: "weekly"
100 changes: 100 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: CI

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

# Bucket used by the live tests and the container smoke test.
env:
BUCKET: s3proxy-public
IMAGE: s3proxy-docker:ci

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci --no-audit --no-fund
- run: npm run lint

test:
name: App Tests
runs-on: ubuntu-latest
needs: [lint]
# The app tests exercise live S3 (health, object GET, 404). Dependabot PRs
# don't receive repo secrets, so skip AWS-dependent jobs for them.
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci --no-audit --no-fund
- run: npm run test:app

docker:
name: Docker Build & Smoke
runs-on: ubuntu-latest
needs: [lint]
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Build image
uses: docker/build-push-action@v6
with:
context: .
target: production
load: true
tags: ${{ env.IMAGE }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Structural checks (non-root user, layout, missing-BUCKET guard) run
# against the image just built, rather than rebuilding it.
- name: Container tests
run: npm run test:container
env:
S3PROXY_IMAGE: ${{ env.IMAGE }}
- name: Smoke test the container
run: |
docker run -d --name s3proxy -p 8080:8080 \
-e BUCKET="$BUCKET" \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
-e AWS_REGION "$IMAGE"
# Wait for the healthcheck to report healthy (max ~30s).
for i in $(seq 1 30); do
status=$(docker inspect -f '{{.State.Health.Status}}' s3proxy 2>/dev/null || echo starting)
echo "health: $status"
[ "$status" = "healthy" ] && break
sleep 2
done
[ "$(docker inspect -f '{{.State.Health.Status}}' s3proxy)" = "healthy" ]
echo "--- GET /index.html ---"
curl -fsS -o /dev/null -w "status=%{http_code} type=%{content_type}\n" http://localhost:8080/index.html
echo "--- GET missing key (expect 404) ---"
code=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/does-not-exist)
[ "$code" = "404" ] || { echo "expected 404, got $code"; exit 1; }
- name: Container logs
if: always()
run: docker logs s3proxy || true
133 changes: 0 additions & 133 deletions .github/workflows/continuous-deployment.yml

This file was deleted.

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

# Publishes forkzero/s3proxy to Docker Hub when a GitHub Release is published.
# The release tag (e.g. v4.1.0) drives the image tags via docker/metadata-action.
on:
release:
types: [published]
workflow_dispatch:

env:
IMAGE: forkzero/s3proxy

jobs:
publish:
name: Build & Push
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4

- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}

- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
target: production
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.meta.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max

scan:
name: Trivy Scan
runs-on: ubuntu-latest
needs: [publish]
permissions:
contents: read
security-events: write
steps:
- name: Scan published image
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ${{ env.IMAGE }}:latest
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
exit-code: '0' # report only; don't fail the pipeline
- name: Upload results to code scanning
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
15 changes: 0 additions & 15 deletions .jscpd.json

This file was deleted.

12 changes: 0 additions & 12 deletions .mega-linter.yml

This file was deleted.

Loading
Loading