Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prebuild files and Github action script to auto build core and vite apps #352

Merged
merged 12 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/prebuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Prebuild core & vite apps

on:
pull_request:
types:
- opened
issue_comment:
types:
- created
workflow_dispatch:

jobs:
build:
if: github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request' || contains(github.event.comment.body, '/build')
runs-on: ubuntu-latest
steps:
- name: Show GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"

- uses: actions/github-script@v6
if: github.event_name == 'pull_request' || contains(github.event.comment.body, '/build')
id: get-head-sha
with:
script: |
const request = {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
}
core.info(`Getting PR #${request.pull_number} from ${request.owner}/${request.repo}`)
try {
const result = await github.rest.pulls.get(request)
core.setOutput('head_ref', result.data.head.ref)
} catch (err) {
core.setFailed(`Request failed with error ${err}`)
}

- name: Checkout repository
uses: actions/checkout@v3

- name: Build Docker image
run: docker build . -t prebuild -f ./docker/DOCKERFILES/build/prebuild.Dockerfile

- name: Run Docker container
run: docker run --name prebuild prebuild

- name: Copy apps/core/dist
run: docker cp prebuild:/app/apps/core/dist ./apps/core

- name: Copy apps/core/applications
run: docker cp prebuild:/app/apps/core/applications ./apps/core

- name: Store branch variable, if event name == workflow_dispatch or steps.get-head.outputs.result.head.ref is defined
id: get-branch
run: |
if [ "${{ github.event_name }}" == 'workflow_dispatch' ]; then
echo ::set-output name=branch::${{ github.ref_name }}
else
branch_ref=${{ steps.get-head.outputs.head_ref }}
if [ "$branch_ref" != "null" ]; then
echo ::set-output name=branch::${branch_ref}
else
echo ::set-output name=branch::master
fi
fi

- name: Create an artifact for core/dist and core/applications
uses: actions/upload-artifact@v3
with:
name: dist-artifact-${{ steps.get-branch.outputs.branch }}
path: |
apps/core/dist
apps/core/applications
retention-days: 30
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

dist-artifact-**.zip

# Misc
.DS_Store
logs
Expand Down
15 changes: 15 additions & 0 deletions .husky/post-checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

# Edit file .env, change value GIT_ARTIFACT_BRANCH with the current branch name
# Example: GIT_ARTIFACT_BRANCH=develop

# Get current branch name
CURRENT_BRANCH=$(git branch --show-current)

# Create .env file is not exists
if [ ! -f ./apps/core/.env ]; then
cp ./apps/core/.env.example ./apps/core/.env
fi

# Edit file .env and replace GIT_ARTIFACT_BRANCH with the current branch name.
awk -v var="$CURRENT_BRANCH" '{ gsub(/GIT_ARTIFACT_BRANCH=.*/, "GIT_ARTIFACT_BRANCH="var) }1' ./apps/core/.env > ./apps/core/.env.tmp && mv ./apps/core/.env.tmp ./apps/core/.env
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,30 @@ A few environment variables are available in the script:
- `LEAV_APPLICATION_ID`: Application ID
- `LEAV_DEST_FOLDER`: instance folder

## Run in light mode

The light mode is made for git user that want to quickly checkout on a dev branch and run the project in approximately 1 minute.

This light mode will download an artifact automatically generated by GitHub action and run it in a docker container.

The light.yml file will avoid to start admin, login, data-studio and portal services.

**Note: The first installation can take up to 5 minutes in order to download and install dependencies.**
### Prerequisites

- Create a .env file in /apps/core with the following content:
- Follow this guide to get your GITHUB_TOKEN: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
```
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

### Execution

- Run the following command in docker folder:
```
docker-compose -f docker-compose.yml -f light.yml up -d
```
- Then you can access the core at http://core.leav.localhost

# License
LEAV-Engine is released under the [LGPL v3](https://www.gnu.org/licenses/lgpl-3.0.txt) license.
3 changes: 3 additions & 0 deletions apps/core/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GITHUB_REPOSITORY=https://api.github.com/repos/leav-solutions/leav-engine
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GIT_ARTIFACT_BRANCH=master
40 changes: 40 additions & 0 deletions apps/core/scripts/preload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const fs = require('fs');

const {getArtifactList, downloadArtifact, initEnvVariables} = require("./utils");

initEnvVariables();

let artifact;

const gitArtifactBranch = process.env.GIT_ARTIFACT_BRANCH;

// if no branch provided, exit
if (!gitArtifactBranch) {
console.error('GIT_ARTIFACT_BRANCH variable is not defined (see apps/core/.env file). Exiting...');
process.exit(0);
}

(async () => {
try {
const { data: list} = await getArtifactList();
// Find the artifact with the same commit sha1
artifact = list.artifacts.find((artifact) => {
// if artifact.name includes commit Sha1
return artifact.name.includes(gitArtifactBranch);
});

if (!artifact) throw new Error(`No artifact found for branch: ${gitArtifactBranch}`);

const fileName = `${artifact.name}.zip`;

// before download remove file if exists
if (fs.existsSync(fileName)) {
fs.unlinkSync(fileName);
}
await downloadArtifact(fileName, artifact.archive_download_url);
console.log(`Artifact ${fileName} downloaded successfully`);
} catch (err) {
console.log('error', err);
process.exit(0);
}
})()
53 changes: 53 additions & 0 deletions apps/core/scripts/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const axios = require('axios');
const fs = require("fs");
const path = require("path");

// get artifacts list
const getArtifactList = () => {
const artifactListUrl = `${process.env.GITHUB_REPOSITORY}/actions/artifacts`;
const options = {
headers: {
"Content-Type": "application/json",
"Authorization": `bearer ${process.env.GITHUB_TOKEN}`,
"User-Agent": "leav-engine",
}
}
return axios.get(artifactListUrl, options);
}

const downloadArtifact = async (fileName, url) => {
const file = fs.createWriteStream(fileName);

// download file with axios
const res= await axios.get(url, {
responseType: 'stream',
headers: {
"Authorization": `bearer ${process.env.GITHUB_TOKEN}`,
"User-Agent": "leav-engine",
"Content-type": "application/zip",
}
})
// pipe the result stream into a file on disc
res.data.pipe(file)
return new Promise((resolve, reject) => {
file.on('finish',() => resolve(fileName))
file.on('error',(err) => reject(err))
});
}

const initEnvVariables = () => {
const envPath = path.resolve(__dirname, "../.env");
const envFile = fs.readFileSync(envPath, "utf8");

process.env = envFile.split("\n").reduce((acc, curr) => {
if (!curr) return acc;
const [key, value] = curr.split("=");
acc[key] = value;
return acc;
}, {});
}
module.exports = {
getArtifactList,
downloadArtifact,
initEnvVariables
}
17 changes: 17 additions & 0 deletions docker/DOCKERFILES/build/prebuild.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:18-alpine

RUN echo "------------------------ START PREBUILD ---------------------------"

# Dependencies needed to retrieve metadata
RUN apk --update add alpine-sdk perl pkgconfig poppler poppler-dev poppler-utils

WORKDIR /app

COPY . /app

RUN yarn workspaces focus core && yarn workspace core build

# Install apps
CMD ["sh", "/app/scripts/apps_install.sh"]

RUN echo "------------------------ END PREBUILD ---------------------------"
53 changes: 53 additions & 0 deletions docker/light.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
version: "3.4"

services:
core:
command: [
sh,
-c,
"/scripts/wait-for-it.sh message-broker:5672 -t 1000 -- /scripts/wait-for-it.sh arangodb:8529 -t 1000 -- /scripts/start-light-core.sh",
]

# Start these services in prod mode
indexation-manager:
command: [
sh,
-c,
"/scripts/wait-for-it.sh core:4001 -t 1000 -- yarn run start --indexationManager"
]
tasks-manager-master:
command: [
sh,
-c,
"/scripts/wait-for-it.sh core:4001 -t 1000 -- yarn run start --tasksManager=master"
]
tasks-manager-worker:
command: [
sh,
-c,
"/scripts/wait-for-it.sh core:4001 -t 1000 -- yarn run start --tasksManager=worker",
]
files-manager:
command: [
sh,
-c,
"/scripts/wait-for-it.sh core:4001 -t 1000 -- yarn run start --filesManager",
]

# Override apps service, to not start them
login:
labels:
- "traefik.enable=false"
command: []
admin:
labels:
- "traefik.enable=false"
command: []
portal:
labels:
- "traefik.enable=false"
command: []
data-studio:
labels:
- "traefik.enable=false"
command: []
22 changes: 22 additions & 0 deletions docker/scripts/start-light-core.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh

echo "Install dependencies"
# If no dependencies have been update, you can comment this line
# to use up to 30sec in load time
yarn install

# Migrate database if needed
yarn run db:migrate

echo "Download artifact and extract it (contains dist folders)"
node ./scripts/preload.js

echo "Unzip dist-artifact-**.zip"
unzip -o dist-artifact-**.zip -q
rm -rf dist-artifact-**.zip

echo "mkdir plugin if does not exist"
mkdir -p /app/apps/core/dist/plugins

echo "start server"
yarn run start --server
Loading