diff --git a/.github/workflows/README.md b/.github/workflows/README.md
index dd3c8cb..6c2f9ce 100644
--- a/.github/workflows/README.md
+++ b/.github/workflows/README.md
@@ -1,22 +1,20 @@
# GitHub Workflow for LifeSG libs
-This guide will breifly explain what how the GitHub workflow works for LifeSG and the necessary setups to get it working on another LifeSG GitHub repository.
+This guide will briefly explain how the GitHub workflow works for LifeSG and the necessary setups to get it working on another LifeSG GitHub repository.
-## trigger-gitlab-pipeline.yml
+## trigger-gitlab-pipeline.yml
-This file is responsible for creating the GitHub workflow and the job that triggers the GitLab pipeline.
+This file is responsible for the job that triggers the GitLab pipeline.
---
+## pr-checks.yml
-## Trigger Pipeline Job
+This file is responsible for running test and build checks on pull requests.
-When a GitHub `push on master branch` or `pull request` is made it will trigger the job.
+---
-Pull Request events that will trigger the pipeline are:
+## Trigger Pipeline Job
-- `opened`: when opening of a PR
-- `synchronize`: when a new commit is added to the PR
-- `reopened`: when reopening of a PR
+When a GitHub `push on master branch` is made it will trigger the job.
We have set variables in the settings of the GitHub repository that is needed to be passed into the trigger pipeline API.
@@ -42,3 +40,15 @@ The API contains variables that are important to be passed in the body of the re
Then the Project in GitLab responsible for running the pipeline will create and start the pipeline.
The GitHub action is marked as successful when the GitLab pipeline's `build-dist-job` is successful. After that you are able to deploy to storybook/github/npm.
+
+## PR Checks
+
+When a GitHub `pull request` is made it will trigger the job.
+
+Pull Request events that will trigger the pipeline are:
+
+- `opened`: when opening of a PR
+- `synchronize`: when a new commit is added to the PR
+- `reopened`: when reopening of a PR
+
+The GitHub action is marked as successful when all checks pass.
diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml
new file mode 100644
index 0000000..2d3032c
--- /dev/null
+++ b/.github/workflows/pr-checks.yml
@@ -0,0 +1,67 @@
+name: PR Checks
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ prepare-deps:
+ timeout-minutes: 5
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - uses: actions/setup-node@v7
+ with:
+ node-version: 22
+ - name: Install dependencies
+ run: npm ci
+ - name: Pack dependencies
+ run: tar -czf node-modules.tgz node_modules
+ - name: Upload dependencies artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: node-modules-tar
+ path: node-modules.tgz
+ retention-days: 1
+
+ build-lib:
+ needs: prepare-deps
+ timeout-minutes: 5
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - uses: actions/setup-node@v7
+ with:
+ node-version: 22
+ - name: Download dependencies artifact
+ uses: actions/download-artifact@v8
+ with:
+ name: node-modules-tar
+ path: .
+ - name: Restore dependencies
+ run: tar -xzf node-modules.tgz
+ - name: Build library
+ run: npm run build-lib
+
+ build-storybook:
+ needs: prepare-deps
+ timeout-minutes: 5
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - uses: actions/setup-node@v7
+ with:
+ node-version: 22
+ - name: Download dependencies artifact
+ uses: actions/download-artifact@v8
+ with:
+ name: node-modules-tar
+ path: .
+ - name: Restore dependencies
+ run: tar -xzf node-modules.tgz
+ - name: Build Storybook
+ run: npm run build-storybook
diff --git a/.github/workflows/trigger-gitlab-pipeline.yml b/.github/workflows/trigger-gitlab-pipeline.yml
index 569f55a..691a11b 100644
--- a/.github/workflows/trigger-gitlab-pipeline.yml
+++ b/.github/workflows/trigger-gitlab-pipeline.yml
@@ -6,8 +6,6 @@ on:
- main
- "release/**"
- "!release/**-published"
- pull_request:
- types: [opened, synchronize, reopened]
jobs:
trigger_pipeline:
@@ -15,10 +13,13 @@ jobs:
steps:
- name: Print Configs
+ env:
+ REF_NAME: ${{ github.ref_name }}
+ HEAD_COMMIT_MSG: ${{ github.event.head_commit.message }}
run: |
- [[ $GITHUB_EVENT_NAME = "pull_request" ]] && BRANCH_NAME="${{ github.head_ref }}" || BRANCH_NAME="${{ github.ref_name }}"
+ BRANCH_NAME="$REF_NAME"
- [[ $GITHUB_EVENT_NAME = "pull_request" ]] && COMMIT_MSG="${{ github.event.pull_request.title }}" || COMMIT_MSG=$(echo -e "${{ github.event.head_commit.message }}" | head -n 1)
+ COMMIT_MSG=$(printf '%s\n' "$HEAD_COMMIT_MSG" | awk 'NR>1{exit};1')
PIPELINE_PROJECT_URL="github.com/$GITHUB_REPOSITORY.git"
diff --git a/package.json b/package.json
index 8180fd7..97b289b 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"typings": "dist/index.d.ts",
"scripts": {
"build": "npm run generate-icons && npm run rollup && npm run post:build",
+ "build-lib": "./scripts/build.sh",
"build-check": "npm run rollup",
"rollup": "rm -rf dist && rollup -c",
"post:build": "node ./scripts/post-build.js",
diff --git a/scripts/generate-icons.js b/scripts/generate-icons.js
index 3b67153..81a4ee1 100644
--- a/scripts/generate-icons.js
+++ b/scripts/generate-icons.js
@@ -51,7 +51,7 @@ async function transformToJSX(file) {
// =============================================================================
// RUNNABLE
// =============================================================================
-async function deleteFiles() {
+async function deleteComponentFiles() {
const files = await readdir(destinationPath);
for (const file of files) {
@@ -62,8 +62,29 @@ async function deleteFiles() {
console.log(`Deleted ${files.length} files`);
}
+async function getSvgFiles() {
+ const files = await readdir(assetPath);
+ const componentFiles = files.filter((file) => file !== "index.ts");
+
+ // Validate file names are in the correct format
+ for (const file of componentFiles) {
+ const fileNameParts = file.split(".");
+ if (
+ fileNameParts.length !== 2 ||
+ !/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(fileNameParts[0]) ||
+ fileNameParts[1] !== "svg"
+ ) {
+ throw new Error(
+ `Invalid file name: ${file}. SVG files should be in kebab case`
+ );
+ }
+ }
+
+ return componentFiles;
+}
+
async function writeComponentFiles() {
- const svgFiles = await readdir(assetPath);
+ const svgFiles = await getSvgFiles();
for (const file of svgFiles) {
const jsxCode = await transformToJSX(file);
@@ -100,7 +121,7 @@ async function generateIndexFile() {
async function run() {
try {
- await deleteFiles();
+ await deleteComponentFiles();
await writeComponentFiles();
await generateIndexFile();
} catch (err) {