diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..febf743 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,69 @@ +name: Autograding Tests +'on': +- push +- repository_dispatch +permissions: + checks: write + actions: read + contents: read +jobs: + run-autograding-tests: + runs-on: ubuntu-latest + if: github.actor != 'github-classroom[bot]' + steps: + - name: Code Verification + uses: actions/checkout@v4 + - name: Foundry Installation + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Forge Installation + run: | + cd hw + forge install + id: test + + ## Problem Template + # - name: Problem + # id: problem- + # uses: classroom-resources/autograding-command-grader@v1 + # with: + # test-name: Problem + # command: cd hw && forge test --mt + # timeout: + # max-score: + + + ## Modify Problem 1 Configuration + - name: Problem 1 + id: problem-1 + uses: classroom-resources/autograding-command-grader@v1 + with: + test-name: Problem 1 + command: cd hw && forge test --mt test_Increment + timeout: 10 + max-score: 10 + + ## Modify Problem 2 Configuration + - name: Problem 2 + id: problem-2 + uses: classroom-resources/autograding-command-grader@v1 + with: + test-name: Problem 2 + command: cd hw && forge test --mt testFuzz_SetNumber + timeout: 10 + max-score: 10 + + ## Add More Problem Below + ## Problem 3 ... + ## Problem 4 ... + + ## Modify Autograding Reporter + ## If new problems are added, remember to add new grading actions below + - name: Autograding Reporter + uses: classroom-resources/autograding-grading-reporter@v1 + env: + PROBLEM-1_RESULTS: "${{steps.problem-1.outputs.result}}" + PROBLEM-2_RESULTS: "${{steps.problem-2.outputs.result}}" + with: + runners: problem-1, problem-2 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2de4f8d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "hw/lib/forge-std"] + path = hw/lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/README.md b/README.md new file mode 100644 index 0000000..c276c00 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# HW-Template + +Assignment Template for GitHub Classroom + +## Introduction + +This tutorial will guide you through creating your assignment locally and configuring it on GitHub Classroom. Follow the step-by-step instructions carefully to ensure each step is completed correctly. + +## Create An Assignment on GitHub +1. Create a new repository by clicking the `Use this template` button. +2. Rename the repository using the format `2024-Fall-HW*`. +3. Choose repository visibility; `Public` is recommended. +4. Design your assignment in the `src/` and `test/` folders. + - Grading should be based on whether the Foundry tests pass or fail. + - Do not support analyzing output content for grading. + - If you install external libraries, run `forge remappings` to link them. +5. Update the autograding configuration in `.github/workflows/test.yml`. + - Copy the `Problem Template` and adjust the `name`, `id`, `test-name`, `command`, `timeout`, and `max-score`. + - Add a new entry in `Autograding Reporter` (at the end of the YAML configuration). +6. Commit the changes and push them to GitHub. +7. Check the GitHub Actions and open the `Autograding Tests` workflow to ensure the auto-grading succeeds. + +![auto-grading-result](./images/auto-grading-result.png) + +## Create An Assignemnt on GitHub Classroom + +1. Go to the relevant GitHub Classroom page. +2. Click the green `+ New Assignment` button. +3. Set up the `Assignment basics` section. + - Enter the assignment title using the format `2024-Fall-HW*``. + - Select deadline, and select `This is a cutoff date`[1]. + - Select individual / group assignment +4. Setup `Starter code and environment` section + - Select the repo for this assignment in the `Find a GitHub repository section`. + - Choose repo visibility, recommend `Private`[2] access. +5. Setup `Grading and feedback` section + - Leave the `Add autograding tests` section empty, as grading rules are already configured. + - Enter protected file path, recommend adding `.github/**/*` since grading rules should not be altered[3]. + - Select `Enable feedback pull requests` to create PR on each assignment. +6. Finish assignment creation, send the invitation code to the students and starting coding! + + +NOTE: +[1] Once the cutoff date option is selected, student will lose write access to their repository after deadline. +[2] `Private` access means students will create private repositories when receiving the invitation link. +[3] For CTF problems, the `src/` folder should be locked. If students need to fill in blanks in the source contract, consider locking the corresponding test files. + +## Check the Assignment Status on GitHub Classroom + +1. Check the students' repositories by clicking the `Repository` button on the right side. +2. Provide feedback by clicking the `Feedback` button on the right side and leave comments on the PR. +3. Verify whether students have submitted the assignment and review grading results. +4. Check if students have altered any protected files or folders. + +There are several examples: + +- Students not submit the assignment. +![hw-status-not-submitted](./images/hw-status-not-submitted.png) +- Students complete the assignment +![hw-status-submitted](./images/hw-status-submitted.png) +- Student change the protected files and folders +![hw-status-modify-files](./images/hw-status-modify-files.png) \ No newline at end of file diff --git a/hw/.gitignore b/hw/.gitignore new file mode 100644 index 0000000..85198aa --- /dev/null +++ b/hw/.gitignore @@ -0,0 +1,14 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/hw/README.md b/hw/README.md new file mode 100644 index 0000000..9265b45 --- /dev/null +++ b/hw/README.md @@ -0,0 +1,66 @@ +## Foundry + +**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** + +Foundry consists of: + +- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). +- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. +- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. +- **Chisel**: Fast, utilitarian, and verbose solidity REPL. + +## Documentation + +https://book.getfoundry.sh/ + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +```shell +$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/hw/foundry.toml b/hw/foundry.toml new file mode 100644 index 0000000..25b918f --- /dev/null +++ b/hw/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/hw/lib/forge-std b/hw/lib/forge-std new file mode 160000 index 0000000..07263d1 --- /dev/null +++ b/hw/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 07263d193d621c4b2b0ce8b4d54af58f6957d97d diff --git a/hw/remappings.txt b/hw/remappings.txt new file mode 100644 index 0000000..e69de29 diff --git a/hw/script/Counter.s.sol b/hw/script/Counter.s.sol new file mode 100644 index 0000000..cdc1fe9 --- /dev/null +++ b/hw/script/Counter.s.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script, console} from "forge-std/Script.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterScript is Script { + Counter public counter; + + function setUp() public {} + + function run() public { + vm.startBroadcast(); + + counter = new Counter(); + + vm.stopBroadcast(); + } +} diff --git a/hw/src/Counter.sol b/hw/src/Counter.sol new file mode 100644 index 0000000..aded799 --- /dev/null +++ b/hw/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/hw/test/Counter.t.sol b/hw/test/Counter.t.sol new file mode 100644 index 0000000..54b724f --- /dev/null +++ b/hw/test/Counter.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + } + + function test_Increment() public { + counter.increment(); + assertEq(counter.number(), 1); + } + + function testFuzz_SetNumber(uint256 x) public { + counter.setNumber(x); + assertEq(counter.number(), x); + } +} diff --git a/images/auto-grading-result.png b/images/auto-grading-result.png new file mode 100644 index 0000000..013f4e7 Binary files /dev/null and b/images/auto-grading-result.png differ diff --git a/images/hw-status-modify-files.png b/images/hw-status-modify-files.png new file mode 100644 index 0000000..729db3b Binary files /dev/null and b/images/hw-status-modify-files.png differ diff --git a/images/hw-status-not-submitted.png b/images/hw-status-not-submitted.png new file mode 100644 index 0000000..baed2ae Binary files /dev/null and b/images/hw-status-not-submitted.png differ diff --git a/images/hw-status-submitted.png b/images/hw-status-submitted.png new file mode 100644 index 0000000..74b455e Binary files /dev/null and b/images/hw-status-submitted.png differ