att / qujata

[inactive] Next-Gen Crypto. Quantified.
MIT License
13 stars 3 forks source link

Static web page displaying reports #63

Open litalmason opened 9 months ago

litalmason commented 9 months ago

Description

Implement and deploy a react-based portal with JSON visualizations of selected test suites to GitHub pages. Static page showing static results exported from our findings.

Figma Report Selector, No navigation image

Acceptance Criteria

  1. React app spin up switch: The "View experiments page" should have 2 modes. The first one is for local run / environment run (already implemented), where you have a backend to run your experiments. The second mode is for the benchmarking reports, displaying our experiment runs from a folder in our main git branch. You need to implement the switch of how you spin up the React application (There is a PR on it). There is an environment variable that you should rely on, which will tell you in which mode you should spin up the app. In the static mode, you should spin up the app with a different main page: View experiments page with its static mode.

  2. View experiments page enhancement - Static mode: page report state must have include the following:

    • Report selector: Select a report by date according to the JSON files that are available.
    • Navigation: There should be no navigation buttons in the toolbar.

Design

Our static portal will be deployed from our main code build, but with a build version dedicated to "Pages". This dedicated build will have a few tweaks:

  1. Different main page: The "Reports Page" will become the main page. It is very similar to a single experiment's page.
  2. Different data source: The idea is to have a folder in the main branch with our latest experiments and use it as a data source.

CI/CD

graph TD
    Dev("Developer") -->|Push changes| GH("GitHub Repo")
    GH -->|Trigger workflow| GA("GitHub Actions")

        GA --> BE("Environment Configuration")

    subgraph DockerBuild["Docker Build"]
        BE -->|BUILD_ENV=gh-pages| GHP("GitHub Pages Build Settings")
        BE -->|BUILD_ENV!=gh-pages| STD("Standard Build Settings")
    end

    DockerBuild --> IMG("Docker Image")

    IMG -->|Extract static content| SC("Static Content")
    SC -->|Deploy to GitHub Pages| Pages("GitHub Pages")

    classDef default fill:#ddf,stroke:#33a,stroke-width:2px, border-radius:10px;
    classDef build fill:#bbf,stroke:#33a,stroke-width:2px, border-radius:10px;
    classDef settings fill:#ccf,stroke:#33a,stroke-width:2px, border-radius:10px;
    class DockerBuild,IMG,SC,Pages build
    class BE,GHP,STD settings

Implementation steps

React Application Setup

  1. Environment Variables: Define necessary environment variables in .env files for different environments:

    • .env (local development):

      REACT_APP_MAIN_PAGE=MainPageLocal.js
    • .env.gh-pages (GitHub Pages):

      REACT_APP_MAIN_PAGE=MainPageGitHubPages.js
  2. Fetching from our GitHub repo reports folder

Fetch All File Names in a GitHub Repo Folder

const fetchFileNames = async () => {
  const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${branch}`;
  try {
    const response = await fetch(apiUrl);
    const data = await response.json();
    const fileNames = data.filter(item => item.type === 'file').map(file => file.name);
    console.log('File names:', fileNames);
  } catch (error) {
    console.error('Error fetching file names:', error);
  }
};

Fetch a Single File by Name from a GitHub Repo

const fetchFileContent = async () => {
  const fileUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${path}/${fileName}`;
  try {
    const response = await fetch(fileUrl);
    const content = await response.text();  // Use .json() if you're fetching a JSON file
    setFileContent(content);
  } catch (error) {
    console.error('Error fetching file content:', error);
  }
};

For both snippets, you need to replace owner, repo, path, and fileName with actual values. The branch parameter defaults to 'main'.

  1. Dynamic Main Page Import: Use dynamic imports based on the environment variable to load the main page component:

    import React, { lazy, Suspense } from 'react';
    
    const MainPage = lazy(() => import(`./pages/${process.env.REACT_APP_MAIN_PAGE}`));
    
    function App() {
      return (
        <Suspense fallback={<div>Loading...</div>}>
          <MainPage />
        </Suspense>
      );
    }
    
    export default App;

Dockerfile Adjustments

Ensure the Dockerfile copies the correct environment file based on the build context:

# Example Dockerfile snippet

COPY . .
RUN if [ "$BUILD_ENV" = "gh-pages" ]; then \
        cp .env.gh-pages .env; \
    fi

# Continue with Docker build steps...

GitHub Actions Workflow

Update the workflow to build the Docker image with the BUILD_ENV argument and include steps for deploying to GitHub Pages:

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Build Docker image for GitHub Pages
      run: docker build ./portal --file ./portal/Dockerfile --tag my-website-image --build-arg BUILD_ENV=gh-pages

    # Steps for copying static content from the Docker image and deploying to GitHub Pages

This solution integrates the dynamic main page switch with the data fetching setup. The main page component is dynamically imported based on an environment variable, which allows for different main pages in different environments (e.g., local development vs. GitHub Pages). The data fetching function adapts to the data source (API or GitHub JSON files) and processes the response accordingly.

Issues

mikekcs commented 8 months ago

I will suggest running that specific flow on the "main' branch only adding

on:
  push:
    branches:
      - 'main'

2 more questions: