From 8e4c0e3040a184cdd09007bfe3cb15df9356adca Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Sat, 10 Aug 2024 11:57:50 +0200 Subject: [PATCH] web: separate build and deploy, incorporate landing page (#2264) --- .../{deploy-webui.yml => web-deploy.yml} | 53 ++++++++++++------ .gitmodules | 4 +- web/explorer/vite.config.js | 2 +- web/public/img/icon.ico | Bin 0 -> 15406 bytes web/public/img/icon.png | Bin 0 -> 6576 bytes web/public/index.html | 49 ++++++++++++++++ 6 files changed, 87 insertions(+), 21 deletions(-) rename .github/workflows/{deploy-webui.yml => web-deploy.yml} (63%) create mode 100644 web/public/img/icon.ico create mode 100644 web/public/img/icon.png create mode 100644 web/public/index.html diff --git a/.github/workflows/deploy-webui.yml b/.github/workflows/web-deploy.yml similarity index 63% rename from .github/workflows/deploy-webui.yml rename to .github/workflows/web-deploy.yml index c1d184d9b..d4522768d 100644 --- a/.github/workflows/deploy-webui.yml +++ b/.github/workflows/web-deploy.yml @@ -1,11 +1,10 @@ -name: deploy Capa Explorer Web to Github Pages +name: deploy web to GitHub Pages on: - # Runs on pushes targeting the webui branch push: - branches: [ master ] + branches: [ master, "wb/webui-actions-1" ] paths: - - 'web/explorer/**' + - 'web/**' # Allows to run this workflow manually from the Actions tab workflow_dispatch: @@ -22,10 +21,17 @@ concurrency: cancel-in-progress: true jobs: - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} + build-landing-page: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/upload-artifact@v4 + with: + name: landing-page + path: './web/public' + + build-explorer: runs-on: ubuntu-latest steps: - name: Checkout @@ -43,24 +49,35 @@ jobs: - name: Install dependencies run: npm ci working-directory: ./web/explorer - - name: Lint - run: npm run lint - working-directory: ./web/explorer - - name: Format - run: npm run format:check - working-directory: ./web/explorer - - name: Run unit tests - run: npm run test - working-directory: ./web/explorer - name: Build run: npm run build working-directory: ./web/explorer + - uses: actions/upload-artifact@v4 + with: + name: explorer + path: './web/explorer/dist' + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: [build-landing-page, build-explorer] + steps: + - uses: actions/download-artifact@v4 + with: + name: landing-page + path: './public/' + - uses: actions/download-artifact@v4 + with: + name: explorer + path: './public/explorer' - name: Setup Pages uses: actions/configure-pages@v4 - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: - path: './web/explorer/dist' + path: './public' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 diff --git a/.gitmodules b/.gitmodules index 079d13dc0..93c0a437d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "rules"] path = rules - url = ../capa-rules.git + url = ../../mandiant/capa-rules.git [submodule "tests/data"] path = tests/data - url = ../capa-testfiles.git + url = ../../mandiant/capa-testfiles.git diff --git a/web/explorer/vite.config.js b/web/explorer/vite.config.js index 7c5725e3a..c615b10fb 100644 --- a/web/explorer/vite.config.js +++ b/web/explorer/vite.config.js @@ -7,7 +7,7 @@ export default defineConfig(({ mode }) => { const isBundle = mode === "bundle"; return { - base: './', + base: "./", plugins: isBundle ? [vue(), viteSingleFile()] : [vue()], resolve: { alias: { diff --git a/web/public/img/icon.ico b/web/public/img/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9dcfdab8d631e1c3adc2030cbb7567d40951d0c1 GIT binary patch literal 15406 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 literal 0 HcmV?d00001 diff --git a/web/public/img/icon.png b/web/public/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..912d71b47b5080f6e574d161d5c621cd4196fa53 GIT binary patch literal 6576 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 i61GT^BMCN$=>GvIB+AFq=HK7|0000 + + + + + + capa + + + + + + +