Tooling

teleport GitHub Action

GitHub actions are a way to run code automatically in response to events on GitHub. Triggers include:

  • Pushing
  • Pull request
  • On a schedule!!!
  • Manually

In EBS many of us are managing all our teaching materials in GitHub repos.

The slides and tutorials obviously need to be public, but assignment solutions should not

Possible solutions

  1. Don’t put assignment solutions in GitHub repos
  2. Pay for GitHub Enterprise
  3. Manage two repositories: one public, one private

When I started at EBS, we had a version of option 3 using the copycat action. Sadly this action is no longer maintained.

teleport

My first draft of this was a manual implementation which effectively:

  • Checks out both repos
  • Uses rsync to copy files from one repo to a specific directory in another
  • Commits and pushes changes if there are any using a bot account
steps:
      - name: Checkout source repo
        uses: actions/checkout@v4
        with:
          repository: ${{ github.repository }}
          path: source

      - name: Checkout target repo
        uses: actions/checkout@v4
        with:
          repository: spectrum-spark/courses 
          path: target-repo
          token: ${{ secrets.PERSONAL_TOKEN }}       # Personal Access Token with repo write perms

      - name: Copy files
        run: |
          mkdir -p target-repo/courses/intro-mathematical-modelling
          rsync -av --delete source/student_materials/ target-repo/courses/intro-mathematical-modelling

      - name: Commit & push changes
        working-directory: target-repo
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add .
          git commit -m "Sync directory from source repo" || echo "No changes to commit"
          git push

teleport

Bundled into an action, you can now just add this to your workflow:

steps:
      - uses: MikeLydeamore/teleport-action@v1
        with:
          target_repo: "OWNER/TARGET_REPO"
          target_path: "path/in/target"
          source_path: "path/in/source"
          token: ${{ secrets.CROSS_REPO_PAT }}

The token needs the following scopes:

  • Target Repo: Contents (read/write)
  • Source repo: Contents (read) if the repo is private

There are also some semantics about trailing / in paths, see the README for details.

Usage

See the action online: MikeLydeamore/teleport

Now deployed in:

  • At least one EBS course material repo
  • ID Modelling course materials

And one dayTM it’s how I will deploy my slides.

unilur quarto filter

One of the principles of reproducibility is to reduce duplication

If you use a variable more than once, define it once and refer to it

My repo looked something like this:

tutorials
├── 01-questions.qmd
├── 01-solutions.qmd

And the content in questions and solutions was almost identical, except for the answers.

unilur

In the world of RMarkdown, an output format called unilur exists koncina/unilur

unilur quarto filter

Aurélien Ginolhac has ported this to Quarto as a filter: ginolhac/unilur, and I have added support for various output formats:

format:
  unilur-html: default
  unilur-html+solution:
    output-file: example-solution.html
  unilur-pdf: default
  unilur-pdf+solution: default

unilur quarto filter

  • Specify solution blocks with ::: {.solution}
  • Or as a chunk option #| solution: true

You can also use unilur-comment to add comments that only appear in solutions such as marking guides

Comment Viewer Positron Extension

How good are tracked changes though?

Collaborative writing and Quarto

  • Quarto works well with git
  • Viewing diffs of .qmd files is not very user friendly
  • Leaving feedback (i.e. without changing the text) is not practical

One approach: Use HTML comments (which never render in any format) to give feedback.

Collaborative writing and Quarto

Problem: Finding these comments again!

  • Grep?
  • Custom script?
  • Positron extension?

Comment Viewer Positron Extension

MikeLydeamore/code-comment-viewer-extension

You can hover and click on comments to jump your document to them.

Sneak peek: ggplot battles

Code Golf

Code golf is a game where the aim is to solve a problem as quickly, and often in as few characters of code as possible.

In my opinion few characters is a poor metric, but speed, and accuracy are interesting.

See for example CSSBattle

Gamifying data visualisation

I built ggplot battles to gamify learning ggplot2.

Available at: https://www.ggplotbattles.dev

This involved:

  • Getting webr working in pure javascript
  • Getting canvases to display ggplots, which is way harder than it sounds
  • Pixel-by-pixel image comparison using resemble.js
  • Writing a custom Quarto-like argument parser for challenges

Contributing

More challenges = more good

Instructions are on GitHub, but if you can write a qmd you can write these.

The build system is entirely custom, and will likely break, but for now I remain the gatekeeper of all things ggplot battles.

Testing

I’m rolling this out in my communication unit. You are welcome to do the same, or try on your own.

Currently, there is no leaderboard or unified scoring system, but maybe it will come.

Innovation through Procastination

Why spend time doing this?

  • It generates a disgusting amount of LinkedIn likes
  • Making small tools keeps my skills sharp
  • Helps me learn new coding styles to take to bigger projects
  • It gives me great joy to see someone else use something I built
  • It’s often a good break from deep thinking work

Credit to Fonti Kar