diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 3b535c8..d20bb93 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -57,7 +57,6 @@ jobs: VITEST_STORAGE_DRIVER: ${{ matrix.storage-driver }} deploy: - if: github.event.ref == 'refs/heads/dev' name: 🚀 Build and push permissions: packages: write @@ -67,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v6 with: - ref: dev + ref: ${{ github.ref_name }} - name: Get build hash id: build_hash @@ -79,7 +78,7 @@ jobs: with: images: ghcr.io/${{ github.repository }} tags: | - dev + ${{ github.ref_name }} - name: Login to GitHub Container Registry uses: docker/login-action@v4 @@ -111,7 +110,7 @@ jobs: with: images: ghcr.io/${{ github.repository }} tags: | - dev-caged + ${{ github.ref_name }}-caged - name: Build and push (caged) uses: docker/build-push-action@v7 @@ -124,3 +123,42 @@ jobs: build-args: | BUILD_HASH=${{ steps.build_hash.outputs.COMMIT_SHA }} BASE_IMAGE=platformatic/node-caged:25-alpine + + deploy-chart: + name: 🚀 Build and push Helm chart + permissions: + packages: write + contents: read + needs: [deploy] + runs-on: ubuntu-latest + env: + CHART_DIR: install/kubernetes/github-actions-cache-server + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.ref_name }} + + - name: Bump version + id: bump-version + run: | + export VERSION=$(node -p "require('./package.json').version") + node scripts/release-metadata.mjs bump dev + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Package Helm chart + run: helm package . --destination packaged + working-directory: ${{ env.CHART_DIR }} + + - name: Push Helm chart to GHCR + run: | + shopt -s nullglob + for pkg in ${{ env.CHART_DIR }}/packaged/*.tgz; do + echo "Pushing $pkg to ghcr.io/${{ github.repository_owner }}/charts" + helm push "$pkg" "oci://ghcr.io/${{ github.repository_owner }}/charts" + done diff --git a/install/kubernetes/github-actions-cache-server/values.yaml b/install/kubernetes/github-actions-cache-server/values.yaml index c25b8b6..175f67b 100644 --- a/install/kubernetes/github-actions-cache-server/values.yaml +++ b/install/kubernetes/github-actions-cache-server/values.yaml @@ -85,9 +85,9 @@ config: # region: us-east-1 # -- Custom S3 endpoint URL (e.g. for MinIO: "http://minio:9000") # endpointUrl: '' - # -- AWS access key ID. Can also be provided via existingSecret. + # -- AWS access key ID. Can also be provided via existingSecret with key: AWS_ACCESS_KEY_ID. # accessKeyId: '' - # -- AWS secret access key. Can also be provided via existingSecret. + # -- AWS secret access key. Can also be provided via existingSecret with key: AWS_SECRET_ACCESS_KEY. # secretAccessKey: '' # -- Socket inactivity timeout in milliseconds. Set to 0 to disable. socketTimeoutMs: 10000 diff --git a/lib/schemas.ts b/lib/schemas.ts index bca21c6..a001912 100644 --- a/lib/schemas.ts +++ b/lib/schemas.ts @@ -1,14 +1,29 @@ import { type } from 'arkenv' +const envS3StorageDriverBaseSchema = { + 'STORAGE_DRIVER': type.unit('s3'), + 'STORAGE_S3_BUCKET': 'string', + 'STORAGE_S3_SOCKET_TIMEOUT_MS': 'number.integer >= 0 = 10000', + 'AWS_REGION': "string = 'us-east-1'", + 'AWS_ENDPOINT_URL?': 'string.url', +} as const + export const envStorageDriverSchema = type.or( { - 'STORAGE_DRIVER': type.unit('s3'), - 'STORAGE_S3_BUCKET': 'string', - 'STORAGE_S3_SOCKET_TIMEOUT_MS': 'number.integer >= 0 = 10000', - 'AWS_REGION': "string = 'us-east-1'", - 'AWS_ENDPOINT_URL?': 'string.url', - 'AWS_ACCESS_KEY_ID?': 'string', - 'AWS_SECRET_ACCESS_KEY?': 'string', + ...envS3StorageDriverBaseSchema, + 'AWS_ACCESS_KEY_ID': 'string', + 'AWS_SECRET_ACCESS_KEY': 'string', + 'AWS_ROLE_ARN?': 'undefined', + 'AWS_WEB_IDENTITY_TOKEN_FILE?': 'undefined', + 'AWS_ROLE_SESSION_NAME?': 'undefined', + }, + { + ...envS3StorageDriverBaseSchema, + 'AWS_ROLE_ARN': 'string', + 'AWS_WEB_IDENTITY_TOKEN_FILE': 'string', + 'AWS_ROLE_SESSION_NAME?': 'string', + 'AWS_ACCESS_KEY_ID?': 'undefined', + 'AWS_SECRET_ACCESS_KEY?': 'undefined', }, { STORAGE_DRIVER: type.unit('filesystem'), diff --git a/scripts/release-metadata.mjs b/scripts/release-metadata.mjs index 06cf475..3adc39d 100644 --- a/scripts/release-metadata.mjs +++ b/scripts/release-metadata.mjs @@ -44,7 +44,7 @@ async function readMetadata() { } async function bumpChartVersion(bump) { - if (!['patch', 'minor', 'major'].includes(bump)) { + if (!['patch', 'minor', 'major', 'dev'].includes(bump)) { fail(`chart bump must be one of patch, minor, or major, received "${bump ?? ''}"`) } @@ -60,13 +60,16 @@ async function bumpChartVersion(bump) { ;[minor, patch] = [minor + 1, 0] break } - case 'patch': { + case 'patch' || 'dev': { patch += 1 break } } - const chartVersion = `${major}.${minor}.${patch}` + let chartVersion = `${major}.${minor}.${patch}` + if (bump === 'dev') { + chartVersion += '-dev' + } const chart = replaceChartField( replaceChartField(metadata.chart, 'version', chartVersion), 'appVersion', diff --git a/tests/s3-irsa.test.ts b/tests/s3-irsa.test.ts new file mode 100644 index 0000000..86e3ed4 --- /dev/null +++ b/tests/s3-irsa.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test } from 'vitest' +import { envSchema } from '~/lib/schemas' + +const baseEnv = { + API_BASE_URL: 'http://localhost:3000', + DB_DRIVER: 'sqlite', + DB_SQLITE_PATH: 'tests/temp/vitest.sqlite', + STORAGE_DRIVER: 's3', + STORAGE_S3_BUCKET: 'vitest', + STORAGE_S3_SOCKET_TIMEOUT_MS: 10_000, + AWS_REGION: 'us-east-1', +} as const + +describe.skipIf(process.env.VITEST_STORAGE_DRIVER !== 's3')('test S3 IRSA authentication', () => { + test('accepts AWS Web Identity environment variables', () => { + expect(() => + envSchema.assert({ + ...baseEnv, + AWS_ROLE_ARN: 'arn:aws:iam::123456789012:role/github-actions-cache-server', + AWS_ROLE_SESSION_NAME: 'github-actions-cache-server', + AWS_WEB_IDENTITY_TOKEN_FILE: '/var/run/secrets/eks.amazonaws.com/serviceaccount/token', + }), + ).not.toThrow() + }) + + test('requires Web Identity settings', () => { + expect(() => + envSchema.assert({ + ...baseEnv, + AWS_ROLE_ARN: 'arn:aws:iam::123456789012:role/github-actions-cache-server', + }), + ).toThrow() + }) +})