-
-
- 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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 8af84b424a9b13dc29308423cd2268bd8a208afb 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:45:10 +0700
Subject: [PATCH 30/35] Optimize RKIX3 mobile web interface
---
.github/workflows/hadolint.yml | 2 +-
.github/workflows/static.yml | 3 +
README.md | 26 ++-
index.html | 322 +++++++++++++++++++++++----------
scripts/smoke-test-static.mjs | 41 +++++
5 files changed, 293 insertions(+), 101 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..66293ea 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,13 +131,13 @@ 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.
## 🗺️ Roadmap
-- [x] Giao diện RKIX3 Studio single-file.
+- [x] Giao diện RKIX3 Studio single-file, ưu tiên mobile web với shell giống app gốc.
- [x] Command Center cho CLI/mobile workflow.
- [x] Demo Offline để sinh blueprint khi chưa có API key.
- [x] GitHub Pages static deploy workflow.
diff --git a/index.html b/index.html
index 12bb580..3f12d05 100644
--- a/index.html
+++ b/index.html
@@ -1,118 +1,256 @@
-
+
- RKIX3 — Developer Workspace Platform
-
+ RKIX3 — Mobile AI Workspace
+
-
-
RKIX3 Command Layer
Dashboard
main · healthy
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Gần đây
+
+
Mobile AI shell
+
Build nhanh giao diện
+
+
+
+
+
diff --git a/scripts/smoke-test-static.mjs b/scripts/smoke-test-static.mjs
new file mode 100644
index 0000000..6b82bd4
--- /dev/null
+++ b/scripts/smoke-test-static.mjs
@@ -0,0 +1,41 @@
+import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
+import { tmpdir } from 'node:os';
+import { join } from 'node:path';
+import { spawnSync } from 'node:child_process';
+
+const html = readFileSync('index.html', 'utf8');
+const failures = [];
+
+function assert(condition, message) {
+ if (!condition) failures.push(message);
+}
+
+assert(html.includes(''), 'index.html must declare an HTML doctype.');
+assert(html.includes('${m.text}'), 'Chat messages must not render raw user text into innerHTML.');
+
+const scripts = [...html.matchAll(/
diff --git a/scripts/smoke-test-static.mjs b/scripts/smoke-test-static.mjs
index 6b82bd4..8a14429 100644
--- a/scripts/smoke-test-static.mjs
+++ b/scripts/smoke-test-static.mjs
@@ -13,6 +13,10 @@ function assert(condition, message) {
assert(html.includes(''), 'index.html must declare an HTML doctype.');
assert(html.includes('
Date: Thu, 4 Jun 2026 21:04:02 +0700
Subject: [PATCH 32/35] Update index.html
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com>
---
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/index.html b/index.html
index a81cb46..245ecd2 100644
--- a/index.html
+++ b/index.html
@@ -247,7 +247,7 @@
const quick=[['code','Lập trình','Viết code, debug và tối ưu',icons.code],['workspace','Build','Xây dựng sản phẩm nhanh chóng',icons.cube],['profile','Tự động hoá','Tự động hoá quy trình và công việc',icons.gear],['ai','AI thông minh','Hỗ trợ bởi AI thế hệ mới',icons.bot]];
const entities={messages:[{role:'agent',text:'RKIX3 đã sẵn sàng. Hỏi bất kỳ điều gì để bắt đầu build.'}],projects:[['Nebula Console','Đang build','76%'],['AgentOps CLI','Lên kế hoạch','42%'],['Docs Pulse','Review','88%']]};
function navHTML(){return routes.map(r=>``).join('')}
-function drawerHTML(){return [['ai','Đoạn chat mới',icons.code],['home','Tìm kiếm đoạn chat',icons.menu],['code','Thư viện',icons.library],['workspace','Dự án',icons.folder],['profile','Ứng dụng',icons.apps]].map(r=>``).join('')}
+function drawerHTML(){return [['home','Đoạn chat mới',icons.code],['home','Tìm kiếm đoạn chat',icons.menu],['code','Thư viện',icons.library],['workspace','Dự án',icons.folder],['profile','Ứng dụng',icons.apps]].map(r=>``).join('')}
function renderChat(){$('#chatLog').innerHTML=entities.messages.map(m=>`
${esc(m.text)}
`).join('')}
function renderHome(){$('#home').innerHTML=`
Chúng ta nên bắt đầu từ đâu?
Lập trình · Code · Build · Tự động hoá trên một giao diện mobile gọn, sáng và nhanh.
${quick.map(q=>``).join('')}
`;renderChat()}
function renderAI(){$('#ai').innerHTML=`
AI thông minh
Online
Tập trung cho mobile trước: prompt nhanh, nút mỏng, icon xanh và layout giống app RKIX3 ban đầu.