ソースを参照

CI: download previous build using GitHub Actions

SukkaW 1 年間 前
コミット
a812c40384
6 ファイル変更42 行追加69 行削除
  1. 33 5
      .github/workflows/main.yml
  2. 2 5
      Build/constants/dir.ts
  3. 6 0
      Build/download-previous-build.ts
  4. 1 7
      Build/index.ts
  5. 0 1
      package.json
  6. 0 51
      pnpm-lock.yaml

+ 33 - 5
.github/workflows/main.yml

@@ -30,6 +30,33 @@ jobs:
         with:
         with:
           node-version-file: ".node-version"
           node-version-file: ".node-version"
           cache: "pnpm"
           cache: "pnpm"
+      - name: Create RAM Disk for building
+        id: ramdisk
+        run: |
+          BUILD_DIR=$(mktemp -d -p /dev/shm/ -t sukka-surge-public.XXXXXXXXXX)
+          echo "Build dir created at $BUILD_DIR"
+          echo "build_dir=$BUILD_DIR" >> $GITHUB_OUTPUT
+      - name: Download Previous Build
+        uses: actions/checkout@v4
+        with:
+          repository: SukkaLab/ruleset.skk.moe
+          persist-credentials: false
+          path: previous-build-${{ github.run_id }}-${{ github.run_number }}
+      - run: mv previous-build-${{ github.run_id }}-${{ github.run_number }}/{.,}* ${{ steps.ramdisk.outputs.build_dir }}/
+      - name: build folder check
+        # If the public directory doesn't exist, the build should fail.
+        # If the public directory is empty, the build should fail.
+        run: |
+          if [ ! -d ${{ steps.ramdisk.outputs.build_dir }}/.git ]; then
+            echo ".git not found"
+            exit 1
+          fi
+          if [ ! -d ${{ steps.ramdisk.outputs.build_dir }}/List ]; then
+            echo "List not found"
+            exit 1
+          fi
+          echo "public directory is ready: ${{ steps.ramdisk.outputs.build_dir }}"
+      - run: rm -rf "${{ steps.ramdisk.outputs.build_dir }}/.git"
       - name: Get current date
       - name: Get current date
         id: date
         id: date
         run: |
         run: |
@@ -57,16 +84,17 @@ jobs:
             ${{ runner.os }}-v3-
             ${{ runner.os }}-v3-
       - run: pnpm install
       - run: pnpm install
       - run: pnpm run build
       - run: pnpm run build
-        id: build
+        env:
+          PUBLIC_DIR: ${{ steps.ramdisk.outputs.build_dir }}
       - name: Pre-deploy check
       - name: Pre-deploy check
         # If the public directory doesn't exist, the build should fail.
         # If the public directory doesn't exist, the build should fail.
         # If the public directory is empty, the build should fail.
         # If the public directory is empty, the build should fail.
         run: |
         run: |
-          if [ ! -d ${{ steps.build.outputs.public_dir }} ]; then
+          if [ ! -d ${{ steps.ramdisk.outputs.build_dir }} ]; then
             echo "public directory not found"
             echo "public directory not found"
             exit 1
             exit 1
           fi
           fi
-          if [ ! "$(ls -A ${{ steps.build.outputs.public_dir }})" ]; then
+          if [ ! "$(ls -A ${{ steps.ramdisk.outputs.build_dir }})" ]; then
             echo "public directory is empty"
             echo "public directory is empty"
             exit 1
             exit 1
           fi
           fi
@@ -74,11 +102,11 @@ jobs:
             echo ".BUILD_FINISHED not found"
             echo ".BUILD_FINISHED not found"
             exit 1
             exit 1
           fi
           fi
-          echo "public directory is ready: ${{ steps.build.outputs.public_dir }}"
+          echo "public directory is ready: ${{ steps.ramdisk.outputs.build_dir }}"
       - uses: actions/upload-artifact@v4
       - uses: actions/upload-artifact@v4
         with:
         with:
           name: build-artifact-${{ github. ref_name }}
           name: build-artifact-${{ github. ref_name }}
-          path: ${{ steps.build.outputs.public_dir }}
+          path: ${{ steps.ramdisk.outputs.build_dir }}
           if-no-files-found: error
           if-no-files-found: error
           retention-days: 1
           retention-days: 1
           compression-level: 4
           compression-level: 4

+ 2 - 5
Build/constants/dir.ts

@@ -1,6 +1,5 @@
 import path from 'node:path';
 import path from 'node:path';
-import fs from 'node:fs';
-import { isCI } from 'ci-info';
+import process from 'node:process';
 
 
 export const ROOT_DIR = path.resolve(__dirname, '../..');
 export const ROOT_DIR = path.resolve(__dirname, '../..');
 
 
@@ -8,9 +7,7 @@ export const CACHE_DIR = path.resolve(ROOT_DIR, '.cache');
 
 
 export const SOURCE_DIR = path.join(ROOT_DIR, 'Source');
 export const SOURCE_DIR = path.join(ROOT_DIR, 'Source');
 
 
-export const PUBLIC_DIR = isCI
-  ? fs.mkdtempSync('/dev/shm/sukkaw-surge-public-')
-  : path.resolve(ROOT_DIR, 'public');
+export const PUBLIC_DIR = process.env.PUBLIC_DIR || path.resolve(ROOT_DIR, 'public');
 
 
 export const OUTPUT_SURGE_DIR = path.join(PUBLIC_DIR, 'List');
 export const OUTPUT_SURGE_DIR = path.join(PUBLIC_DIR, 'List');
 export const OUTPUT_CLASH_DIR = path.resolve(PUBLIC_DIR, 'Clash');
 export const OUTPUT_CLASH_DIR = path.resolve(PUBLIC_DIR, 'Clash');

+ 6 - 0
Build/download-previous-build.ts

@@ -10,6 +10,7 @@ import picocolors from 'picocolors';
 import { PUBLIC_DIR } from './constants/dir';
 import { PUBLIC_DIR } from './constants/dir';
 import { requestWithLog } from './lib/fetch-retry';
 import { requestWithLog } from './lib/fetch-retry';
 import { isDirectoryEmptySync } from './lib/misc';
 import { isDirectoryEmptySync } from './lib/misc';
+import { isCI } from 'ci-info';
 
 
 const GITHUB_CODELOAD_URL = 'https://codeload.github.com/sukkalab/ruleset.skk.moe/tar.gz/master';
 const GITHUB_CODELOAD_URL = 'https://codeload.github.com/sukkalab/ruleset.skk.moe/tar.gz/master';
 const GITLAB_CODELOAD_URL = 'https://gitlab.com/SukkaW/ruleset.skk.moe/-/archive/master/ruleset.skk.moe-master.tar.gz';
 const GITLAB_CODELOAD_URL = 'https://gitlab.com/SukkaW/ruleset.skk.moe/-/archive/master/ruleset.skk.moe-master.tar.gz';
@@ -20,6 +21,11 @@ export const downloadPreviousBuild = task(require.main === module, __filename)(a
     return;
     return;
   }
   }
 
 
+  // we uses actions/checkout to download the previous build now, so we should throw if the directory is empty
+  if (isCI) {
+    throw new Error('CI environment detected, but public directory is empty');
+  }
+
   const tarGzUrl = await span.traceChildAsync('get tar.gz url', async () => {
   const tarGzUrl = await span.traceChildAsync('get tar.gz url', async () => {
     const resp = await requestWithLog(GITHUB_CODELOAD_URL, { method: 'HEAD' });
     const resp = await requestWithLog(GITHUB_CODELOAD_URL, { method: 'HEAD' });
     if (resp.statusCode !== 200) {
     if (resp.statusCode !== 200) {

+ 1 - 7
Build/index.ts

@@ -29,9 +29,7 @@ import { buildCloudMounterRules } from './build-cloudmounter-rules';
 import { createSpan, printTraceResult, whyIsNodeRunning } from './trace';
 import { createSpan, printTraceResult, whyIsNodeRunning } from './trace';
 import { buildDeprecateFiles } from './build-deprecate-files';
 import { buildDeprecateFiles } from './build-deprecate-files';
 import path from 'node:path';
 import path from 'node:path';
-import { PUBLIC_DIR, ROOT_DIR } from './constants/dir';
-
-import { setOutput } from '@actions/core';
+import { ROOT_DIR } from './constants/dir';
 
 
 process.on('uncaughtException', (error) => {
 process.on('uncaughtException', (error) => {
   console.error('Uncaught exception:', error);
   console.error('Uncaught exception:', error);
@@ -108,10 +106,6 @@ const buildFinishedLock = path.join(ROOT_DIR, '.BUILD_FINISHED');
     // write a file to demonstrate that the build is finished
     // write a file to demonstrate that the build is finished
     fs.writeFileSync(buildFinishedLock, 'BUILD_FINISHED\n');
     fs.writeFileSync(buildFinishedLock, 'BUILD_FINISHED\n');
 
 
-    if (process.env.GITHUB_OUTPUT) {
-      setOutput('public_dir', PUBLIC_DIR);
-    }
-
     // Finish the build to avoid leaking timer/fetch ref
     // Finish the build to avoid leaking timer/fetch ref
     await whyIsNodeRunning();
     await whyIsNodeRunning();
     process.exit(0);
     process.exit(0);

+ 0 - 1
package.json

@@ -20,7 +20,6 @@
   "author": "",
   "author": "",
   "license": "ISC",
   "license": "ISC",
   "dependencies": {
   "dependencies": {
-    "@actions/core": "^1.11.1",
     "@ghostery/adblocker": "^2.3.1",
     "@ghostery/adblocker": "^2.3.1",
     "@henrygd/queue": "^1.0.7",
     "@henrygd/queue": "^1.0.7",
     "async-retry": "^1.3.3",
     "async-retry": "^1.3.3",

+ 0 - 51
pnpm-lock.yaml

@@ -19,9 +19,6 @@ importers:
 
 
   .:
   .:
     dependencies:
     dependencies:
-      '@actions/core':
-        specifier: ^1.11.1
-        version: 1.11.1
       '@ghostery/adblocker':
       '@ghostery/adblocker':
         specifier: ^2.3.1
         specifier: ^2.3.1
         version: 2.3.1
         version: 2.3.1
@@ -164,18 +161,6 @@ importers:
 
 
 packages:
 packages:
 
 
-  '@actions/core@1.11.1':
-    resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==}
-
-  '@actions/exec@1.1.1':
-    resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==}
-
-  '@actions/http-client@2.2.3':
-    resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==}
-
-  '@actions/io@1.1.3':
-    resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==}
-
   '@antfu/utils@0.7.10':
   '@antfu/utils@0.7.10':
     resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
     resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
 
 
@@ -249,10 +234,6 @@ packages:
     resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==}
     resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
 
-  '@fastify/busboy@2.1.1':
-    resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
-    engines: {node: '>=14'}
-
   '@ghostery/adblocker-content@2.3.1':
   '@ghostery/adblocker-content@2.3.1':
     resolution: {integrity: sha512-8ZTY1sEE218b0EMk3Q9fv/cWwUxunSCyBOaKuviEmJY5EyvPa1VbGPuTq/Qdvo1kduD8nLEzCwgWhcT3F3TT0Q==}
     resolution: {integrity: sha512-8ZTY1sEE218b0EMk3Q9fv/cWwUxunSCyBOaKuviEmJY5EyvPa1VbGPuTq/Qdvo1kduD8nLEzCwgWhcT3F3TT0Q==}
 
 
@@ -1745,10 +1726,6 @@ packages:
   tunnel-agent@0.6.0:
   tunnel-agent@0.6.0:
     resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
     resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
 
 
-  tunnel@0.0.6:
-    resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
-    engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
-
   type-check@0.4.0:
   type-check@0.4.0:
     resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
     resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
     engines: {node: '>= 0.8.0'}
     engines: {node: '>= 0.8.0'}
@@ -1773,10 +1750,6 @@ packages:
   undici-types@6.20.0:
   undici-types@6.20.0:
     resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
     resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
 
 
-  undici@5.28.5:
-    resolution: {integrity: sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==}
-    engines: {node: '>=14.0'}
-
   undici@7.2.3:
   undici@7.2.3:
     resolution: {integrity: sha512-2oSLHaDalSt2/O/wHA9M+/ZPAOcU2yrSP/cdBYJ+YxZskiPYDSqHbysLSlD7gq3JMqOoJI5O31RVU3BxX/MnAA==}
     resolution: {integrity: sha512-2oSLHaDalSt2/O/wHA9M+/ZPAOcU2yrSP/cdBYJ+YxZskiPYDSqHbysLSlD7gq3JMqOoJI5O31RVU3BxX/MnAA==}
     engines: {node: '>=20.18.1'}
     engines: {node: '>=20.18.1'}
@@ -1870,22 +1843,6 @@ packages:
 
 
 snapshots:
 snapshots:
 
 
-  '@actions/core@1.11.1':
-    dependencies:
-      '@actions/exec': 1.1.1
-      '@actions/http-client': 2.2.3
-
-  '@actions/exec@1.1.1':
-    dependencies:
-      '@actions/io': 1.1.3
-
-  '@actions/http-client@2.2.3':
-    dependencies:
-      tunnel: 0.0.6
-      undici: 5.28.5(patch_hash=eyidnukwfhrd7exzoydz2h5cfq)
-
-  '@actions/io@1.1.3': {}
-
   '@antfu/utils@0.7.10': {}
   '@antfu/utils@0.7.10': {}
 
 
   '@babel/code-frame@7.26.2':
   '@babel/code-frame@7.26.2':
@@ -1985,8 +1942,6 @@ snapshots:
       '@eslint/core': 0.10.0
       '@eslint/core': 0.10.0
       levn: 0.4.1
       levn: 0.4.1
 
 
-  '@fastify/busboy@2.1.1': {}
-
   '@ghostery/adblocker-content@2.3.1':
   '@ghostery/adblocker-content@2.3.1':
     dependencies:
     dependencies:
       '@ghostery/adblocker-extended-selectors': 2.3.1
       '@ghostery/adblocker-extended-selectors': 2.3.1
@@ -3581,8 +3536,6 @@ snapshots:
     dependencies:
     dependencies:
       safe-buffer: 5.2.1
       safe-buffer: 5.2.1
 
 
-  tunnel@0.0.6: {}
-
   type-check@0.4.0:
   type-check@0.4.0:
     dependencies:
     dependencies:
       prelude-ls: 1.2.1
       prelude-ls: 1.2.1
@@ -3606,10 +3559,6 @@ snapshots:
 
 
   undici-types@6.20.0: {}
   undici-types@6.20.0: {}
 
 
-  undici@5.28.5(patch_hash=eyidnukwfhrd7exzoydz2h5cfq):
-    dependencies:
-      '@fastify/busboy': 2.1.1
-
   undici@7.2.3(patch_hash=eyidnukwfhrd7exzoydz2h5cfq): {}
   undici@7.2.3(patch_hash=eyidnukwfhrd7exzoydz2h5cfq): {}
 
 
   unique-filename@4.0.0:
   unique-filename@4.0.0: