-
-
- RKIX3 AI - Lập trình, Code, Build, Tự động hoá
-
-
-
-
-
+
+
+ RKIX3 — Developer Workspace Platform
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- OpenAI GPT-5.5 Ready
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Model chủ lực
GPT-5.5 / Gemini 2.5
-
Workflow
Auth · Init · AI · DB · Deploy
-
Mobile CLI
Termux-ready
-
Preview
HTML live sandbox
-
-
Chúng ta nên bắt đầu từ đâu?
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Không đặt API key thật trong code public. Dùng key tạm ở modal hoặc backend proxy khi triển khai production.
-
-
-
-
-
-
RKIX3 CORE ENGINE
-
-
-
-
-
-
-
-
-
-
-
- RKIX3 đang lập trình cấu trúc...
-
-
-
-
-
-
-
-
-
-
-
-
-
Lập trình
Viết code, debug và tối ưu hệ thống
-
Build
Tạo UI/web app phẳng vuông góc
-
Tự động hoá
Auth CLI, GitHub, CI, deploy
-
AI thông minh
GPT-5.5, Gemini, context file
-
CLI OAuth
Local loopback Termux flow
-
Database
Supabase/Neon schema + env
-
-
-
-
-
-
-
-
-
-
-
Cổng API RKIX3
-
-
-
-
Chọn provider AI. OpenAI dùng Responses API với GPT-5.5 cho coding/pro workflow; Gemini giữ làm lựa chọn phụ. Nếu không có key, RKIX3 chạy Demo Mode để sinh blueprint offline.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
RKIX3 Command Center
-
-
-
-
-
-
-
Hệ thống thông báo!
-
-
+
+
+
+
RKIX3 Command Layer
Dashboard
main · healthy
+
+
+
From 157295353243aa9b4b0af4bd0c921e1b43214eb8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:03:09 +0700
Subject: [PATCH 02/63] Update FUNDING.yml
---
.github/FUNDING.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 42bf91f..d581e97 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,4 +1,4 @@
-# These are supported funding model platforms
+ # These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
From d8de250737fa40cf377a5e7c4b258041c624d8ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:09:09 +0700
Subject: [PATCH 03/63] Create CNAME
---
CNAME | 1 +
1 file changed, 1 insertion(+)
create mode 100644 CNAME
diff --git a/CNAME b/CNAME
new file mode 100644
index 0000000..9867ca9
--- /dev/null
+++ b/CNAME
@@ -0,0 +1 @@
+app.rkix3.github
\ No newline at end of file
From 02046ab54e5fec22579af288b470b6cef9995a93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:10:40 +0700
Subject: [PATCH 04/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index 9867ca9..5eb9dd7 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-app.rkix3.github
\ No newline at end of file
+rkix.com
\ No newline at end of file
From b6c7adf0111677636b9b7f109b5c3820ecf19664 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:12:54 +0700
Subject: [PATCH 05/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index 5eb9dd7..6656493 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-rkix.com
\ No newline at end of file
+agents.rkix3.githun.io
\ No newline at end of file
From 3d956773e67e135197305327244f9a6670bf7070 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:17:28 +0700
Subject: [PATCH 06/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index 6656493..ff15f5c 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-agents.rkix3.githun.io
\ No newline at end of file
+rkix.page
From 737fcca845befaee77ff3eb3c4882ebc905de3eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:18:52 +0700
Subject: [PATCH 07/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index ff15f5c..dcd6846 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-rkix.page
+www.rkix.page
From a8676e1b0053cac83f70a3f254900afa6e864257 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 16:20:58 +0700
Subject: [PATCH 08/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index dcd6846..6656493 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-www.rkix.page
+agents.rkix3.githun.io
\ No newline at end of file
From e006fb93d6ef47411d6c30cb6c66c9c83be55df7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 18:13:00 +0700
Subject: [PATCH 09/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index 6656493..4997ef0 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-agents.rkix3.githun.io
\ No newline at end of file
+rkix.ai
\ No newline at end of file
From 6c0b7b6c3a9bde5bd45d16e2c8bef1f35ba3e3c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 18:14:50 +0700
Subject: [PATCH 10/63] Update CNAME
---
CNAME | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CNAME b/CNAME
index 4997ef0..2037010 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-rkix.ai
\ No newline at end of file
+app.github.rkix
\ No newline at end of file
From 6d4701f47df2dc2cf8819c8c68b740a0ed19a844 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 18:59:08 +0700
Subject: [PATCH 11/63] Create dependabot.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/dependabot.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 .github/dependabot.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..5990d9c
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
+
+version: 2
+updates:
+ - package-ecosystem: "" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "weekly"
From e9dc21204e5cd10ae22b8506ea9ac88faa5a64c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:01:17 +0700
Subject: [PATCH 12/63] Create codeql.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/codeql.yml | 99 ++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
create mode 100644 .github/workflows/codeql.yml
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..69d42ce
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,99 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL Advanced"
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+ schedule:
+ - cron: '37 11 * * 0'
+
+jobs:
+ analyze:
+ name: Analyze (${{ matrix.language }})
+ # Runner size impacts CodeQL analysis time. To learn more, please see:
+ # - https://gh.io/recommended-hardware-resources-for-running-codeql
+ # - https://gh.io/supported-runners-and-hardware-resources
+ # - https://gh.io/using-larger-runners (GitHub.com only)
+ # Consider using larger runners or machines with greater resources for possible analysis time improvements.
+ runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
+ permissions:
+ # required for all workflows
+ security-events: write
+
+ # required to fetch internal or private CodeQL packs
+ packages: read
+
+ # only required for workflows in private repositories
+ actions: read
+ contents: read
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - language: actions
+ build-mode: none
+ # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
+ # Use `c-cpp` to analyze code written in C, C++ or both
+ # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
+ # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
+ # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
+ # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
+ # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
+ # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ # Add any setup steps before running the `github/codeql-action/init` action.
+ # This includes steps like installing compilers or runtimes (`actions/setup-node`
+ # or others). This is typically only required for manual builds.
+ # - name: Setup runtime (example)
+ # uses: actions/setup-example@v1
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: ${{ matrix.language }}
+ build-mode: ${{ matrix.build-mode }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+
+ # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+ # queries: security-extended,security-and-quality
+
+ # If the analyze step fails for one of the languages you are analyzing with
+ # "We were unable to automatically build your code", modify the matrix above
+ # to set the build mode to "manual" for that language. Then modify this step
+ # to build your code.
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+ - name: Run manual build steps
+ if: matrix.build-mode == 'manual'
+ shell: bash
+ run: |
+ echo 'If you are using a "manual" build mode for one or more of the' \
+ 'languages you are analyzing, replace this with the commands to build' \
+ 'your code, for example:'
+ echo ' make bootstrap'
+ echo ' make release'
+ exit 1
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
+ with:
+ category: "/language:${{matrix.language}}"
From 5e854c6ecd5253d8806aaf48f1095c78b0c92a24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:01:59 +0700
Subject: [PATCH 13/63] Create jscrambler-code-integrity.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.../workflows/jscrambler-code-integrity.yml | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 .github/workflows/jscrambler-code-integrity.yml
diff --git a/.github/workflows/jscrambler-code-integrity.yml b/.github/workflows/jscrambler-code-integrity.yml
new file mode 100644
index 0000000..893d5bf
--- /dev/null
+++ b/.github/workflows/jscrambler-code-integrity.yml
@@ -0,0 +1,47 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This is a basic workflow to help you get started with Using Jscrambler Code Integrity Action.
+# It automates the protection of your JavaScript Applications, so you can run it whenever a new version of your application is built.
+# A Jscrambler account is required to use this Workflow.
+#
+# More info can be found here : https://docs.jscrambler.com/latest/code-integrity/documentation/github-ci-integration
+
+name: Jscrambler Code Integrity
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ "main" ]
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ - run: npm ci
+ - run: npm run build
+ - name: Jscrambler Code Integrity
+ id: jscrambler
+ # the complete list of inputs can be found here: https://github.com/marketplace/actions/jscrambler#inputs
+ uses: jscrambler/code-integrity-actions/protect@ab65962a2ecffcc362b75a997e24a181d0bde5fb
+ with:
+ application-id: ${{ secrets.JSCRAMBLER_APPLICATION_ID }} # This value should be created within your Jscrambler account
+ secret-key: ${{ secrets.JSCRAMBLER_SECRET_KEY }} # This value can be found in your Jscrambler account
+ access-key: ${{ secrets.JSCRAMBLER_ACCESS_KEY }} # This value can be found in your Jscrambler account
+ jscrambler-config-path: jscrambler.json # Download from your Jscrambler account
+ files-src: | # List of Files to be protected
+ dist/**/*
+ files-dest: .
From c63e250bbbf88d9988bce0cda44c19d81fbfbb8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:02:33 +0700
Subject: [PATCH 14/63] Create anchore-syft.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/anchore-syft.yml | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 .github/workflows/anchore-syft.yml
diff --git a/.github/workflows/anchore-syft.yml b/.github/workflows/anchore-syft.yml
new file mode 100644
index 0000000..85249e2
--- /dev/null
+++ b/.github/workflows/anchore-syft.yml
@@ -0,0 +1,38 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This workflow checks out code, builds an image, performs a container image
+# scan with Anchore's Syft tool, and uploads the results to the GitHub Dependency
+# submission API.
+
+# For more information on the Anchore sbom-action usage
+# and parameters, see https://github.com/anchore/sbom-action. For more
+# information about the Anchore SBOM tool, Syft, see
+# https://github.com/anchore/syft
+name: Anchore Syft SBOM scan
+
+on:
+ push:
+ branches: [ "main" ]
+
+permissions:
+ contents: write
+
+jobs:
+ Anchore-Build-Scan:
+ permissions:
+ contents: write # required to upload to the Dependency submission API
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout the code
+ uses: actions/checkout@v4
+ - name: Build the Docker image
+ run: docker build . --file Dockerfile --tag localbuild/testimage:latest
+ - name: Scan the image and upload dependency results
+ uses: anchore/sbom-action@bb716408e75840bbb01e839347cd213767269d4a
+ with:
+ image: "localbuild/testimage:latest"
+ artifact-name: image.spdx.json
+ dependency-snapshot: true
From 3cfafcb575fb64f7cd77ae53315bdc426be5dcad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:03:17 +0700
Subject: [PATCH 15/63] Create apisec-scan.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/apisec-scan.yml | 71 +++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 .github/workflows/apisec-scan.yml
diff --git a/.github/workflows/apisec-scan.yml b/.github/workflows/apisec-scan.yml
new file mode 100644
index 0000000..eead8c1
--- /dev/null
+++ b/.github/workflows/apisec-scan.yml
@@ -0,0 +1,71 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# APIsec addresses the critical need to secure APIs before they reach production.
+# APIsec provides the industry’s only automated and continuous API testing platform that uncovers security vulnerabilities and logic flaws in APIs.
+# Clients rely on APIsec to evaluate every update and release, ensuring that no APIs go to production with vulnerabilities.
+
+# How to Get Started with APIsec.ai
+# 1. Schedule a demo at https://www.apisec.ai/request-a-demo .
+#
+# 2. Register your account at https://cloud.apisec.ai/#/signup .
+#
+# 3. Register your API . See the video (https://www.youtube.com/watch?v=MK3Xo9Dbvac) to get up and running with APIsec quickly.
+#
+# 4. Get GitHub Actions scan attributes from APIsec Project -> Configurations -> Integrations -> CI-CD -> GitHub Actions
+#
+# apisec-run-scan
+#
+# This action triggers the on-demand scans for projects registered in APIsec.
+# If your GitHub account allows code scanning alerts, you can then upload the sarif file generated by this action to show the scan findings.
+# Else you can view the scan results from the project home page in APIsec Platform.
+# The link to view the scan results is also displayed on the console on successful completion of action.
+
+# This is a starter workflow to help you get started with APIsec-Scan Actions
+
+name: APIsec
+
+# Controls when the workflow will run
+on:
+ # Triggers the workflow on push or pull request events but only for the "main" branch
+ # Customize trigger events based on your DevSecOps processes.
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+ schedule:
+ - cron: '38 19 * * 6'
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+
+permissions:
+ contents: read
+
+jobs:
+
+ Trigger_APIsec_scan:
+ permissions:
+ security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: APIsec scan
+ uses: apisec-inc/apisec-run-scan@025432089674a28ba8fb55f8ab06c10215e772ea
+ with:
+ # The APIsec username with which the scans will be executed
+ apisec-username: ${{ secrets.apisec_username }}
+ # The Password of the APIsec user with which the scans will be executed
+ apisec-password: ${{ secrets.apisec_password}}
+ # The name of the project for security scan
+ apisec-project: "VAmPI"
+ # The name of the sarif format result file The file is written only if this property is provided.
+ sarif-result-file: "apisec-results.sarif"
+ - name: Import results
+ uses: github/codeql-action/upload-sarif@v3
+ with:
+ sarif_file: ./apisec-results.sarif
From 587faa08e3415214d6eec6f8aa55bde3b0aef241 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:07:09 +0700
Subject: [PATCH 16/63] Create hadolint.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/hadolint.yml | 47 ++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 .github/workflows/hadolint.yml
diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml
new file mode 100644
index 0000000..dc73566
--- /dev/null
+++ b/.github/workflows/hadolint.yml
@@ -0,0 +1,47 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+# hadoint is a Dockerfile linter written in Haskell
+# that helps you build best practice Docker images.
+# More details at https://github.com/hadolint/hadolint
+
+name: Hadolint
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ "main" ]
+ schedule:
+ - cron: '41 11 * * 6'
+
+permissions:
+ contents: read
+
+jobs:
+ hadolint:
+ name: Run hadolint scanning
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Run hadolint
+ uses: hadolint/hadolint-action@f988afea3da57ee48710a9795b6bb677cc901183
+ with:
+ dockerfile: ./Dockerfile
+ format: sarif
+ output-file: hadolint-results.sarif
+ no-fail: true
+
+ - name: Upload analysis results to GitHub
+ uses: github/codeql-action/upload-sarif@v3
+ with:
+ sarif_file: hadolint-results.sarif
+ wait-for-processing: true
From ea6351cf65a4f50c6372d6cd26e8c2efa58a7c33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:09:07 +0700
Subject: [PATCH 17/63] Create policy-validator-tf.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/policy-validator-tf.yml | 101 ++++++++++++++++++++++
1 file changed, 101 insertions(+)
create mode 100644 .github/workflows/policy-validator-tf.yml
diff --git a/.github/workflows/policy-validator-tf.yml b/.github/workflows/policy-validator-tf.yml
new file mode 100644
index 0000000..28fd356
--- /dev/null
+++ b/.github/workflows/policy-validator-tf.yml
@@ -0,0 +1,101 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This workflow will validate the IAM policies in the terraform (TF) templates with using the standard and custom checks in AWS IAM Access Analyzer
+# To use this workflow, you will need to complete the following set up steps before start using it:
+# 1. Configure an AWS IAM role to use the Access Analyzer's ValidatePolicy, CheckNoNewAccess and CheckAccessNotGranted. This IAM role must be configured to call from the GitHub Actions, use the following [doc](https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/) for steps.
+# 2. If you're using CHECK_NO_NEW_ACCESS policy-check-type, you need to create a reference policy. Use the guide [here](https://github.com/aws-samples/iam-access-analyzer-custom-policy-check-samples?tab=readme-ov-file#how-do-i-write-my-own-reference-policies) and store it your GitHub repo.
+# 3. If you're using the CHECK_ACCESS_NOT_GRANTED policy-check-type, identify the list of critical actions that shouldn't be granted access by the policies in the TF templates.
+# 4. Start using the GitHub actions by generating the GitHub events matching the defined criteria in your workflow.
+
+name: Validate AWS IAM policies in Terraform templates using Policy Validator
+on:
+ push:
+ branches: ["main" ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: ["main"]
+env:
+ AWS_ROLE: MY_ROLE # set this with the role ARN which has permissions to invoke access-analyzer:ValidatePolicy,access-analyzer:CheckNoNewAccess, access-analyzer:CheckAccessNotGranted and can be used in GitHub actions
+ REGION: MY_AWS_REGION # set this to your preferred AWS region where you plan to deploy your policies, e.g. us-west-1
+ TEMPLATE_PATH: FILE_PATH_TO_THE_TF_PLAN # set this to the file path to the terraform plan in JSON
+ ACTIONS: MY_LIST_OF_ACTIONS # set to pass list of actions in the format action1, action2,.. One of `ACTIONS` or `RESOURCES` is required if you are using `CHECK_ACCESS_NOT_GRANTED` policy-check-type.
+ RESOURCES: MY_LIST_OF_RESOURCES # set to pass list of resource ARNs in the format resource1, resource2,.. One of `ACTIONS` or `RESOURCES` is required if you are using `CHECK_ACCESS_NOT_GRANTED` policy-check-type.
+ REFERENCE_POLICY: REFERENCE_POLICY # set to pass a JSON formatted file that specifies the path to the reference policy that is used for a permissions comparison. For example, if you stored such path in a GitHub secret with name REFERENCE_IDENTITY_POLICY , you can pass ${{ secrets.REFERENCE_IDENTITY_POLICY }}. If not you have the reference policy in the repository, you can directly pass it's path. This is required if you are using `CHECK_NO_NEW_ACCESS_CHECK` policy-check-type.
+ REFERENCE_POLICY_TYPE: TYPE_OF_REFERENCE_POLICY # set to pass the policy type associated with the IAM policy under analysis and the reference policy. This is required if you are using `CHECK_NO_NEW_ACCESS_CHECK` policy-check-type.
+
+jobs:
+ policy-validator:
+ runs-on: ubuntu-latest # Virtual machine to run the workflow (configurable)
+ #https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services#updating-your-github-actions-workflow
+ #https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/
+ permissions:
+ id-token: write # This is required for requesting the JWT
+ contents: read # This is required for actions/checkout
+ # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners
+ name: Policy Validator checks for AWS IAM policies
+ steps:
+ # checkout the repo for workflow to access the contents
+ - name: Checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ # Configure AWS Credentials. More configuration details here- https://github.com/aws-actions/configure-aws-credentials
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
+ with:
+ role-to-assume: ${{ env.AWS_ROLE }}
+ aws-region: ${{ env.REGION }}
+ # Run the VALIDATE_POLICY check. More configuration details here - https://github.com/aws-actions/terraform-aws-iam-policy-validator
+ - name: Run AWS AccessAnalyzer ValidatePolicy check
+ id: run-aws-validate-policy
+ uses: aws-actions/terraform-aws-iam-policy-validator@26797c40250bf1ee50af8996a2475b9b5a8b8927 #v1.0.2
+ with:
+ policy-check-type: "VALIDATE_POLICY"
+ template-path: ${{ env.TEMPLATE_PATH }}
+ region: ${{ env.REGION }}
+ # Print result from VALIDATE_POLICY check
+ - name: Print the result for ValidatePolicy check
+ if: success() || failure()
+ run: echo "${{ steps.run-aws-validate-policy.outputs.result }}"
+ # Run the CHECK_ACCESS_NOT_GRANTED check. More configuration details here - https://github.com/aws-actions/terraform-aws-iam-policy-validator
+ - name: Run AWS AccessAnalyzer CheckAccessNotGranted check
+ id: run-aws-check-access-not-granted
+ uses: aws-actions/terraform-aws-iam-policy-validator@26797c40250bf1ee50af8996a2475b9b5a8b8927 #v1.0.2
+ with:
+ policy-check-type: "CHECK_ACCESS_NOT_GRANTED"
+ template-path: ${{ env.TEMPLATE_PATH }}
+ actions: ${{ env.ACTIONS }}
+ resources: ${{ env.RESOURCES }}
+ region: ${{ env.REGION }}
+ # Print result from CHECK_ACCESS_NOT_GRANTED check
+ - name: Print the result for CheckAccessNotGranted check
+ if: success() || failure()
+ run: echo "${{ steps.run-aws-check-access-not-granted.outputs.result }}"
+ # Run the CHECK_NO_NEW_ACCESS check. More configuration details here - https://github.com/aws-actions/terraform-aws-iam-policy-validator
+ # reference-policy is stored in GitHub secrets
+ - name: Run AWS AccessAnalyzer CheckNoNewAccess check
+ id: run-aws-check-no-new-access
+ uses: aws-actions/terraform-aws-iam-policy-validator@26797c40250bf1ee50af8996a2475b9b5a8b8927 #v1.0.2
+ with:
+ policy-check-type: "CHECK_NO_NEW_ACCESS"
+ template-path: ${{ env.TEMPLATE_PATH }}
+ reference-policy: ${{ env.REFERENCE_POLICY }}
+ reference-policy-type: ${{ env.REFERENCE_POLICY_TYPE }}
+ region: ${{ env.REGION }}
+ # Print result from CHECK_NO_NEW_ACCESS check
+ - name: Print the result CheckNoNewAccess check
+ if: success() || failure()
+ run: echo "${{ steps.run-aws-check-no-new-access.outputs.result }}"
+ # Run the CHECK_NO_PUBLIC_ACCESS check. More configuration details here - https://github.com/aws-actions/terraform-aws-iam-policy-validator
+ - name: Run AWS AccessAnalyzer CheckNoPublicAccess check
+ id: run-aws-check-no-public-access
+ uses: aws-actions/terraform-aws-iam-policy-validator@26797c40250bf1ee50af8996a2475b9b5a8b8927 #v1.0.2
+ with:
+ policy-check-type: "CHECK_NO_PUBLIC_ACCESS"
+ template-path: ${{ env.TEMPLATE_PATH }}
+ region: ${{ env.REGION }}
+ # Print result from CHECK_NO_PUBLIC_ACCESS check
+ - name: Print the result for CheckNoPublicAccess check
+ if: success() || failure()
+ run: echo "${{ steps.run-aws-check-no-public-access.outputs.result }}"
From a3906ddc41f4a39847b60f2df461e36acc620a36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:11:16 +0700
Subject: [PATCH 18/63] Create sonarcloud.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/sonarcloud.yml | 67 ++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 .github/workflows/sonarcloud.yml
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
new file mode 100644
index 0000000..07701be
--- /dev/null
+++ b/.github/workflows/sonarcloud.yml
@@ -0,0 +1,67 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This workflow helps you trigger a SonarCloud analysis of your code and populates
+# GitHub Code Scanning alerts with the vulnerabilities found.
+# Free for open source project.
+
+# 1. Login to SonarCloud.io using your GitHub account
+
+# 2. Import your project on SonarCloud
+# * Add your GitHub organization first, then add your repository as a new project.
+# * Please note that many languages are eligible for automatic analysis,
+# which means that the analysis will start automatically without the need to set up GitHub Actions.
+# * This behavior can be changed in Administration > Analysis Method.
+#
+# 3. Follow the SonarCloud in-product tutorial
+# * a. Copy/paste the Project Key and the Organization Key into the args parameter below
+# (You'll find this information in SonarCloud. Click on "Information" at the bottom left)
+#
+# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN
+# (On SonarCloud, click on your avatar on top-right > My account > Security
+# or go directly to https://sonarcloud.io/account/security/)
+
+# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/)
+# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9)
+
+name: SonarCloud analysis
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+ workflow_dispatch:
+
+permissions:
+ pull-requests: read # allows SonarCloud to decorate PRs with analysis results
+
+jobs:
+ Analysis:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Analyze with SonarCloud
+
+ # You can pin the exact commit or the version.
+ # uses: SonarSource/sonarcloud-github-action@v2.2.0
+ uses: SonarSource/sonarcloud-github-action@4006f663ecaf1f8093e8e4abb9227f6041f52216
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on Sonarcloud.io, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret)
+ with:
+ # Additional arguments for the SonarScanner CLI
+ args:
+ # Unique keys of your project and organization. You can find them in SonarCloud > Information (bottom-left menu)
+ # mandatory
+ -Dsonar.projectKey=
+ -Dsonar.organization=
+ # Comma-separated paths to directories containing main source files.
+ #-Dsonar.sources= # optional, default is project base directory
+ # Comma-separated paths to directories containing test source files.
+ #-Dsonar.tests= # optional. For more info about Code Coverage, please refer to https://docs.sonarcloud.io/enriching/test-coverage/overview/
+ # Adds more detail to both client and server-side analysis logs, activating DEBUG mode for the scanner, and adding client-side environment variables and system properties to the server-side log of analysis report processing.
+ #-Dsonar.verbose= # optional, default is false
+ # When you need the analysis to take place in a directory other than the one from which it was launched, default is .
+ projectBaseDir: .
From 995ef3f23114eda928183fe54b73a7fa3f777a09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:15:26 +0700
Subject: [PATCH 19/63] Create CONTRIBUTING.md
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
CONTRIBUTING.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1 @@
+
From 09dcafd221d1a1802ccb4310a0bf8a63ab45b072 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:43:16 +0700
Subject: [PATCH 20/63] Create azure-webapps-node.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/azure-webapps-node.yml | 78 ++++++++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 .github/workflows/azure-webapps-node.yml
diff --git a/.github/workflows/azure-webapps-node.yml b/.github/workflows/azure-webapps-node.yml
new file mode 100644
index 0000000..2ebbac2
--- /dev/null
+++ b/.github/workflows/azure-webapps-node.yml
@@ -0,0 +1,78 @@
+# This workflow will build and push a node.js application to an Azure Web App when a commit is pushed to your default branch.
+#
+# This workflow assumes you have already created the target Azure App Service web app.
+# For instructions see https://docs.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=linux&pivots=development-environment-cli
+#
+# To configure this workflow:
+#
+# 1. Download the Publish Profile for your Azure Web App. You can download this file from the Overview page of your Web App in the Azure Portal.
+# For more information: https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#generate-deployment-credentials
+#
+# 2. Create a secret in your repository named AZURE_WEBAPP_PUBLISH_PROFILE, paste the publish profile contents as the value of the secret.
+# For instructions on obtaining the publish profile see: https://docs.microsoft.com/azure/app-service/deploy-github-actions#configure-the-github-secret
+#
+# 3. Change the value for the AZURE_WEBAPP_NAME. Optionally, change the AZURE_WEBAPP_PACKAGE_PATH and NODE_VERSION environment variables below.
+#
+# For more information on GitHub Actions for Azure: https://github.com/Azure/Actions
+# For more information on the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
+# For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples
+
+on:
+ push:
+ branches: [ "main" ]
+ workflow_dispatch:
+
+env:
+ AZURE_WEBAPP_NAME: your-app-name # set this to your application's name
+ AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
+ NODE_VERSION: '20.x' # set this to the node version to use
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: 'npm'
+
+ - name: npm install, build, and test
+ run: |
+ npm install
+ npm run build --if-present
+ npm run test --if-present
+
+ - name: Upload artifact for deployment job
+ uses: actions/upload-artifact@v4
+ with:
+ name: node-app
+ path: .
+
+ deploy:
+ permissions:
+ contents: none
+ runs-on: ubuntu-latest
+ needs: build
+ environment:
+ name: 'Development'
+ url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
+
+ steps:
+ - name: Download artifact from build job
+ uses: actions/download-artifact@v4
+ with:
+ name: node-app
+
+ - name: 'Deploy to Azure WebApp'
+ id: deploy-to-webapp
+ uses: azure/webapps-deploy@v2
+ with:
+ app-name: ${{ env.AZURE_WEBAPP_NAME }}
+ publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
+ package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
From 819e26947383de98e075623c2347703b53475115 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:44:03 +0700
Subject: [PATCH 21/63] Create google.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/google.yml | 116 +++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
create mode 100644 .github/workflows/google.yml
diff --git a/.github/workflows/google.yml b/.github/workflows/google.yml
new file mode 100644
index 0000000..0b5c7d1
--- /dev/null
+++ b/.github/workflows/google.yml
@@ -0,0 +1,116 @@
+# This workflow will build a docker container, publish it to Google Container
+# Registry, and deploy it to GKE when there is a push to the "main"
+# branch.
+#
+# To configure this workflow:
+#
+# 1. Enable the following Google Cloud APIs:
+#
+# - Artifact Registry (artifactregistry.googleapis.com)
+# - Google Kubernetes Engine (container.googleapis.com)
+# - IAM Credentials API (iamcredentials.googleapis.com)
+#
+# You can learn more about enabling APIs at
+# https://support.google.com/googleapi/answer/6158841.
+#
+# 2. Ensure that your repository contains the necessary configuration for your
+# Google Kubernetes Engine cluster, including deployment.yml,
+# kustomization.yml, service.yml, etc.
+#
+# 3. Create and configure a Workload Identity Provider for GitHub:
+# https://github.com/google-github-actions/auth#preferred-direct-workload-identity-federation.
+#
+# Depending on how you authenticate, you will need to grant an IAM principal
+# permissions on Google Cloud:
+#
+# - Artifact Registry Administrator (roles/artifactregistry.admin)
+# - Kubernetes Engine Developer (roles/container.developer)
+#
+# You can learn more about setting IAM permissions at
+# https://cloud.google.com/iam/docs/manage-access-other-resources
+#
+# 5. Change the values in the "env" block to match your values.
+
+name: 'Build and Deploy to GKE'
+
+on:
+ push:
+ branches:
+ - '"main"'
+
+env:
+ PROJECT_ID: 'my-project' # TODO: update to your Google Cloud project ID
+ GAR_LOCATION: 'us-central1' # TODO: update to your region
+ GKE_CLUSTER: 'cluster-1' # TODO: update to your cluster name
+ GKE_ZONE: 'us-central1-c' # TODO: update to your cluster zone
+ DEPLOYMENT_NAME: 'gke-test' # TODO: update to your deployment name
+ REPOSITORY: 'samples' # TODO: update to your Artifact Registry docker repository name
+ IMAGE: 'static-site'
+ WORKLOAD_IDENTITY_PROVIDER: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' # TODO: update to your workload identity provider
+
+jobs:
+ setup-build-publish-deploy:
+ name: 'Setup, Build, Publish, and Deploy'
+ runs-on: 'ubuntu-latest'
+ environment: 'production'
+
+ permissions:
+ contents: 'read'
+ id-token: 'write'
+
+ steps:
+ - name: 'Checkout'
+ uses: 'actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332' # actions/checkout@v4
+
+ # Configure Workload Identity Federation and generate an access token.
+ #
+ # See https://github.com/google-github-actions/auth for more options,
+ # including authenticating via a JSON credentials file.
+ - id: 'auth'
+ name: 'Authenticate to Google Cloud'
+ uses: 'google-github-actions/auth@f112390a2df9932162083945e46d439060d66ec2' # google-github-actions/auth@v2
+ with:
+ workload_identity_provider: '${{ env.WORKLOAD_IDENTITY_PROVIDER }}'
+
+ # Authenticate Docker to Google Cloud Artifact Registry
+ - name: 'Docker Auth'
+ uses: 'docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567' # docker/login-action@v3
+ with:
+ username: 'oauth2accesstoken'
+ password: '${{ steps.auth.outputs.auth_token }}'
+ registry: '${{ env.GAR_LOCATION }}-docker.pkg.dev'
+
+ # Get the GKE credentials so we can deploy to the cluster
+ - name: 'Set up GKE credentials'
+ uses: 'google-github-actions/get-gke-credentials@6051de21ad50fbb1767bc93c11357a49082ad116' # google-github-actions/get-gke-credentials@v2
+ with:
+ cluster_name: '${{ env.GKE_CLUSTER }}'
+ location: '${{ env.GKE_ZONE }}'
+
+ # Build the Docker image
+ - name: 'Build and push Docker container'
+ run: |-
+ DOCKER_TAG="${GAR_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE}:${GITHUB_SHA}"
+
+ docker build \
+ --tag "${DOCKER_TAG}" \
+ --build-arg GITHUB_SHA="${GITHUB_SHA}" \
+ --build-arg GITHUB_REF="${GITHUB_REF}" \
+ .
+
+ docker push "${DOCKER_TAG}"
+
+ # Set up kustomize
+ - name: 'Set up Kustomize'
+ run: |-
+ curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz
+ chmod u+x ./kustomize
+
+ # Deploy the Docker image to the GKE cluster
+ - name: 'Deploy to GKE'
+ run: |-
+ # replacing the image name in the k8s template
+ ./kustomize edit set image LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:TAG=$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE:$GITHUB_SHA
+ ./kustomize build . | kubectl apply -f -
+ kubectl rollout status deployment/$DEPLOYMENT_NAME
+ kubectl get services -o wide
From 938be392029d3ff4ed97ffa5c696e2cd95fc01ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:44:31 +0700
Subject: [PATCH 22/63] Create terraform.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/terraform.yml | 93 +++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 .github/workflows/terraform.yml
diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml
new file mode 100644
index 0000000..540e804
--- /dev/null
+++ b/.github/workflows/terraform.yml
@@ -0,0 +1,93 @@
+# This workflow installs the latest version of Terraform CLI and configures the Terraform CLI configuration file
+# with an API token for Terraform Cloud (app.terraform.io). On pull request events, this workflow will run
+# `terraform init`, `terraform fmt`, and `terraform plan` (speculative plan via Terraform Cloud). On push events
+# to the "main" branch, `terraform apply` will be executed.
+#
+# Documentation for `hashicorp/setup-terraform` is located here: https://github.com/hashicorp/setup-terraform
+#
+# To use this workflow, you will need to complete the following setup steps.
+#
+# 1. Create a `main.tf` file in the root of this repository with the `remote` backend and one or more resources defined.
+# Example `main.tf`:
+# # The configuration for the `remote` backend.
+# terraform {
+# backend "remote" {
+# # The name of your Terraform Cloud organization.
+# organization = "example-organization"
+#
+# # The name of the Terraform Cloud workspace to store Terraform state files in.
+# workspaces {
+# name = "example-workspace"
+# }
+# }
+# }
+#
+# # An example resource that does nothing.
+# resource "null_resource" "example" {
+# triggers = {
+# value = "A example resource that does nothing!"
+# }
+# }
+#
+#
+# 2. Generate a Terraform Cloud user API token and store it as a GitHub secret (e.g. TF_API_TOKEN) on this repository.
+# Documentation:
+# - https://www.terraform.io/docs/cloud/users-teams-organizations/api-tokens.html
+# - https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
+#
+# 3. Reference the GitHub secret in step using the `hashicorp/setup-terraform` GitHub Action.
+# Example:
+# - name: Setup Terraform
+# uses: hashicorp/setup-terraform@v1
+# with:
+# cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
+
+name: 'Terraform'
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ terraform:
+ name: 'Terraform'
+ runs-on: ubuntu-latest
+ environment: production
+
+ # Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
+ defaults:
+ run:
+ shell: bash
+
+ steps:
+ # Checkout the repository to the GitHub Actions runner
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token
+ - name: Setup Terraform
+ uses: hashicorp/setup-terraform@v1
+ with:
+ cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
+
+ # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc.
+ - name: Terraform Init
+ run: terraform init
+
+ # Checks that all Terraform configuration files adhere to a canonical format
+ - name: Terraform Format
+ run: terraform fmt -check
+
+ # Generates an execution plan for Terraform
+ - name: Terraform Plan
+ run: terraform plan -input=false
+
+ # On push to "main", build or change infrastructure according to Terraform configuration files
+ # Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks
+ - name: Terraform Apply
+ if: github.ref == 'refs/heads/"main"' && github.event_name == 'push'
+ run: terraform apply -auto-approve -input=false
From cd4fe90da6694cf5c787bf5372827a2eeb7edce2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:45:10 +0700
Subject: [PATCH 23/63] Create openshift.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/openshift.yml | 202 ++++++++++++++++++++++++++++++++
1 file changed, 202 insertions(+)
create mode 100644 .github/workflows/openshift.yml
diff --git a/.github/workflows/openshift.yml b/.github/workflows/openshift.yml
new file mode 100644
index 0000000..f5de166
--- /dev/null
+++ b/.github/workflows/openshift.yml
@@ -0,0 +1,202 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# 💁 The OpenShift Starter workflow will:
+# - Checkout your repository
+# - Perform a container image build
+# - Push the built image to the GitHub Container Registry (GHCR)
+# - Log in to your OpenShift cluster
+# - Create an OpenShift app from the image and expose it to the internet
+
+# ℹ️ Configure your repository and the workflow with the following steps:
+# 1. Have access to an OpenShift cluster. Refer to https://www.openshift.com/try
+# 2. Create the OPENSHIFT_SERVER and OPENSHIFT_TOKEN repository secrets. Refer to:
+# - https://github.com/redhat-actions/oc-login#readme
+# - https://docs.github.com/en/actions/reference/encrypted-secrets
+# - https://cli.github.com/manual/gh_secret_set
+# 3. (Optional) Edit the top-level 'env' section as marked with '🖊️' if the defaults are not suitable for your project.
+# 4. (Optional) Edit the build-image step to build your project.
+# The default build type is by using a Dockerfile at the root of the repository,
+# but can be replaced with a different file, a source-to-image build, or a step-by-step buildah build.
+# 5. Commit and push the workflow file to your default branch to trigger a workflow run.
+
+# 👋 Visit our GitHub organization at https://github.com/redhat-actions/ to see our actions and provide feedback.
+
+name: OpenShift
+
+env:
+ # 🖊️ EDIT your repository secrets to log into your OpenShift cluster and set up the context.
+ # See https://github.com/redhat-actions/oc-login#readme for how to retrieve these values.
+ # To get a permanent token, refer to https://github.com/redhat-actions/oc-login/wiki/Using-a-Service-Account-for-GitHub-Actions
+ OPENSHIFT_SERVER: ${{ secrets.OPENSHIFT_SERVER }}
+ OPENSHIFT_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }}
+ # 🖊️ EDIT to set the kube context's namespace after login. Leave blank to use your user's default namespace.
+ OPENSHIFT_NAMESPACE: ""
+
+ # 🖊️ EDIT to set a name for your OpenShift app, or a default one will be generated below.
+ APP_NAME: ""
+
+ # 🖊️ EDIT with the port your application should be accessible on.
+ # If the container image exposes *exactly one* port, this can be left blank.
+ # Refer to the 'port' input of https://github.com/redhat-actions/oc-new-app
+ APP_PORT: ""
+
+ # 🖊️ EDIT to change the image registry settings.
+ # Registries such as GHCR, Quay.io, and Docker Hub are supported.
+ IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}
+ IMAGE_REGISTRY_USER: ${{ github.actor }}
+ IMAGE_REGISTRY_PASSWORD: ${{ github.token }}
+
+ # 🖊️ EDIT to specify custom tags for the container image, or default tags will be generated below.
+ IMAGE_TAGS: ""
+
+on:
+ # https://docs.github.com/en/actions/reference/events-that-trigger-workflows
+ workflow_dispatch:
+ push:
+ # Edit to the branch(es) you want to build and deploy on each push.
+ branches: [ "main" ]
+
+jobs:
+ # 🖊️ EDIT if you want to run vulnerability check on your project before deploying
+ # the application. Please uncomment the below CRDA scan job and configure to run it in
+ # your workflow. For details about CRDA action visit https://github.com/redhat-actions/crda/blob/main/README.md
+ #
+ # TODO: Make sure to add 'CRDA Scan' starter workflow from the 'Actions' tab.
+ # For guide on adding new starter workflow visit https://docs.github.com/en/github-ae@latest/actions/using-workflows/using-starter-workflows
+
+ #crda-scan:
+ # uses: ./.github/workflows/crda.yml
+ # secrets:
+ # CRDA_KEY: ${{ secrets.CRDA_KEY }}
+ # # SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} # Either use SNYK_TOKEN or CRDA_KEY
+
+ openshift-ci-cd:
+ # 🖊️ Uncomment this if you are using CRDA scan step above
+ # needs: crda-scan
+ name: Build and deploy to OpenShift
+ runs-on: ubuntu-latest
+ environment: production
+
+ outputs:
+ ROUTE: ${{ steps.deploy-and-expose.outputs.route }}
+ SELECTOR: ${{ steps.deploy-and-expose.outputs.selector }}
+
+ steps:
+ - name: Check for required secrets
+ uses: actions/github-script@v6
+ with:
+ script: |
+ const secrets = {
+ OPENSHIFT_SERVER: `${{ secrets.OPENSHIFT_SERVER }}`,
+ OPENSHIFT_TOKEN: `${{ secrets.OPENSHIFT_TOKEN }}`,
+ };
+
+ const GHCR = "ghcr.io";
+ if (`${{ env.IMAGE_REGISTRY }}`.startsWith(GHCR)) {
+ core.info(`Image registry is ${GHCR} - no registry password required`);
+ }
+ else {
+ core.info("A registry password is required");
+ secrets["IMAGE_REGISTRY_PASSWORD"] = `${{ secrets.IMAGE_REGISTRY_PASSWORD }}`;
+ }
+
+ const missingSecrets = Object.entries(secrets).filter(([ name, value ]) => {
+ if (value.length === 0) {
+ core.error(`Secret "${name}" is not set`);
+ return true;
+ }
+ core.info(`✔️ Secret "${name}" is set`);
+ return false;
+ });
+
+ if (missingSecrets.length > 0) {
+ core.setFailed(`❌ At least one required secret is not set in the repository. \n` +
+ "You can add it using:\n" +
+ "GitHub UI: https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository \n" +
+ "GitHub CLI: https://cli.github.com/manual/gh_secret_set \n" +
+ "Also, refer to https://github.com/redhat-actions/oc-login#getting-started-with-the-action-or-see-example");
+ }
+ else {
+ core.info(`✅ All the required secrets are set`);
+ }
+
+ - name: Check out repository
+ uses: actions/checkout@v4
+
+ - name: Determine app name
+ if: env.APP_NAME == ''
+ run: |
+ echo "APP_NAME=$(basename $PWD)" | tee -a $GITHUB_ENV
+
+ - name: Determine image tags
+ if: env.IMAGE_TAGS == ''
+ run: |
+ echo "IMAGE_TAGS=latest ${GITHUB_SHA::12}" | tee -a $GITHUB_ENV
+
+ # https://github.com/redhat-actions/buildah-build#readme
+ - name: Build from Dockerfile
+ id: build-image
+ uses: redhat-actions/buildah-build@v2
+ with:
+ image: ${{ env.APP_NAME }}
+ tags: ${{ env.IMAGE_TAGS }}
+
+ # If you don't have a Dockerfile/Containerfile, refer to https://github.com/redhat-actions/buildah-build#scratch-build-inputs
+ # Or, perform a source-to-image build using https://github.com/redhat-actions/s2i-build
+ # Otherwise, point this to your Dockerfile/Containerfile relative to the repository root.
+ dockerfiles: |
+ ./Dockerfile
+
+ # https://github.com/redhat-actions/push-to-registry#readme
+ - name: Push to registry
+ id: push-image
+ uses: redhat-actions/push-to-registry@v2
+ with:
+ image: ${{ steps.build-image.outputs.image }}
+ tags: ${{ steps.build-image.outputs.tags }}
+ registry: ${{ env.IMAGE_REGISTRY }}
+ username: ${{ env.IMAGE_REGISTRY_USER }}
+ password: ${{ env.IMAGE_REGISTRY_PASSWORD }}
+
+ # The path the image was pushed to is now stored in ${{ steps.push-image.outputs.registry-path }}
+
+ - name: Install oc
+ uses: redhat-actions/openshift-tools-installer@v1
+ with:
+ oc: 4
+
+ # https://github.com/redhat-actions/oc-login#readme
+ - name: Log in to OpenShift
+ uses: redhat-actions/oc-login@v1
+ with:
+ openshift_server_url: ${{ env.OPENSHIFT_SERVER }}
+ openshift_token: ${{ env.OPENSHIFT_TOKEN }}
+ insecure_skip_tls_verify: true
+ namespace: ${{ env.OPENSHIFT_NAMESPACE }}
+
+ # This step should create a deployment, service, and route to run your app and expose it to the internet.
+ # https://github.com/redhat-actions/oc-new-app#readme
+ - name: Create and expose app
+ id: deploy-and-expose
+ uses: redhat-actions/oc-new-app@v1
+ with:
+ app_name: ${{ env.APP_NAME }}
+ image: ${{ steps.push-image.outputs.registry-path }}
+ namespace: ${{ env.OPENSHIFT_NAMESPACE }}
+ port: ${{ env.APP_PORT }}
+
+ - name: Print application URL
+ env:
+ ROUTE: ${{ steps.deploy-and-expose.outputs.route }}
+ SELECTOR: ${{ steps.deploy-and-expose.outputs.selector }}
+ run: |
+ [[ -n ${{ env.ROUTE }} ]] || (echo "Determining application route failed in previous step"; exit 1)
+ echo
+ echo "======================== Your application is available at: ========================"
+ echo ${{ env.ROUTE }}
+ echo "==================================================================================="
+ echo
+ echo "Your app can be taken down with: \"oc delete all --selector='${{ env.SELECTOR }}'\""
From 67b4c03644ba11ecdb7353e3f0bf28dabcc2985a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:45:49 +0700
Subject: [PATCH 24/63] Create generator-generic-ossf-slsa3-publish.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.../generator-generic-ossf-slsa3-publish.yml | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 .github/workflows/generator-generic-ossf-slsa3-publish.yml
diff --git a/.github/workflows/generator-generic-ossf-slsa3-publish.yml b/.github/workflows/generator-generic-ossf-slsa3-publish.yml
new file mode 100644
index 0000000..35c829b
--- /dev/null
+++ b/.github/workflows/generator-generic-ossf-slsa3-publish.yml
@@ -0,0 +1,66 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This workflow lets you generate SLSA provenance file for your project.
+# The generation satisfies level 3 for the provenance requirements - see https://slsa.dev/spec/v0.1/requirements
+# The project is an initiative of the OpenSSF (openssf.org) and is developed at
+# https://github.com/slsa-framework/slsa-github-generator.
+# The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier.
+# For more information about SLSA and how it improves the supply-chain, visit slsa.dev.
+
+name: SLSA generic generator
+on:
+ workflow_dispatch:
+ release:
+ types: [created]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ outputs:
+ digests: ${{ steps.hash.outputs.digests }}
+
+ steps:
+ - uses: actions/checkout@v4
+
+ # ========================================================
+ #
+ # Step 1: Build your artifacts.
+ #
+ # ========================================================
+ - name: Build artifacts
+ run: |
+ # These are some amazing artifacts.
+ echo "artifact1" > artifact1
+ echo "artifact2" > artifact2
+
+ # ========================================================
+ #
+ # Step 2: Add a step to generate the provenance subjects
+ # as shown below. Update the sha256 sum arguments
+ # to include all binaries that you generate
+ # provenance for.
+ #
+ # ========================================================
+ - name: Generate subject for provenance
+ id: hash
+ run: |
+ set -euo pipefail
+
+ # List the artifacts the provenance will refer to.
+ files=$(ls artifact*)
+ # Generate the subjects (base64 encoded).
+ echo "hashes=$(sha256sum $files | base64 -w0)" >> "${GITHUB_OUTPUT}"
+
+ provenance:
+ needs: [build]
+ permissions:
+ actions: read # To read the workflow path.
+ id-token: write # To sign the provenance.
+ contents: write # To add assets to a release.
+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0
+ with:
+ base64-subjects: "${{ needs.build.outputs.digests }}"
+ upload-assets: true # Optional: Upload to a new release
From 459762bd71820015762c7c61b1e429878ea0b068 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:46:26 +0700
Subject: [PATCH 25/63] Create fortify.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/fortify.yml | 129 ++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
create mode 100644 .github/workflows/fortify.yml
diff --git a/.github/workflows/fortify.yml b/.github/workflows/fortify.yml
new file mode 100644
index 0000000..51ca2bc
--- /dev/null
+++ b/.github/workflows/fortify.yml
@@ -0,0 +1,129 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+################################################################################################################################################
+# Fortify Application Security provides your team with solutions to empower DevSecOps practices, enable cloud transformation, and secure your #
+# software supply chain. To learn more about Fortify, start a free trial or contact our sales team, visit fortify.com. #
+# #
+# Use this starter workflow as a basis for integrating Fortify Application Security Testing into your GitHub workflows. This template #
+# demonstrates the steps to package the code+dependencies, initiate a scan, and optionally import SAST vulnerabilities into GitHub Security #
+# Code Scanning Alerts. Additional information is available in the workflow comments and the Fortify AST Action / fcli / Fortify product #
+# documentation. If you need additional assistance, please contact Fortify support. #
+################################################################################################################################################
+
+name: Fortify AST Scan
+
+# Customize trigger events based on your DevSecOps process and/or policy
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ "main" ]
+ schedule:
+ - cron: '38 10 * * 0'
+ workflow_dispatch:
+
+jobs:
+ Fortify-AST-Scan:
+ # Use the appropriate runner for building your source code. Ensure dev tools required to build your code are present and configured appropriately (MSBuild, Python, etc).
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+ # pull-requests: write # Required if DO_PR_COMMENT is set to true
+
+ steps:
+ # Check out source code
+ - name: Check Out Source Code
+ uses: actions/checkout@v4
+
+ # Perform SAST and/or SCA scan via Fortify on Demand/Fortify Hosted/ScanCentral SAST/Debricked. Based on
+ # configuration, the Fortify GitHub Action can optionally set up the application version/release, generate
+ # job summaries and Pull Request comments, and/or export SAST results to the GitHub code scanning dashboard.
+ # The Fortify GitHub Action provides many customization capabilities, but in case further customization is
+ # required, you can use sub-actions like fortify/github-action/setup@v1 to set up the various Fortify tools
+ # and run them directly from within your pipeline. It is recommended to review the Fortify GitHub Action
+ # documentation at https://github.com/fortify/github-action#readme for more information on the various
+ # configuration options and available sub-actions.
+ - name: Run Fortify Scan
+ # Specify Fortify GitHub Action version to run. As per GitHub starter workflow requirements, this example
+ # uses the commit id corresponding to version 1.6.2. It is recommended to check whether any later releases
+ # are available at https://github.com/fortify/github-action/releases. Depending on the amount of stability
+ # required, you may want to consider using fortify/github-action@v1 instead to use the latest 1.x.y version
+ # of this action, allowing your workflows to automatically benefit from any new features and bug fixes.
+ uses: fortify/github-action@ef5539bf4bd9c45c0bd971978f635a69eae55297
+ with:
+ sast-scan: true # Run a SAST scan; if not specified or set to false, no SAST scan will be run
+ debricked-sca-scan: true # For FoD, run an open-source scan as part of the SAST scan (ignored if SAST scan
+ # is disabled). For SSC, run a Debricked scan and import results into SSC.
+ env:
+ #############################################################
+ ##### Fortify on Demand configuration
+ ##### Remove this section if you're integrating with Fortify Hosted/Software Security Center (see below)
+ ### Required configuration
+ FOD_URL: https://ams.fortify.com # Must be hardcoded or configured through GitHub variable, not secret
+ FOD_TENANT: ${{secrets.FOD_TENANT}} # Either tenant/user/password or client id/secret are required;
+ FOD_USER: ${{secrets.FOD_USER}} # these should be configured through GitHub secrets.
+ FOD_PASSWORD: ${{secrets.FOD_PAT}}
+ # FOD_CLIENT_ID: ${{secrets.FOD_CLIENT_ID}}
+ # FOD_CLIENT_SECRET: ${{secrets.FOD_CLIENT_SECRET}}
+ ### Optional configuration
+ # FOD_LOGIN_EXTRA_OPTS: --socket-timeout=60s # Extra 'fcli fod session login' options
+ # FOD_RELEASE: MyApp:MyRelease # FoD release name, default: /:
+ # DO_SETUP: true # Setup FoD application, release & static scan configuration
+ # SETUP_ACTION: # Customize setup action
+ # Pass extra options to setup action:
+ # SETUP_EXTRA_OPTS: --copy-from "${{ github.repository }}:${{ github.event.repository.default_branch }}"
+ # PACKAGE_EXTRA_OPTS: -oss -bt mvn # Extra 'scancentral package' options
+ # FOD_SAST_SCAN_EXTRA_OPTS: # Extra 'fcli fod sast-scan start' options
+ # DO_WAIT: true # Wait for successful scan completion (implied if post-scan actions enabled)
+ # DO_POLICY_CHECK: true # Fail pipeline if security policy outcome is FAIL
+ # POLICY_CHECK_ACTION: # Customize security policy checks
+ # POLICY_CHECK_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to policy check action
+ # DO_JOB_SUMMARY: true # Generate workflow job summary
+ # JOB_SUMMARY_ACTION: # Customize job summary
+ # JOB_SUMMARY_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to job summary action
+ # DO_PR_COMMENT: true # Generate PR comments, only used on pull_request triggers
+ # PR_COMMENT_ACTION: # Customize PR comments
+ # PR_COMMENT_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to PR comment action
+ # DO_EXPORT: true # Export vulnerability data to GitHub code scanning dashboard
+ # EXPORT_ACTION: # Customize export action
+ # EXPORT_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to export action
+ # TOOL_DEFINITIONS: # URL from where to retrieve Fortify tool definitions
+
+ #############################################################
+ ##### Fortify Hosted / Software Security Center & ScanCentral
+ ##### Remove this section if you're integrating with Fortify on Demand (see above)
+ ### Required configuration
+ SSC_URL: ${{vars.SSC_URL}} # Must be hardcoded or configured through GitHub variable, not secret
+ SSC_TOKEN: ${{secrets.SSC_TOKEN}} # SSC CIToken; credentials should be configured through GitHub secrets
+ SC_SAST_TOKEN: ${{secrets.SC_CLIENT_AUTH_TOKEN}} # ScanCentral SAST client_auth_token, required if SAST scan is enabled
+ DEBRICKED_TOKEN: ${{secrets.DEBRICKED_TOKEN}} # Debricked token, required if Debricked scan is enabled
+ SC_SAST_SENSOR_VERSION: 24.4.0 # Sensor version to use for the scan, required if SAST scan is enabled
+ ### Optional configuration
+ # SSC_LOGIN_EXTRA_OPTS: --socket-timeout=60s # Extra 'fcli ssc session login' options
+ # SC_SAST_LOGIN_EXTRA_OPTS: --socket-timeout=60s # Extra 'fcli sc-sast session login' options
+ # SSC_APPVERSION: MyApp:MyVersion # SSC application version name, default: /:
+ # DO_SETUP: true # Set up SSC application & version
+ # SETUP_ACTION: # Customize setup action
+ # SETUP_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to setup action
+ # PACKAGE_EXTRA_OPTS: -bt mvn # Extra 'scancentral package' options
+ # EXTRA_SC_SAST_SCAN_OPTS: # Extra 'fcli sc-sast scan start' options
+ # DO_WAIT: true # Wait for successful scan completion (implied if post-scan actions enabled)
+ # DO_POLICY_CHECK: true # Fail pipeline if security policy outcome is FAIL
+ # POLICY_CHECK_ACTION: # Customize security policy checks
+ # POLICY_CHECK_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to policy check action
+ # DO_JOB_SUMMARY: true # Generate workflow job summary
+ # JOB_SUMMARY_ACTION: # Customize job summary
+ # JOB_SUMMARY_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to job summary action
+ # DO_PR_COMMENT: true # Generate PR comments, only used on pull_request triggers
+ # PR_COMMENT_ACTION: # Customize PR comments
+ # PR_COMMENT_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to PR comment action
+ # DO_EXPORT: true # Export vulnerability data to GitHub code scanning dashboard
+ # EXPORT_ACTION: # Customize export action
+ # EXPORT_EXTRA_OPTS: --on-unsigned=ignore # Pass extra options to export action
+ # TOOL_DEFINITIONS: # URL from where to retrieve Fortify tool definitions
From b73f8de68f6b755f2bd9e9318f33372c3bd0501c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:47:22 +0700
Subject: [PATCH 26/63] Create greetings.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/greetings.yml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 .github/workflows/greetings.yml
diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml
new file mode 100644
index 0000000..4677434
--- /dev/null
+++ b/.github/workflows/greetings.yml
@@ -0,0 +1,16 @@
+name: Greetings
+
+on: [pull_request_target, issues]
+
+jobs:
+ greeting:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/first-interaction@v1
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-message: "Message that will be displayed on users' first issue"
+ pr-message: "Message that will be displayed on users' first pull request"
From 3dc30cf7dc9c5ea32251091af4698424f2bffc80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:48:11 +0700
Subject: [PATCH 27/63] Create astro.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/astro.yml | 90 +++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
create mode 100644 .github/workflows/astro.yml
diff --git a/.github/workflows/astro.yml b/.github/workflows/astro.yml
new file mode 100644
index 0000000..64dc505
--- /dev/null
+++ b/.github/workflows/astro.yml
@@ -0,0 +1,90 @@
+# Sample workflow for building and deploying an Astro site to GitHub Pages
+#
+# To get started with Astro see: https://docs.astro.build/en/getting-started/
+#
+name: Deploy Astro site to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches: ["main"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+env:
+ BUILD_PATH: "." # default value when not using subfolders
+ # BUILD_PATH: subfolder
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Detect package manager
+ id: detect-package-manager
+ run: |
+ if [ -f "${{ github.workspace }}/yarn.lock" ]; then
+ echo "manager=yarn" >> $GITHUB_OUTPUT
+ echo "command=install" >> $GITHUB_OUTPUT
+ echo "runner=yarn" >> $GITHUB_OUTPUT
+ echo "lockfile=yarn.lock" >> $GITHUB_OUTPUT
+ exit 0
+ elif [ -f "${{ github.workspace }}/package.json" ]; then
+ echo "manager=npm" >> $GITHUB_OUTPUT
+ echo "command=ci" >> $GITHUB_OUTPUT
+ echo "runner=npx --no-install" >> $GITHUB_OUTPUT
+ echo "lockfile=package-lock.json" >> $GITHUB_OUTPUT
+ exit 0
+ else
+ echo "Unable to determine package manager"
+ exit 1
+ fi
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: "20"
+ cache: ${{ steps.detect-package-manager.outputs.manager }}
+ cache-dependency-path: ${{ env.BUILD_PATH }}/${{ steps.detect-package-manager.outputs.lockfile }}
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v5
+ - name: Install dependencies
+ run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
+ working-directory: ${{ env.BUILD_PATH }}
+ - name: Build with Astro
+ run: |
+ ${{ steps.detect-package-manager.outputs.runner }} astro build \
+ --site "${{ steps.pages.outputs.origin }}" \
+ --base "${{ steps.pages.outputs.base_path }}"
+ working-directory: ${{ env.BUILD_PATH }}
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ${{ env.BUILD_PATH }}/dist
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ needs: build
+ runs-on: ubuntu-latest
+ name: Deploy
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v5
From b444f01373e605e27956e4b06ca1eee20c8225cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:48:39 +0700
Subject: [PATCH 28/63] Create gatsby.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/gatsby.yml | 98 ++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
create mode 100644 .github/workflows/gatsby.yml
diff --git a/.github/workflows/gatsby.yml b/.github/workflows/gatsby.yml
new file mode 100644
index 0000000..1c99811
--- /dev/null
+++ b/.github/workflows/gatsby.yml
@@ -0,0 +1,98 @@
+# Sample workflow for building and deploying a Gatsby site to GitHub Pages
+#
+# To get started with Gatsby see: https://www.gatsbyjs.com/docs/quick-start/
+#
+name: Deploy Gatsby site to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches: ["main"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+# Default to bash
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Detect package manager
+ id: detect-package-manager
+ run: |
+ if [ -f "${{ github.workspace }}/yarn.lock" ]; then
+ echo "manager=yarn" >> $GITHUB_OUTPUT
+ echo "command=install" >> $GITHUB_OUTPUT
+ exit 0
+ elif [ -f "${{ github.workspace }}/package.json" ]; then
+ echo "manager=npm" >> $GITHUB_OUTPUT
+ echo "command=ci" >> $GITHUB_OUTPUT
+ exit 0
+ else
+ echo "Unable to determine package manager"
+ exit 1
+ fi
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: "20"
+ cache: ${{ steps.detect-package-manager.outputs.manager }}
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v5
+ with:
+ # Automatically inject pathPrefix in your Gatsby configuration file.
+ #
+ # You may remove this line if you want to manage the configuration yourself.
+ static_site_generator: gatsby
+ - name: Restore cache
+ uses: actions/cache@v4
+ with:
+ path: |
+ public
+ .cache
+ key: ${{ runner.os }}-gatsby-build-${{ hashFiles('public') }}
+ restore-keys: |
+ ${{ runner.os }}-gatsby-build-
+ - name: Install dependencies
+ run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
+ - name: Build with Gatsby
+ env:
+ PREFIX_PATHS: 'true'
+ run: ${{ steps.detect-package-manager.outputs.manager }} run build
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v5
+
From 4943a9e0a731987d914835a09964726ec87af8d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:49:46 +0700
Subject: [PATCH 29/63] Create aws.yml
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
.github/workflows/aws.yml | 94 +++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
create mode 100644 .github/workflows/aws.yml
diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml
new file mode 100644
index 0000000..a8219c4
--- /dev/null
+++ b/.github/workflows/aws.yml
@@ -0,0 +1,94 @@
+# This workflow will build and push a new container image to Amazon ECR,
+# and then will deploy a new task definition to Amazon ECS, when there is a push to the "main" branch.
+#
+# To use this workflow, you will need to complete the following set-up steps:
+#
+# 1. Create an ECR repository to store your images.
+# For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`.
+# Replace the value of the `ECR_REPOSITORY` environment variable in the workflow below with your repository's name.
+# Replace the value of the `AWS_REGION` environment variable in the workflow below with your repository's region.
+#
+# 2. Create an ECS task definition, an ECS cluster, and an ECS service.
+# For example, follow the Getting Started guide on the ECS console:
+# https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun
+# Replace the value of the `ECS_SERVICE` environment variable in the workflow below with the name you set for the Amazon ECS service.
+# Replace the value of the `ECS_CLUSTER` environment variable in the workflow below with the name you set for the cluster.
+#
+# 3. Store your ECS task definition as a JSON file in your repository.
+# The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`.
+# Replace the value of the `ECS_TASK_DEFINITION` environment variable in the workflow below with the path to the JSON file.
+# Replace the value of the `CONTAINER_NAME` environment variable in the workflow below with the name of the container
+# in the `containerDefinitions` section of the task definition.
+#
+# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
+# See the documentation for each action used below for the recommended IAM policies for this IAM user,
+# and best practices on handling the access key credentials.
+
+name: Deploy to Amazon ECS
+
+on:
+ push:
+ branches: [ "main" ]
+
+env:
+ AWS_REGION: MY_AWS_REGION # set this to your preferred AWS region, e.g. us-west-1
+ ECR_REPOSITORY: MY_ECR_REPOSITORY # set this to your Amazon ECR repository name
+ ECS_SERVICE: MY_ECS_SERVICE # set this to your Amazon ECS service name
+ ECS_CLUSTER: MY_ECS_CLUSTER # set this to your Amazon ECS cluster name
+ ECS_TASK_DEFINITION: MY_ECS_TASK_DEFINITION # set this to the path to your Amazon ECS task definition
+ # file, e.g. .aws/task-definition.json
+ CONTAINER_NAME: MY_CONTAINER_NAME # set this to the name of the container in the
+ # containerDefinitions section of your task definition
+
+permissions:
+ contents: read
+
+jobs:
+ deploy:
+ name: Deploy
+ runs-on: ubuntu-latest
+ environment: production
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v1
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: ${{ env.AWS_REGION }}
+
+ - name: Login to Amazon ECR
+ id: login-ecr
+ uses: aws-actions/amazon-ecr-login@v1
+
+ - name: Build, tag, and push image to Amazon ECR
+ id: build-image
+ env:
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+ IMAGE_TAG: ${{ github.sha }}
+ run: |
+ # Build a docker container and
+ # push it to ECR so that it can
+ # be deployed to ECS.
+ docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
+ docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
+ echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
+
+ - name: Fill in the new image ID in the Amazon ECS task definition
+ id: task-def
+ uses: aws-actions/amazon-ecs-render-task-definition@v1
+ with:
+ task-definition: ${{ env.ECS_TASK_DEFINITION }}
+ container-name: ${{ env.CONTAINER_NAME }}
+ image: ${{ steps.build-image.outputs.image }}
+
+ - name: Deploy Amazon ECS task definition
+ uses: aws-actions/amazon-ecs-deploy-task-definition@v1
+ with:
+ task-definition: ${{ steps.task-def.outputs.task-definition }}
+ service: ${{ env.ECS_SERVICE }}
+ cluster: ${{ env.ECS_CLUSTER }}
+ wait-for-service-stability: true
From d0d4a9cc46225c5f76d89eac88c32ff9afe796d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?=
<252359928+Huynhthuongg@users.noreply.github.com>
Date: Thu, 4 Jun 2026 20:19:58 +0700
Subject: [PATCH 30/63] Fix static app smoke checks and chat escaping
---
.github/workflows/hadolint.yml | 2 +-
.github/workflows/static.yml | 3 +++
README.md | 24 ++++++++++++++------
index.html | 2 +-
scripts/smoke-test-static.mjs | 41 ++++++++++++++++++++++++++++++++++
5 files changed, 63 insertions(+), 9 deletions(-)
create mode 100644 scripts/smoke-test-static.mjs
diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml
index dc73566..a264df3 100644
--- a/.github/workflows/hadolint.yml
+++ b/.github/workflows/hadolint.yml
@@ -2,7 +2,7 @@
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
-# hadoint is a Dockerfile linter written in Haskell
+# hadolint is a Dockerfile linter written in Haskell
# that helps you build best practice Docker images.
# More details at https://github.com/hadolint/hadolint
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
index 09631a2..8e55f57 100644
--- a/.github/workflows/static.yml
+++ b/.github/workflows/static.yml
@@ -22,6 +22,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
+ - name: Smoke test static app
+ run: node scripts/smoke-test-static.mjs
+
- name: Prepare static site
shell: bash
run: |
diff --git a/README.md b/README.md
index 91f1766..704c5d9 100644
--- a/README.md
+++ b/README.md
@@ -55,6 +55,7 @@
RKIX3/
├─ index.html # Single-file AI Studio UI
├─ README.md # Trang giới thiệu chuyên nghiệp trên GitHub
+├─ scripts/smoke-test-static.mjs # Smoke test HTML/JS trước khi deploy
├─ 1780136894650-Photoroom.png # Logo chính
└─ .github/workflows/static.yml # Build _site + deploy GitHub Pages
```
@@ -66,17 +67,26 @@ python3 -m http.server 4173
# mở http://127.0.0.1:4173
```
+## 🧪 Kiểm thử
+
+```bash
+node scripts/smoke-test-static.mjs
+```
+
+Smoke test sẽ kiểm tra cấu trúc route chính, sự tồn tại của chat input/send button, cú pháp JavaScript inline và guard chống render raw user message vào `innerHTML`.
+
## 🚀 Deploy GitHub Pages
-Workflow `.github/workflows/static.yml` sẽ:
+Workflow chính `.github/workflows/static.yml` sẽ:
1. Checkout source.
-2. Setup GitHub Pages.
-3. Tạo `_site` chứa `index.html`, ảnh và file đánh dấu static site.
-4. Upload artifact Pages.
-5. Deploy bằng `actions/deploy-pages`.
+2. Chạy smoke test static app bằng `node scripts/smoke-test-static.mjs`.
+3. Setup GitHub Pages.
+4. Tạo `_site` chứa `index.html`, ảnh và file đánh dấu static site.
+5. Upload artifact Pages.
+6. Deploy bằng `actions/deploy-pages`.
-> Nếu GitHub vẫn báo lỗi deploy, hãy vào **Settings → Pages → Build and deployment** và chọn **Source: GitHub Actions** cho repository.
+> Nếu GitHub vẫn báo lỗi deploy, hãy vào **Settings → Pages → Build and deployment** và chọn **Source: GitHub Actions** cho repository. Các workflow mẫu khác trong `.github/workflows/` chỉ nên được bật khi dự án thật sự dùng stack tương ứng.
## 🏅 Huy hiệu dự án
@@ -121,7 +131,7 @@ Workflow `.github/workflows/static.yml` sẽ:
## ✅ Ba xung đột đã được chốt
-- **Workflow Pages**: chỉ giữ một pipeline static ở `.github/workflows/static.yml`, dùng `_site` làm artifact triển khai.
+- **Workflow Pages**: `.github/workflows/static.yml` là pipeline deploy chính, chạy smoke test rồi dùng `_site` làm artifact triển khai.
- **Tài liệu GitHub**: README là trang giới thiệu chính thức của RKIX3, không còn nội dung cũ trùng lặp.
- **Web app RKIX3**: `index.html` tiếp tục là nguồn giao diện single-file được workflow copy trực tiếp khi deploy.
diff --git a/index.html b/index.html
index 12bb580..af17760 100644
--- a/index.html
+++ b/index.html
@@ -103,7 +103,7 @@
function taskCard(t){return `
${t.id}${t.priority}
${t.title}
${t.project}
`}
function renderHome(){$('#home').innerHTML=`
Developer Workspace Platform
Build faster with AI, projects, code, docs, and deploys in one command deck.
RKIX3 combines an AI workspace, project roadmap, code studio, build center, library hub, integrations, and profile controls in a sleek dark-first developer UI.
`).join('')}
function renderWorkspace(){const cols=[['todo','Todo'],['doing','In progress'],['review','Review'],['done','Done']];$('#workspace').innerHTML=`${card(`
Project & Task Management
Kanban board, project list, and roadmap planning view.