Search code examples
gitlab-ci

The react project I am working on does not use a public folder but some prompts in the .gitlab-ci.yml file - need help understandig the pipeline


I was given a template to work with that I can modify but I lack the necessary understanding about the pipeline. If anyone has the time, I would appreciate (also partial) explanations how the pipeline constructs the public folder and how I could change the project so I can put other files in the public folder, too. I want to put a js file into the public folder in case that is relevant. The project is currently structured like this:

├── README.md                       -> The file you are currently reading
├── index.html                      -> Single HTML file for the wiki
├── package.json                    -> Manages project metadata and dependencies
├── src/
│   ├── components/                 -> Components (Like Navbar, Timelines, ...)
│   ├── App/                        -> Main React application container
|   |     └── App.tsx
│   ├── contents/                   -> Page components for the website
│   │   └── *.tsx                   
│   ├── main.tsx                    -> Entry point of the wiki application
│   ├── pages.ts                    -> Page definition and path mapping
│   ├── utils/                      -> Utility functions
│   └── vite-env.d.ts               -> TypeScript definitions for Vite
├── tsconfig.json                   -> Configures TypeScript options
├── tsconfig.node.json              -> TypeScript settings for Node.js
├── vite.config.ts                  -> Configuration for the Vite tool
└── yarn.lock                       -> Yarn lock file for dependency management

This is the .gitlab-ci.yml file:

image: node:18.20.0

build:
  stage: build
  cache:
    - key:
        files:
          - yarn.lock
      paths:
        - .yarn-cache/
  before_script:
    - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
    - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
    - yarn install --frozen-lockfile
  script:
    - yarn build
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH

pages:
  stage: build
  cache:
    - key:
        files:
          - yarn.lock
      paths:
        - .yarn-cache/
  before_script:
    - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
    - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
    - yarn install --frozen-lockfile
  script:
    - yarn build
    - cp -a dist/. public/
    - echo '/* /index.html 200' > public/_redirects
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

I read a few articles and basic instructions about pipelines, gitlab CI, vite and yarn. Unfortunately for me, this is not a very basic pipeline and it seems like it is always assumed that it is clear what expressions such as p -a in the yml file mean.

Using the classic "delete something and see what errors arise to figure out its purpose" approach, I figured out that - echo '/* /index.html 200' > public/_redirects makes all links to files in the public folder go to the index.html page (I think...).

And that cp -a dist/. public/ is necessary to find all the files to build the website with. Therefore, I tried putting the js file into the project structure as follows

├── README.md                       -> The file you are currently reading
├── mapscript.js
├── index.html                      -> Single HTML file for the wiki

Alas, that did not lead to it being found.

Edit / further info

I figured I just have to get the mapscript.js to be published somehow... so I created a folder whose contents are moved to the public directory on build. It is in the structure like this:

├── README.md                       -> The file you are currently reading 
├── pubpub  
├──   └── mapscript.js
├── index.html                      -> Single HTML file for the wiki
├── package.json 

And changed the pages/script part of the xml file like:

script:
    - yarn build
    - mv dist public

And added the folder in the vite.config.js:

export default () => {
  const env = loadEnv("dev", process.cwd());
  return defineConfig({
    base: `/${stringToSlug(env.VITE_TEAM_NAME)}/`,
    plugins: [react()],
    build: {
      outDir: "dist",
    },
    publicDir: 'pubpub',
  });
};

That worked more or less. More, because mapscript.js has now a valid url I can use. Less, because the pages of the website were sent to 404 not found on reload or if I just entered the url. In other word, they were only reachable when coming from the homepage and using the navigation bar. To change that I added a line of the original yml back:

script:
    - yarn build
    - mv dist public
    - echo '/* /index.html 200' > public/_redirects

And now they are reachable again. One thing is still not working. Trying to reach the home page with this link works still: https://2024.igem.wiki/bielefeld-cebitec/ but not the original link https://2024.igem.wiki/bielefeld-cebitec/index.html .

Still have to figure out how I messed that up and how to reverse it. And I still do not really understand the pipeline and how everything is published. I just tried a lot of things that seemed to make sense until one worked and gave mapscript.js a reachable url.


Solution

  • I solved it this way:

    Build script:

    script:
        - yarn build
        - mv dist public
    

    pages script:

    script:
        - yarn build
        - mv dist public 
        - echo '/* /index.html 200' > public/_redirects 
    

    vite.confog.js:

    export default () => {
      const env = loadEnv("dev", process.cwd());
      if (!env.VITE_TEAM_NAME) {
        throw new Error("VITE_TEAM_NAME environment variable is not defined");
      }
    
      const baseSlug = stringToSlug(env.VITE_TEAM_NAME);
      console.log(`Base URL: /${baseSlug}/`);
      console.log(`Output directory: ${path.resolve(__dirname, 'dist')}`);
    
      
    
      return defineConfig({
        base: `/`,
        plugins: [react()],
        resolve: {
          alias: {
            '@': path.resolve(__dirname, './src'), // Simplifies imports
          }
        },
        css: {
          preprocessorOptions: {
            css: {
              //javascriptEnabled: true, // Enable JavaScript in CSS (useful for certain CSS preprocessor plugins)
            }
          }    },
        build: {
          outDir: "dist",
          rollupOptions: {
            output: {
              assetFileNames: `assets/[ext]/[name]-[hash].[ext]`
              }      
            }
          },
        publicDir: 'pubpub',
      });
    };
    

    Now it is working. Well it was until I changed something else today haha. But that has nothing to do with this error, that was completely resolved.