Skip to content

Commit 7f4c163

Browse files
v3.1.0 (#62)
2 parents 090165c + a4f7b0c commit 7f4c163

File tree

23 files changed

+654
-69
lines changed

23 files changed

+654
-69
lines changed

.github/workflows/ci-cd.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
workflow_dispatch:
55
push:
66
branches: '**'
7+
pull_request:
8+
branches:
9+
- dev
710

811
concurrency:
912
group: ${{ github.workflow }}-${{ github.ref }}
@@ -41,7 +44,7 @@ jobs:
4144
runs-on: ubuntu-latest
4245
strategy:
4346
matrix:
44-
storage-driver: [filesystem, memory, s3]
47+
storage-driver: [filesystem, memory, s3, gcs]
4548
db-driver: [postgres, mysql, sqlite]
4649
steps:
4750
- name: pnpm install
@@ -50,6 +53,7 @@ jobs:
5053
- run: VITEST_DB_DRIVER=${{ matrix.db-driver }} VITEST_STORAGE_DRIVER=${{ matrix.storage-driver }} pnpm run test:run
5154

5255
deploy:
56+
if: github.event.ref == 'refs/heads/dev'
5357
name: 🚀 Build and push
5458
permissions:
5559
packages: write

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ RUN corepack enable
99
RUN corepack prepare pnpm@latest-9 --activate
1010

1111
COPY package.json pnpm-lock.yaml .npmrc ./
12+
COPY patches patches
1213

1314
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm fetch --prod
1415

docs/content/1.getting-started/2.storage-drivers.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ description: A list of storage drivers available for the GitHub Actions Cache Se
55

66
- [File System](/storage-drivers/filesystem)
77
- [S3 / MinIO](/storage-drivers/s3)
8+
- [GCS](/storage-drivers/gcs)
89
- [Memory](/storage-drivers/memory)

docs/content/2.storage-drivers/gcs.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
title: Google Cloud Storage
3+
description: This storage driver stores the cache in a GCS bucket.
4+
---
5+
6+
Driver: `gcs`
7+
8+
This storage driver stores the cache in a GCS bucket.
9+
10+
## Configuration
11+
12+
### `docker-compose` GCS bucket
13+
14+
```yaml [docker-compose.yml]
15+
version: '3.9'
16+
17+
services:
18+
cache-server:
19+
image: ghcr.io/falcondev-oss/github-actions-cache-server:latest
20+
ports:
21+
- '3000:3000'
22+
environment:
23+
URL_ACCESS_TOKEN: random_token
24+
API_BASE_URL: http://localhost:3000
25+
26+
STORAGE_DRIVER: gcs
27+
STORAGE_GCS_BUCKET: gh-actions-cache
28+
# Optional, not required if running in GCP
29+
STORAGE_GCS_SERVICE_ACCOUNT_KEY: /gcp/config/application_default_credentials.json
30+
volumes:
31+
- cache-data:/app/.data
32+
33+
# Use host's application default credentials
34+
- $HOME/.config/gcloud:/gcp/config:ro
35+
36+
volumes:
37+
cache-data:
38+
```
39+
40+
### Environment Variables
41+
42+
Don't forget to set the `STORAGE_DRIVER` environment variable to `gcs` to use the GCS storage driver.
43+
44+
#### `STORAGE_GCS_BUCKET`
45+
46+
Example: `gh-actions-cache`
47+
48+
The name of the GCS bucket used for storage.
49+
50+
#### `STORAGE_GCS_SERVICE_ACCOUNT_KEY`
51+
52+
Example: `/config/auth/serviceaccount.json`
53+
54+
Path to the service account key used for authentication. If not set, [Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials) is used.
55+
56+
#### `STORAGE_GCS_ENDPOINT`
57+
58+
Example: `http://localhost:9000`
59+
60+
The API endpoint for GCS.

lib/db/index.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ export interface CacheKeysTable {
1919
accessed_at: string
2020
}
2121

22-
async function initializeDatabase() {
22+
let db: Kysely<Database>
23+
24+
export async function initializeDatabase() {
2325
const driverName = ENV.DB_DRIVER
2426
const driverSetup = getDatabaseDriver(driverName)
2527
if (!driverSetup) {
@@ -31,7 +33,7 @@ async function initializeDatabase() {
3133

3234
const driver = await driverSetup()
3335

34-
const db = new Kysely<Database>({
36+
db = new Kysely<Database>({
3537
dialect: driver,
3638
})
3739

@@ -52,12 +54,8 @@ async function initializeDatabase() {
5254
}
5355
logger.debug('Migration results', results)
5456
logger.success('Database migrated')
55-
56-
return db
5757
}
5858

59-
const db = await initializeDatabase()
60-
6159
/**
6260
* @see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
6361
*/

lib/env.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { z } from 'zod'
33
const envSchema = z.object({
44
URL_ACCESS_TOKEN: z.string().min(1),
55
CLEANUP_OLDER_THAN_DAYS: z.coerce.number().int().min(0).default(90),
6-
API_BASE_URL: z.string().min(1),
6+
API_BASE_URL: z.string().url(),
77
STORAGE_DRIVER: z.string().toLowerCase().default('filesystem'),
88
DB_DRIVER: z.string().toLowerCase().default('sqlite'),
99
TEMP_DIR: z.string().min(1).default('/tmp'),

lib/storage/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ await fs.mkdir(bufferDir, {
2020
recursive: true,
2121
})
2222

23-
async function initializeStorageDriver() {
23+
let storageAdapter: StorageAdapter
24+
25+
export async function initializeStorageAdapter() {
2426
try {
2527
const driverName = ENV.STORAGE_DRIVER
2628
const driverSetup = getStorageDriver(driverName)
@@ -38,7 +40,7 @@ async function initializeStorageDriver() {
3840
const commitLocks = new Set<number>()
3941
const uploadChunkLocks = new Map<string, Promise<any>>()
4042

41-
return <StorageAdapter>{
43+
storageAdapter = {
4244
async reserveCache(key, version, cacheSize) {
4345
logger.debug('Reserve: Reserving cache for', key, version, cacheSize ?? '[no cache size]')
4446
const bufferKey = `${key}:${version}`
@@ -199,4 +201,6 @@ async function initializeStorageDriver() {
199201
}
200202
}
201203

202-
export const storageAdapter = await initializeStorageDriver()
204+
export function useStorageAdapter() {
205+
return storageAdapter
206+
}

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "github-actions-cache-server",
33
"type": "module",
4-
"version": "3.0.0",
4+
"version": "3.1.0",
55
"private": true,
66
"packageManager": "pnpm@9.1.3",
77
"engines": {
@@ -24,11 +24,13 @@
2424
"extends": "gh:falcondev-it/configs/changelogithub"
2525
},
2626
"dependencies": {
27+
"@google-cloud/storage": "^7.12.1",
2728
"@types/better-sqlite3": "^7.6.11",
2829
"@types/pg": "^8.11.6",
2930
"better-sqlite3": "^11.1.2",
3031
"consola": "^3.2.3",
3132
"croner": "^8.1.0",
33+
"execa": "^9.3.1",
3234
"h3": "^1.12.0",
3335
"kysely": "^0.27.4",
3436
"minio": "^8.0.1",
@@ -65,5 +67,10 @@
6567
"ts-pattern": "^5.2.0",
6668
"vitest": "^2.0.4",
6769
"wait-on": "^8.0.0"
70+
},
71+
"pnpm": {
72+
"patchedDependencies": {
73+
"nitropack@2.9.7": "patches/nitropack@2.9.7.patch"
74+
}
6875
}
6976
}

patches/nitropack@2.9.7.patch

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
diff --git a/dist/runtime/app.mjs b/dist/runtime/app.mjs
2+
index 6e968f59e719851b0fc166bc02a30e41ebbb8e63..10d19fed1cf71f82d912be1210dc9ec906fe9d6f 100644
3+
--- a/dist/runtime/app.mjs
4+
+++ b/dist/runtime/app.mjs
5+
@@ -22,7 +22,7 @@ import { nitroAsyncContext } from "./context.mjs";
6+
import { plugins } from "#internal/nitro/virtual/plugins";
7+
import errorHandler from "#internal/nitro/virtual/error-handler";
8+
import { handlers } from "#internal/nitro/virtual/server-handlers";
9+
-function createNitroApp() {
10+
+async function createNitroApp() {
11+
const config = useRuntimeConfig();
12+
const hooks = createHooks();
13+
const captureError = (error, context = {}) => {
14+
@@ -140,7 +140,7 @@ function createNitroApp() {
15+
};
16+
for (const plugin of plugins) {
17+
try {
18+
- plugin(app);
19+
+ await plugin(app);
20+
} catch (err) {
21+
captureError(err, { tags: ["plugin"] });
22+
throw err;
23+
@@ -148,5 +148,5 @@ function createNitroApp() {
24+
}
25+
return app;
26+
}
27+
-export const nitroApp = createNitroApp();
28+
+export const nitroApp = await createNitroApp();
29+
export const useNitroApp = () => nitroApp;
30+
diff --git a/dist/runtime/plugin.d.ts b/dist/runtime/plugin.d.ts
31+
index a83e51dc732331862e8eac011e97ae784ee525b8..7907875fe883e837e9305acccdd4cd55a1bf3353 100644
32+
--- a/dist/runtime/plugin.d.ts
33+
+++ b/dist/runtime/plugin.d.ts
34+
@@ -1,6 +1,6 @@
35+
import type { NitroApp } from "./app";
36+
export interface NitroAppPlugin {
37+
- (nitro: NitroApp): void;
38+
+ (nitro: NitroApp): Promise<void> | void;
39+
}
40+
export declare function defineNitroPlugin(def: NitroAppPlugin): NitroAppPlugin;
41+
export declare const nitroPlugin: typeof defineNitroPlugin;

plugins/cleanup.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { colorize } from 'consola/utils'
22
import { Cron } from 'croner'
33

4+
import { useStorageAdapter } from '~/lib/storage'
5+
46
import { ENV } from '@/lib/env'
57
import { logger } from '@/lib/logger'
6-
import { storageAdapter } from '@/lib/storage'
78

89
export default defineNitroPlugin(() => {
910
if (ENV.CLEANUP_OLDER_THAN_DAYS === 0) return
@@ -14,6 +15,6 @@ export default defineNitroPlugin(() => {
1415
`Cleaning up cache entries older than ${colorize('blue', `${ENV.CLEANUP_OLDER_THAN_DAYS}d`)} with schedule ${colorize('blue', job.getPattern() ?? '')}${nextRun ? ` (next run: ${nextRun.toLocaleString()})` : ''}`,
1516
)
1617
job.schedule(async () => {
17-
await storageAdapter.pruneCaches(ENV.CLEANUP_OLDER_THAN_DAYS)
18+
await useStorageAdapter().pruneCaches(ENV.CLEANUP_OLDER_THAN_DAYS)
1819
})
1920
})

0 commit comments

Comments
 (0)