github/codeql-learninglab-actions
GitHub: github/codeql-learninglab-actions
为 GitHub Learning Lab 的 CodeQL 课程提供 Docker 镜像和 Actions,用于自动验证学员提交的代码查询是否产生正确结果。
Stars: 36 | Forks: 18
# Learning Lab CodeQL 课程 Actions
[](https://github.com/github/codeql-learninglab-actions/actions?query=workflow%3ACI)
[](https://github.com/github/codeql-learninglab-actions/actions?query=workflow%3A%22Build+and+publish+docker+images+to+registry%22)
本代码库提供了 Docker 镜像和 GitHub Actions,
供 [Learning Lab](https://lab.github.com/) 上的
CodeQL 课程使用。
这些 actions 允许你指定工作流,
通过在已知的 CodeQL database 上运行参与者编写的查询,
并检查结果是否符合预期,
来验证课程参与者的查询是否正确。
无论结果如何,
该 action 都会在推送的 commit 上发布评论,
以添加查询。
当用户的结果不正确时,
评论将包含有关哪些结果缺失以及哪些是多余的详细信息,
并在可能的情况下提供指向 GitHub 上源代码行的链接:
**截图:**

**目录**
- [创建你自己的课程](#creating-your-own-course)
- [创建查询检查 Action](#creating-the-query-checking-action)
- [测试 action](#testing-the-action)
- [添加新查询并计算 CSV 文件的内容](#adding-new-queries--calculating-the-contents-for-the-csv-files)
- [发布你的 action](#publishing-your-action)
- [将你的 GitHub Action 贡献到此代码库](#contributing-your-github-action-to-this-repository)
- [创建 Learning Lab 课程](#creating-the-learning-lab-course)
- [示例课程](#example-courses)
- [贡献](#contributing)
- [发布新版本或更新依赖](#releasing-new-versions-or-updating-dependencies)
- [许可证](#license)
## 创建你自己的课程
任何使用此代码库中组件的 CodeQL Learning Lab 课程都包含两个主要部分:
* [**查询检查 Action:**](#creating-the-query-checking-action)
每个课程都有自己的 GitHub Action,旨在用于课程参与者向其 repo 推送新 commit 时运行的工作流。
该 action 会检查此次 push 中更改了哪些查询,
并运行它识别为课程一部分的查询
(基于文件名)。
运行查询后,
该 action 会根据预期结果的 CSV 文件检查结果。
然后它会在该 commit 上发布评论,
详细说明每个查询是否产生了正确的结果。
如果没有,
它将包含有关哪些结果缺失以及哪些结果出乎意料的详细信息。
这些 actions 使用 Docker 打包,
并通过
[GitHub Packages](https://github.com/features/packages) 提供。
* [**Learning Lab 课程:**](#creating-the-learning-lab-course)
这就是课程本身。
它创建参与者将要用于其课程的初始 repo,
以 GitHub issues 的形式发布说明,
并监听 GitHub action 发布的评论,以了解用户
何时正确完成了当前任务,
并准备好进入下一个任务。
### 创建查询检查 Action
*(有关有效的 action 示例,
请参见 [`courses/cpp/ctf-segv`](courses/cpp/ctf-segv))。*
课程 actions 由一个 `action.yml` 文件
以及基于基础镜像
[`codeql-learninglab-check`](codeql-learninglab-check) 构建的 docker image 组成。
基础镜像要求基于它构建的课程镜像
添加 `/home/codeql/config/config.json` 文件,
该文件详细说明了课程的配置。
该文件应如下所示:
```
{
"databasePath": "",
"locationPaths": "https://github.com///blob/{path}#L{line-start}-L{line-end}",
"expectedResults": {
"step-01.ql": "step-01.csv",
"step-02.ql": "step-02.csv",
"step-03.ql": false,
}
}
```
除了上述 `config.json` 文件外,
课程镜像还需要添加用于运行查询的快照目录
以及用于预期结果的 csv 文件。
* `databasePath` 应为 docker image 中的一个目录,
相对于 `config.json` 文件,
包含用于运行查询的已解压 CodeQL database。
如果你使用下面的模板,
它通常是 database zip 文件中唯一一个顶级目录的名称。
* `locationPaths` 是一个可选的模板字符串,可用于在评论中启用源链接,特别是当参与者编写的查询输出了意外的行或缺少结果时。
``、`` 和 `` 应视情况进行替换,
占位符 `{path}`、`{line-start}` 和 `{line-end}` 会被检查器使用,
应保持原样。
* `expectedResults` 是一个对象,它将预期的查询文件名映射到一个 csv 文件,该文件详细说明了此查询的预期结果。
仅检查查询结果中每行的第一个表达式。
如果使用 `false` 代替 CSV 文件名,
则检查器将假定该 CSV 文件尚未生成,
并会为你打印出查询的结果输出,以便你将其复制到新文件中。
为简化课程创建,
我们建议按如下方式构建你的课程文件夹:
```
├── answers <─── Model Answers
│ ├── qlpack.yml
│ ├── step-01.ql <─┬─ Answers with expected paths
│ ├── step-02.ql <─┤ (relative to answers/)
│ └── ... <─┘ as specified in config.json
├── image
│ ├── config
│ │ ├── config.json <─── Main course configuration
│ │ ├── step-01.csv
│ │ ├── step-02.csv
│ │ └── ...
│ └── Dockerfile
└── action.yml
```
*(为了方便起见,
我们在 [`templates/action`](templates/action) 文件夹中创建了一个使用此文件结构的模板课程。
你可以直接复制该文件夹,
并按照模板 README 中的说明替换相应内容)。*
`action.yml` 应如下所示:
```
name: 'Check queries'
description: 'Check that the queries that have been pushed (as part of the lesson) produce the correct results'
author: 'GitHub '
runs:
using: 'docker'
image: 'docker://docker.pkg.github.com///'
branding:
icon: 'check-circle'
color: 'purple'
```
`Dockerfile` 应如下所示:
```
FROM docker.pkg.github.com/github/codeql-learninglab-actions/codeql-learninglab-check:
## 添加 course config
COPY --chown=codeql:codeql config /home/codeql/config
WORKDIR /home/codeql/config
# 一步完成下载、解压并删除 zip 文件以减小 image size
RUN wget --quiet -O database.zip && unzip -qq database.zip && rm -rf database.zip
```
请注意,我们在此处通过单个步骤下载、解压并删除了快照的 zip 文件。
这有助于减小镜像体积,
因为单独的步骤会导致生成相互叠加的中间镜像层。
#### 测试 action
你可以在本地或 GitHub actions 上测试该 action。
**本地:**
要在本地测试课程,
请在课程目录中运行以下脚本之一:
* [`scripts/test-course-actual.sh`](scripts/test-course-actual.sh):
将下载并使用 `Dockerfile` 中指定的特定版本的 `codeql-learninglab-check`
* [`scripts/test-course-latest.sh`](scripts/test-course-latest.sh):
还会在本地构建 `codeql-learninglab-check` 镜像,
并使用预期的课程基础镜像对其进行标记,
让你无需发布任何新镜像即可测试对 `codeql-learninglab-check` 的更改如何影响此特定课程。
这两个脚本都将一个 **可选的** 正则表达式字符串作为参数。
如果传递了此字符串,则只会运行名称与正则表达式匹配的查询。
否则,将运行所有查询。
**在 GitHub Actions 中:**
如果将课程添加到本代码库,
请扩展工作流文件 [`.github/workflows/ci.yml`](.github/workflows/ci.yml)
以包含你的新课程。
随后对任何分支的任何 push 都应触发 Action 运行,
且仅当所有预期查询都产生正确的结果时,该运行才会成功。
如果你要在其他代码库中创建课程,
可以将 [`scripts/test-course-actual.sh`](scripts/test-course-actual.sh)
和 [`scripts/test-course-latest.sh`](scripts/test-course-latest.sh) 文件复制到该代码库中,
并添加与上述类似的工作流文件。
#### 添加新查询并计算 CSV 文件的内容
测试 action 时([如上所述](#testing-the-action)),
当运行的查询产生了意外的结果,
或者在 `config.yml` 中被指定为 `false` 而不是列出 CSV 文件名时,
它产生的实际结果将打印在控制台中。
然后,你可以将此输出存储为相应的 CSV 文件。
因此,添加新查询和 CSV 文件的工作流程如下所示:
* 将查询(`.ql` 文件)添加到 `answers/` 中。
* 将查询添加到 `config.json` 中的 `expectedResults` 属性中,
起始值为 `false`。
* 测试 action(根据你喜欢的方法)。
* 将 CSV 输出复制到 `image/config/` 中的相应文件中。
* 重新测试 action,以确保它将查询标记为产生了正确的结果。
#### 发布你的 action
在这里你需要做的主要事情是将你的 Docker 镜像发布到某处,
并确保 `action.yml` 引用了一个可下载的 tag。
我们建议设置一个 GitHub Actions Workflow,
以便在每次向 `master` 推送新内容时,
自动将你的 docker image 连同 `latest` 版本发布到 `docker.pkg.github.com`。
这就是我们在
[`.github/workflows/publish.yml`](.github/workflows/publish.yml) 中所做的。
添加到此代码库的任何课程
都需要以这种方式发布。
### 将你的 GitHub Action 贡献到此代码库
如果你想将课程添加到此代码库,
请确保:
* 你正在 `courses/` 文件夹中创建课程,
位于项目对应的语言子文件夹下。
* 你同时更新了 [`.github/workflows/ci.yml`](.github/workflows/ci.yml) 和
[`.github/workflows/publish.yml`](.github/workflows/publish.yml),以包含课程的
测试和镜像发布。
### 创建 Learning Lab 课程
如果你之前没有创建过 Learning Lab 课程,
建议你学习有关
[创建课程的课程](https://lab.github.com/githubtraining/write-a-learning-lab-course)!
作为任何 learning-lab 课程的一部分,需要创建核心 repo:
* **课程 repo:**
所有的课程配置、说明等……
* **模板 repo:**
填充代表课程参与者创建的 repo 的初始内容。
(所有课程都是针对其各自的 repo 进行的)
我们创建了两个模板目录,
你可以将它们用作自己 CodeQL Learning Lab 课程的起点:
* [`templates/learninglab/course`](templates/learninglab/course)
* [`templates/learninglab/course-template`](templates/learninglab/course-template)
只需将这些模板的内容复制到它们各自的 repo 中,
并按照[模板说明](templates/learninglab)开始操作。
*(请记住,你需要为你的 Learning Lab 课程创建 2 个独立的 repo,
它们不能是现有 repo 中的目录)。*
## 示例课程
* [GitHub Security Lab CTF 1: SEGV hunt](courses/cpp/ctf-segv)
欢迎将你自己的课程添加到此列表!
请参见 [CONTRIBUTING.md](CONTRIBUTING.md)。
### 发布新版本或更新依赖
请参见:[更新与发布](CONTRIBUTING.md#updating-and-releasing)
## 许可证
本代码库中的代码采用 MIT 许可(请参见 [LICENSE.md](LICENSE.md))。
但是,由于它使用了 CodeQL CLI,
只要你的使用涉及 CodeQL CLI,
你也必须遵守
[GitHub CodeQL 条款和条件](https://securitylab.github.com/tools/codeql/license)。
特别是,
根据[条款和条件](https://securitylab.github.com/tools/codeql/license),不允许使用这些 docker 镜像或 actions 通过 CLI 在 CI/CD 中创建 CodeQL database:
标签:CodeQL, Cutter, GitHub Actions, LNA, 云安全监控, 安全评估工具, 教学工具, 自动化攻击, 自动笔记, 请求拦截, 静态分析