Skip to main content
Version: Next (unreleased)

All Inputs

A fully annotated workflow showing every available input. Inputs that are optional are commented out with an explanation of when they would be used.

Copy this file to .github/workflows/grill-my-code.yml in the student repository and remove or adjust inputs as needed.

name: GrillMyCode

on:
push:
branches: ["main", "master"]
workflow_dispatch:

# A new push cancels any run still in progress for the same branch,
# so only the latest commit is ever assessed (see FAQ).
# Do not modify this setting unless you have a compelling reason to.
concurrency:
group: grillmycode-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
generate-questions:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write # required to create the gmc-assessments release and PDF asset
issues: write # required to create the assessment issue
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # full history required for diff resolution

- uses: NSCC-ITC-Assessment/GrillMyCode@v1
with:
# ── Authentication ────────────────────────────────────────────────

# GitHub token used for API access — creating the assessment issue and
# release, and reading repository metadata. It is NOT used to generate
# questions; see api_key below. The built-in token is sufficient.
github_token: ${{ secrets.GITHUB_TOKEN }}

# API key for the AI provider. REQUIRED — the action fails immediately
# without it. Create a key at https://openrouter.ai/keys and store it as an
# organisation-level secret so every student repository inherits it.
api_key: ${{ secrets.OPENROUTER_API_KEY }}

# ── AI Provider ───────────────────────────────────────────────────

# Provider to use for question generation.
# Supported values: openrouter (the default — may be omitted)
# ai_provider: "openrouter"

# Model identifier, in OpenRouter's provider/model-name format.
# See https://openrouter.ai/models for the full catalogue and pricing.
ai_model: "google/gemini-3.5-flash-lite"

# Total number of attempts (initial + retries) when calling the AI provider.
# Retries are triggered by 429 (rate limit), 500, 502, 503, 504, and network
# failures. A 429 with a Retry-After header has that delay honoured (max 30s).
# Values below 1 are clamped to 1.
# ai_retry_max_attempts: "5"

# Controls the randomness of the AI's output (0.0 = fully deterministic,
# 1.0 = most random). Lower values produce more consistent questions;
# higher values produce more varied output. Most users should leave this
# at the default.
# ai_temperature: "0.5"

# ── Question generation ───────────────────────────────────────────

# Number of comprehension questions to generate. Minimum 1, maximum 50.
num_questions: "20"

# When true, answers are shown to the student immediately after each
# question — this defeats the purpose of the assessment. Leave false
# in almost all cases. The instructor repository always includes
# answers regardless of this setting.
# include_answers: "false"

# Assignment-specific instructions for the AI. Injected at the end of
# the system prompt and takes precedence over default behaviour.
# Supports multi-line YAML strings.
instructor_context: |
Assignment 3 — Python loops.
Prioritize execution flow questions that trace what a loop
produces for a given input, conceptual questions about loop
design, and at least one error identification question about
off-by-one errors.

# Comma-separated file glob(s) whose contents are read from the repo
# and injected into the prompt as assignment context (before
# instructor_context). Useful for README files, assignment briefs, or
# coding style guides. Leave empty (default) to disable.
# Supported file types: plain text / source files (UTF-8), PDF (.pdf,
# text layer only), and Microsoft Word (.doc/.docx, text content only).
# assignment_context: "README.md, assignment.pdf, marking/rubric.docx"

# Maximum total characters read from all assignment_context files
# combined. Increase if your assignment brief is large; decrease to
# limit token usage. Values below 1 are clamped to 1.
# assignment_context_max_chars: "20000"

# ── File filtering ────────────────────────────────────────────────

# Allow specific files through the default exclude list.
# Use an exact default pattern (e.g. **/*.md) to re-include all files
# of that type, or a specific path (e.g. README.md) to allow only
# that file while the pattern still excludes everything else.
# exclude_pattern_overrides: 'README.md'

# Comma-separated glob patterns for extra files to exclude on top of
# the auto-detected stack patterns (lock files, build artefacts, etc.
# for your language/framework are excluded automatically).
# additional_exclude_patterns: 'tests/**,docs/**'

# ── Instructor repository ─────────────────────────────────────────

# Classroom 50 assignment repositories only — not available elsewhere.
# PAT with repo scope and permission to create repositories in the
# same organisation as the student repositories. When provided, the
# action writes a private instructor-only report (questions AND answers)
# to a repository named {assignment-name}-grillmycode-instructor in the same org.
# The repository is auto-created on first run if it does not exist.
# The assignment name and student folder are read from the Classroom 50
# repo name (<classroom>-<assignment>-<username>) and its direct
# collaborators; any other repo skips instructor delivery with a warning.
# Leave empty (default) to disable instructor repository delivery.
# instructor_repo_token: ${{ secrets.INSTRUCTOR_REPO_TOKEN }}

# ── Run reporting ─────────────────────────────────────────────────

# When true, a run that finds nothing to assess fails instead of
# succeeding. A run ends with nothing to assess when the commit range
# is empty, or when every changed file is removed by the exclude
# patterns; either way the job summary explains which and what to
# check. Left "false" (default) because both cases occur normally the
# moment an assignment is accepted, so failing by default would show a
# red run on every student repository at creation. Set to "true" once
# students have started work.
# fail_on_empty_assessment: "false"

# ── Comment stripping ─────────────────────────────────────────────

# When false (default), inline and block comments are stripped from
# the code before sending it to the AI. Set to "true" to preserve them.
keep_comments: "false"

# ── Diff resolution ───────────────────────────────────────────────

# Include the initial commit's eligible files in the diff (default: false).
# Set to "true" to use the empty tree as the base instead,
# which includes the initial commit's eligible files in the diff.
# Required for Classroom 50 empty-repository assignments
# (--empty-repo): those repos start with no commits at all, so the
# first commit is the student's own work, not starter code.
# include_initial_commit: "false"

# Comma-separated list of author names or email substrings.
# A leading run of commits whose author matches any entry is skipped.
# Only skips a contiguous leading run — not all matching commits.
# Set to '' to disable entirely.
# Classroom 50's accept-time setup commit is authored under the
# student's own identity, not a bot, so it isn't matched here — its
# .classroom50.yaml file is excluded by pattern instead.
skip_committers: "github-actions[bot]"

# Manually override the base and/or head commit SHA.
# These take precedence over all automatic SHA resolution.
# base_sha: ''
# head_sha: ''