@@ -55,13 +55,188 @@ the components in this repository:
5555 has completed the current task correctly,
5656 and is ready to advance to the next one.
5757
58- ### Creating a GitHub Action
58+ ### Creating the GitHub Action
5959
60- TODO
60+ * (for an example of a working action,
61+ see [ ` courses/cpp/ctf-segv ` ] ( courses/cpp/ctf-segv ) ).*
62+
63+ Course actions consist of an ` action.yml ` file,
64+ and docker image built from the base image
65+ [ ` codeql-learninglab-check ` ] ( codeql-learninglab-check ) .
66+
67+ The base image expects course images built on-top of it
68+ to add the file ` /home/codeql/config/config.json ` ,
69+ which details the configuration for the course.
70+
71+ The file should look something like this:
72+
73+ <!-- TODO : change snapshotPath to databasePath -->
74+
75+ ``` json
76+ {
77+ "snapshotPath" : " <path-to-database-directory>" ,
78+ "locationPaths" : " https://github.com/<owner>/<repo>/blob/<sha>{path}#L{line-start}-L{line-end}" ,
79+ "expectedResults" : {
80+ "step-01.ql" : " step-01.csv" ,
81+ "step-02.ql" : " step-02.csv" ,
82+ "step-03.ql" : " step-03.csv" ,
83+ }
84+ }
85+ ```
86+
87+ In addition to the ` config.json ` file above,
88+ a course image needs to also add the snapshot directory
89+ that queries should be run against,
90+ and csv files for the expected results.
91+
92+ * ` snapshotPath ` should be a directory in the docker image,
93+ relative to the ` config.json ` file,
94+ that contains the extracted CodeQL database that queries will be run against.
95+ If you are using the template below,
96+ it will usually be the name of the only top-level directory
97+ from inside the database zip file.
98+ * ` locationPaths ` is an optional template string that can be used to enable
99+ source links in comments, when participants have written queries that output
100+ unexpected rows, or are missing results.
101+ ` <owner> ` , ` <repo> ` and ` <sha> ` should be replace as appropriate,
102+ the placeholders ` {path} ` , ` {line-start} ` and ` {line-end} ` are used by the
103+ checker, and should be left as-is.
104+ * ` expectedResults ` is an object that maps expected query filenames to a csv
105+ file detailing what the expected results for this query should be.
106+ Only the first expression for each row in the query results is checked.
107+
108+ To simplify course creation,
109+ we recommend structuring your course folder like so:
110+
111+ ```
112+ ├── answers <─── Model Answers
113+ │ ├── step-01.ql <─┬─ Answers with expected paths
114+ │ ├── step-02.ql <─┤ (relative to answers/)
115+ │ └── ... <─┘ as specified in config.json
116+ ├── image
117+ │ ├── config
118+ │ │ ├── config.json <─── Main course configuration
119+ │ │ ├── step-01.csv
120+ │ │ ├── step-02.csv
121+ │ │ └── ...
122+ │ └── Dockerfile
123+ └── action.yml
124+ ```
125+
126+ * (For your convinience,
127+ we've created a template course that uses this file-structure
128+ in the folder [ ` courses/template ` ] ( courses/template ) .
129+ You can simply copy the folder,
130+ and follow the instructions in the template README for what things to replace).*
131+
132+ ` action.yml ` should look something like this:
133+
134+ ``` yml
135+ name : ' Check queries'
136+ description : ' Check that the queries that have been pushed (as part of the lesson) produce the correct results'
137+ author : ' GitHub <opensource+codeql-learninglab-actions@github.com>'
138+ runs :
139+ using : ' docker'
140+ image : ' docker.pkg.github.com/<owner>/<repo>/<package>'
141+ branding :
142+ icon : ' check-circle'
143+ color : ' purple'
144+ ` ` `
145+
146+ and ` Dockerfile` should look something like:
147+
148+ ` ` ` Dockerfile
149+ FROM docker.pkg.github.com/github/codeql-learninglab-actions/codeql-learninglab-check:<version>
150+
151+ ## Add course config
152+ COPY --chown=codeql:codeql config /home/codeql/config
153+ WORKDIR /home/codeql/config
154+ # Download, unzip and then delete the zip file in one step to reduce image size
155+ RUN wget --quiet <url-for-snapshot-zip> -O snapshot.zip && unzip -qq snapshot.zip && rm -rf snapshot.zip
156+ ` ` `
157+
158+ Note that we download, unzip and then delete the zip file of the snapshot
159+ in a single step here.
160+ This helps us reduce the size of the image,
161+ as separate steps would result in intermediate image layers that are built
162+ on-top of one another.
163+
164+ # ### Testing the action
165+
166+ You can test the action either locally or on GitHub actions.
167+
168+ **Locally:**
169+
170+ To test a course locally,
171+ from the course directory,
172+ run either of these scripts :
173+
174+ * [`scripts/test-course-actual.sh`](scripts/test-course-only.sh):
175+ which will download and use the specific version of `codeql-learninglab-check`
176+ that is specified in `Dockerfile`
177+ * [`scripts/test-course.sh`](scripts/test-course.sh):
178+ Which will also build the `codeql-learninglab-check` image locally,
179+ and tag it with the expected base image of the course,
180+ allowing you to test how changes to the `codeql-learninglab-check`
181+ affect this specific course,
182+ without publishing any new images.
183+
184+ **In GitHub Actions:**
185+
186+ If adding a course to this repository,
187+ extend the workflow file [`.github/workflows/ci.yml`](.github/workflows/ci.yml)
188+ to include your new course.
189+ Any subsequent pushes to any branch should trigger an Action to run
190+ that will succeed only when all the expected queries produce the right results.
191+
192+ If you are creating a course in another repository,
193+ you can copy the [`scripts/test-course-only.sh`](scripts/test-course-only.sh)
194+ and [`scripts/test-course.sh`](scripts/test-course.sh) files
195+ into that repository,
196+ and add a similar workflow file to the one mentioned above.
197+
198+ # ### Adding new queries & calculating the contents for the CSV files
199+
200+ When testing the action ([as detailed above](#testing-the-action)),
201+ when a query that is run produces unexpected results,
202+ the actual results that it produces are printed out in the console.
203+ You can then store this output as the relevant CSV file.
204+
205+ So the workflow for adding a new query and CSV file looks like :
206+
207+ * add the query (`.ql` file) to `answers/`
208+ * add the query to `config.json`
209+ (remember that the path should be relative to `answers/`)
210+ * Test the action (whichever method you prefer)
211+ * Copy the CSV output to the appropriate file in `image/config/`
212+ * Re-test the action to ensure it marks the query
213+ as producing the correct results
214+
215+ # ### Publishing your action
216+
217+ The main thing you need to do here is publish your Docker image somewhere,
218+ and ensure that `action.yml` referrs to a tag that is downloadable.
219+
220+ We recommend setting up a GitHub Actions Workflow
221+ to automatically publish your docker image
222+ with the version `latest` to `docker.pkg.github.com`
223+ whenever you get a new push to `master`.
224+ This is what we do in
225+ [`.github/workflows/publish.yml`](.github/workflows/publish.yml).
226+
227+ Any courses that are added to this repository
228+ need to be published in this manner.
61229
62230# ## Contributing your GitHub Action to this repository
63231
64- TODO
232+ If you want to add a course to this repository,
233+ ensure that :
234+
235+ * You're creating the course in the `courses/` folder,
236+ under the appropriate language sub-folder for the project.
237+ * You update both [`.github/workflows/ci.yml`](.github/workflows/ci.yml) and
238+ [`.github/workflows/publish.yml`](.github/workflows/publish.yml) to include
239+ testing and image publishing for your course.
65240
66241# # Example Courses
67242
70245Feel free to add your own courses to this list!
71246See [CONTRIBUTING.md](CONTRIBUTING.md).
72247
248+ # # Contributing
249+
250+ We welcome contributions,
251+ both for new courses,
252+ and improvements to existing courses ot the
253+ [`codeql-learninglab-check`](codeql-learninglab-check) docker image.
254+
255+ # ## Releasing new versions or updating dependencies
256+
257+ See : [Updating and Releasing](CONTRIBUTING.md#updating-and-releasing)
258+
73259# # License
74260
75261The code in this repository is licensed under MIT (see [LICENSE.md](LICENSE.md)),
0 commit comments