[{"data":1,"prerenderedAt":1070},["ShallowReactive",2],{"navigation":3,"talk-/talks/github-actions":146,"person-Harry Swift":1057,"/talks/github-actions-surround":1065},[4],{"title":5,"path":6,"stem":7,"children":8,"page":145},"Talks","/talks","talks",[9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141],{"title":10,"path":11,"stem":12},"The Single Responsibility Principle","/talks/single-responsibility-principle","talks/single-responsibility-principle",{"title":14,"path":15,"stem":16},"The Open/Closed Principle","/talks/open-closed-principle","talks/open-closed-principle",{"title":18,"path":19,"stem":20},"Spack","/talks/spack","talks/spack",{"title":22,"path":23,"stem":24},"GitHub Actions","/talks/github-actions","talks/github-actions",{"title":26,"path":27,"stem":28},"Inheritance is Evil","/talks/inheritance-is-evil","talks/inheritance-is-evil",{"title":30,"path":31,"stem":32},"Nuxt","/talks/nuxt","talks/nuxt",{"title":34,"path":35,"stem":36},"LogSeq","/talks/logseq","talks/logseq",{"title":38,"path":39,"stem":40},"Time Complexity","/talks/time-complexity","talks/time-complexity",{"title":42,"path":43,"stem":44},"How to Review a Codebase","/talks/how-to-review-a-codebase","talks/how-to-review-a-codebase",{"title":46,"path":47,"stem":48},"Numba and Bitmasks","/talks/numba-and-bitmasks","talks/numba-and-bitmasks",{"title":50,"path":51,"stem":52},"Mutation Testing","/talks/mutation-testing","talks/mutation-testing",{"title":54,"path":55,"stem":56},"Message Passing Interface","/talks/message-passing-interface","talks/message-passing-interface",{"title":58,"path":59,"stem":60},"P vs NP","/talks/p-vs-np","talks/p-vs-np",{"title":62,"path":63,"stem":64},"Verbose Graphics with Rust and Vulkan","/talks/verbose-graphics-with-rust-and-vulkan","talks/verbose-graphics-with-rust-and-vulkan",{"title":66,"path":67,"stem":68},"Slidev","/talks/slidev","talks/slidev",{"title":70,"path":71,"stem":72},"Nuxt Content By Example","/talks/nuxt-content-by-example","talks/nuxt-content-by-example",{"title":74,"path":75,"stem":76},"Rust MMU Guest Lecture","/talks/rust-mmu-guest-lecture","talks/rust-mmu-guest-lecture",{"title":78,"path":79,"stem":80},"As We May Think - AI for Coding","/talks/ai-for-coding","talks/ai-for-coding",{"title":82,"path":83,"stem":84},"Git in Practice: Techniques for Collaborative Development","/talks/git-in-practice","talks/git-in-practice",{"title":86,"path":87,"stem":88},"A Crash Course in Natural Language Processing","/talks/natural-language-processing","talks/natural-language-processing",{"title":90,"path":91,"stem":92},"Graphs: Ruining the Travelling Salesman's Day Since 1930","/talks/graph-theory","talks/graph-theory",{"title":94,"path":95,"stem":96},"Automating File Creation With Jinja2 Templates in Python","/talks/jinja2-templates-with-python","talks/jinja2-templates-with-python",{"title":98,"path":99,"stem":100},"What the hell is a Monad?","/talks/monads","talks/monads",{"title":102,"path":103,"stem":104},"The Liskov Substitution Principle","/talks/liskov-substitution-principle","talks/liskov-substitution-principle",{"title":106,"path":107,"stem":108},"Everything as a Specification","/talks/everything-as-a-specification","talks/everything-as-a-specification",{"title":110,"path":111,"stem":112},"The Interface Segregation Principle","/talks/interface-segregation-principle","talks/interface-segregation-principle",{"title":114,"path":115,"stem":116},"The Dependency Inversion Principle","/talks/dependency-inversion-principle","talks/dependency-inversion-principle",{"title":118,"path":119,"stem":120},"A Field Guide To Coupling","/talks/a-field-guide-to-coupling","talks/a-field-guide-to-coupling",{"title":122,"path":123,"stem":124},"Why Python is (and isn't) Fast","/talks/why-python-is-slow","talks/why-python-is-slow",{"title":126,"path":127,"stem":128},"Cybersecurity","/talks/cybersecurity","talks/cybersecurity",{"title":130,"path":131,"stem":132},"What Linux Distribution Should You Use?","/talks/what-linux-distribution","talks/what-linux-distribution",{"title":134,"path":135,"stem":136},"Agent Communication Protocols","/talks/agent-communication-protocols","talks/agent-communication-protocols",{"title":138,"path":139,"stem":140},"Why I hate try/catch, and why you should hate it too!","/talks/hate-try-catch","talks/hate-try-catch",{"title":142,"path":143,"stem":144},"The Beauty of Vim Motions","/talks/beauty-of-vim-motions","talks/beauty-of-vim-motions",false,{"id":147,"title":22,"body":148,"date":1048,"description":1049,"extension":1050,"imgClass":1051,"imgUrl":1052,"isImgLogo":145,"meta":1053,"navigation":303,"path":23,"recordingUrl":1051,"seo":1054,"speaker":1055,"stem":24,"__hash__":1056},"talks/talks/github-actions.md",{"type":149,"value":150,"toc":1046},"minimark",[151,160,1042],[152,153,154,155,159],"p",{},"GitHub Actions is a CI/CD platform built into GitHub that lets you automate workflows such as testing, building, and deploying code. You define workflows using YAML files stored in your repository under ",[156,157,158],"code",{},".github/workflows/",".",[161,162,164,169,186,190,231,235,238,259,266,283,289,316,322,330,334,340,615,619,675,679,685,688,692,697,952,958,1035],"steps",{"level":163},"4",[165,166,168],"h4",{"id":167},"prerequisites","Prerequisites",[170,171,172,176,179],"ul",{},[173,174,175],"li",{},"Git installed",[173,177,178],{},"Python installed",[173,180,181,182,185],{},"GitHub CLI (",[156,183,184],{},"gh",") installed and logged in",[165,187,189],{"id":188},"create-a-new-project-directory-and-initialize-git","Create a New Project Directory and Initialize Git",[191,192,198],"pre",{"className":193,"code":194,"filename":195,"language":196,"meta":197,"style":197},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","mkdir python-ci-demo\ncd python-ci-demo\ngit init\n","Terminal","bash","",[156,199,200,213,222],{"__ignoreMap":197},[201,202,205,209],"span",{"class":203,"line":204},"line",1,[201,206,208],{"class":207},"sBMFI","mkdir",[201,210,212],{"class":211},"sfazB"," python-ci-demo\n",[201,214,216,220],{"class":203,"line":215},2,[201,217,219],{"class":218},"s2Zo4","cd",[201,221,212],{"class":211},[201,223,225,228],{"class":203,"line":224},3,[201,226,227],{"class":207},"git",[201,229,230],{"class":211}," init\n",[165,232,234],{"id":233},"create-python-app-and-tests","Create Python app and tests",[152,236,237],{},"Create the directory structure and files:",[191,239,241],{"className":193,"code":240,"filename":195,"language":196,"meta":197,"style":197},"mkdir -p app tests .github/workflows\n",[156,242,243],{"__ignoreMap":197},[201,244,245,247,250,253,256],{"class":203,"line":204},[201,246,208],{"class":207},[201,248,249],{"class":211}," -p",[201,251,252],{"class":211}," app",[201,254,255],{"class":211}," tests",[201,257,258],{"class":211}," .github/workflows\n",[152,260,261,262,265],{},"Create ",[156,263,264],{},"app/main.py"," with a simple function:",[191,267,271],{"className":268,"code":269,"filename":264,"language":270,"meta":197,"style":197},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","def add(x, y):\n    return x + y\n","python",[156,272,273,278],{"__ignoreMap":197},[201,274,275],{"class":203,"line":204},[201,276,277],{},"def add(x, y):\n",[201,279,280],{"class":203,"line":215},[201,281,282],{},"    return x + y\n",[152,284,261,285,288],{},[156,286,287],{},"tests/test_main.py"," with a test case:",[191,290,292],{"className":268,"code":291,"filename":287,"language":270,"meta":197,"style":197},"from app.main import add\n\ndef test_add():\n    assert add(2, 3) == 5\n",[156,293,294,299,305,310],{"__ignoreMap":197},[201,295,296],{"class":203,"line":204},[201,297,298],{},"from app.main import add\n",[201,300,301],{"class":203,"line":215},[201,302,304],{"emptyLinePlaceholder":303},true,"\n",[201,306,307],{"class":203,"line":224},[201,308,309],{},"def test_add():\n",[201,311,313],{"class":203,"line":312},4,[201,314,315],{},"    assert add(2, 3) == 5\n",[152,317,261,318,321],{},[156,319,320],{},"requirements.txt"," listing dependencies:",[191,323,328],{"className":324,"code":326,"filename":320,"language":327,"meta":197},[325],"language-text","pytest\nblack\n","text",[156,329,326],{"__ignoreMap":197},[165,331,333],{"id":332},"add-the-workflow-yaml","Add the Workflow YAML",[152,335,261,336,339],{},[156,337,338],{},".github/workflows/ci.yml"," with the following contents:",[191,341,345],{"className":342,"code":343,"filename":338,"language":344,"meta":197,"style":197},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: Python CI\non: [push, pull_request]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [3.11, 3.12, 3.13]\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v5\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -r requirements.txt\n      - name: Run tests\n        run: |\n          pytest\n      - name: Check formatting with Black\n        run: |\n          black --check .\n","yaml",[156,346,347,360,383,391,398,409,417,425,451,459,473,484,496,506,514,525,537,549,555,561,573,582,588,600,609],{"__ignoreMap":197},[201,348,349,353,357],{"class":203,"line":204},[201,350,352],{"class":351},"swJcz","name",[201,354,356],{"class":355},"sMK4o",":",[201,358,359],{"class":211}," Python CI\n",[201,361,362,366,368,371,374,377,380],{"class":203,"line":215},[201,363,365],{"class":364},"sfNiH","on",[201,367,356],{"class":355},[201,369,370],{"class":355}," [",[201,372,373],{"class":211},"push",[201,375,376],{"class":355},",",[201,378,379],{"class":211}," pull_request",[201,381,382],{"class":355},"]\n",[201,384,385,388],{"class":203,"line":224},[201,386,387],{"class":351},"jobs",[201,389,390],{"class":355},":\n",[201,392,393,396],{"class":203,"line":312},[201,394,395],{"class":351},"  build",[201,397,390],{"class":355},[201,399,401,404,406],{"class":203,"line":400},5,[201,402,403],{"class":351},"    runs-on",[201,405,356],{"class":355},[201,407,408],{"class":211}," ubuntu-latest\n",[201,410,412,415],{"class":203,"line":411},6,[201,413,414],{"class":351},"    strategy",[201,416,390],{"class":355},[201,418,420,423],{"class":203,"line":419},7,[201,421,422],{"class":351},"      matrix",[201,424,390],{"class":355},[201,426,428,431,433,435,439,441,444,446,449],{"class":203,"line":427},8,[201,429,430],{"class":351},"        python-version",[201,432,356],{"class":355},[201,434,370],{"class":355},[201,436,438],{"class":437},"sbssI","3.11",[201,440,376],{"class":355},[201,442,443],{"class":437}," 3.12",[201,445,376],{"class":355},[201,447,448],{"class":437}," 3.13",[201,450,382],{"class":355},[201,452,454,457],{"class":203,"line":453},9,[201,455,456],{"class":351},"    steps",[201,458,390],{"class":355},[201,460,462,465,468,470],{"class":203,"line":461},10,[201,463,464],{"class":355},"      -",[201,466,467],{"class":351}," name",[201,469,356],{"class":355},[201,471,472],{"class":211}," Checkout repository\n",[201,474,476,479,481],{"class":203,"line":475},11,[201,477,478],{"class":351},"        uses",[201,480,356],{"class":355},[201,482,483],{"class":211}," actions/checkout@v4\n",[201,485,487,489,491,493],{"class":203,"line":486},12,[201,488,464],{"class":355},[201,490,467],{"class":351},[201,492,356],{"class":355},[201,494,495],{"class":211}," Set up Python ${{ matrix.python-version }}\n",[201,497,499,501,503],{"class":203,"line":498},13,[201,500,478],{"class":351},[201,502,356],{"class":355},[201,504,505],{"class":211}," actions/setup-python@v5\n",[201,507,509,512],{"class":203,"line":508},14,[201,510,511],{"class":351},"        with",[201,513,390],{"class":355},[201,515,517,520,522],{"class":203,"line":516},15,[201,518,519],{"class":351},"          python-version",[201,521,356],{"class":355},[201,523,524],{"class":211}," ${{ matrix.python-version }}\n",[201,526,528,530,532,534],{"class":203,"line":527},16,[201,529,464],{"class":355},[201,531,467],{"class":351},[201,533,356],{"class":355},[201,535,536],{"class":211}," Install dependencies\n",[201,538,540,543,545],{"class":203,"line":539},17,[201,541,542],{"class":351},"        run",[201,544,356],{"class":355},[201,546,548],{"class":547},"s7zQu"," |\n",[201,550,552],{"class":203,"line":551},18,[201,553,554],{"class":211},"          python -m pip install --upgrade pip\n",[201,556,558],{"class":203,"line":557},19,[201,559,560],{"class":211},"          pip install -r requirements.txt\n",[201,562,564,566,568,570],{"class":203,"line":563},20,[201,565,464],{"class":355},[201,567,467],{"class":351},[201,569,356],{"class":355},[201,571,572],{"class":211}," Run tests\n",[201,574,576,578,580],{"class":203,"line":575},21,[201,577,542],{"class":351},[201,579,356],{"class":355},[201,581,548],{"class":547},[201,583,585],{"class":203,"line":584},22,[201,586,587],{"class":211},"          pytest\n",[201,589,591,593,595,597],{"class":203,"line":590},23,[201,592,464],{"class":355},[201,594,467],{"class":351},[201,596,356],{"class":355},[201,598,599],{"class":211}," Check formatting with Black\n",[201,601,603,605,607],{"class":203,"line":602},24,[201,604,542],{"class":351},[201,606,356],{"class":355},[201,608,548],{"class":547},[201,610,612],{"class":203,"line":611},25,[201,613,614],{"class":211},"          black --check .\n",[165,616,618],{"id":617},"adding-github-actions-workflow","Adding Github Actions Workflow",[191,620,622],{"className":193,"code":621,"filename":195,"language":196,"meta":197,"style":197},"git add .\ngit commit -m \"Initial commit with Python app and GitHub Actions CI\"\ngh repo create python-ci-demo --public --source=. --push\n",[156,623,624,634,653],{"__ignoreMap":197},[201,625,626,628,631],{"class":203,"line":204},[201,627,227],{"class":207},[201,629,630],{"class":211}," add",[201,632,633],{"class":211}," .\n",[201,635,636,638,641,644,647,650],{"class":203,"line":215},[201,637,227],{"class":207},[201,639,640],{"class":211}," commit",[201,642,643],{"class":211}," -m",[201,645,646],{"class":355}," \"",[201,648,649],{"class":211},"Initial commit with Python app and GitHub Actions CI",[201,651,652],{"class":355},"\"\n",[201,654,655,657,660,663,666,669,672],{"class":203,"line":224},[201,656,184],{"class":207},[201,658,659],{"class":211}," repo",[201,661,662],{"class":211}," create",[201,664,665],{"class":211}," python-ci-demo",[201,667,668],{"class":211}," --public",[201,670,671],{"class":211}," --source=.",[201,673,674],{"class":211}," --push\n",[165,676,678],{"id":677},"view-your-workflow","View your Workflow",[152,680,681,682],{},"Open your browser to your new repo, e.g.: ",[156,683,684],{},"https://github.com/YOUR_USERNAME/python-ci-demo",[152,686,687],{},"Click on thee \"Actions\" tab and observe the workflow running for each push or pull request.",[165,689,691],{"id":690},"create-cron-jobs","Create CRON Jobs",[152,693,261,694,339],{},[156,695,696],{},".github/workflows/cron.yml",[191,698,700],{"className":342,"code":699,"filename":696,"language":344,"meta":197,"style":197},"name: Python CI\n\non:\n  push:\n  pull_request:\n  schedule:\n    - cron: '0 9 * * 1'  # Every Monday at 09:00 UTC\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [3.11, 3.12, 3.13]\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v5\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -r requirements.txt\n      - name: Run tests\n        run: |\n          pytest\n      - name: Check formatting with Black\n        run: |\n          black --check .\n",[156,701,702,710,714,720,727,734,741,764,768,774,780,788,794,800,820,826,836,844,854,862,868,876,886,894,898,902,913,922,927,938,947],{"__ignoreMap":197},[201,703,704,706,708],{"class":203,"line":204},[201,705,352],{"class":351},[201,707,356],{"class":355},[201,709,359],{"class":211},[201,711,712],{"class":203,"line":215},[201,713,304],{"emptyLinePlaceholder":303},[201,715,716,718],{"class":203,"line":224},[201,717,365],{"class":364},[201,719,390],{"class":355},[201,721,722,725],{"class":203,"line":312},[201,723,724],{"class":351},"  push",[201,726,390],{"class":355},[201,728,729,732],{"class":203,"line":400},[201,730,731],{"class":351},"  pull_request",[201,733,390],{"class":355},[201,735,736,739],{"class":203,"line":411},[201,737,738],{"class":351},"  schedule",[201,740,390],{"class":355},[201,742,743,746,749,751,754,757,760],{"class":203,"line":419},[201,744,745],{"class":355},"    -",[201,747,748],{"class":351}," cron",[201,750,356],{"class":355},[201,752,753],{"class":355}," '",[201,755,756],{"class":211},"0 9 * * 1",[201,758,759],{"class":355},"'",[201,761,763],{"class":762},"sHwdD","  # Every Monday at 09:00 UTC\n",[201,765,766],{"class":203,"line":427},[201,767,304],{"emptyLinePlaceholder":303},[201,769,770,772],{"class":203,"line":453},[201,771,387],{"class":351},[201,773,390],{"class":355},[201,775,776,778],{"class":203,"line":461},[201,777,395],{"class":351},[201,779,390],{"class":355},[201,781,782,784,786],{"class":203,"line":475},[201,783,403],{"class":351},[201,785,356],{"class":355},[201,787,408],{"class":211},[201,789,790,792],{"class":203,"line":486},[201,791,414],{"class":351},[201,793,390],{"class":355},[201,795,796,798],{"class":203,"line":498},[201,797,422],{"class":351},[201,799,390],{"class":355},[201,801,802,804,806,808,810,812,814,816,818],{"class":203,"line":508},[201,803,430],{"class":351},[201,805,356],{"class":355},[201,807,370],{"class":355},[201,809,438],{"class":437},[201,811,376],{"class":355},[201,813,443],{"class":437},[201,815,376],{"class":355},[201,817,448],{"class":437},[201,819,382],{"class":355},[201,821,822,824],{"class":203,"line":516},[201,823,456],{"class":351},[201,825,390],{"class":355},[201,827,828,830,832,834],{"class":203,"line":527},[201,829,464],{"class":355},[201,831,467],{"class":351},[201,833,356],{"class":355},[201,835,472],{"class":211},[201,837,838,840,842],{"class":203,"line":539},[201,839,478],{"class":351},[201,841,356],{"class":355},[201,843,483],{"class":211},[201,845,846,848,850,852],{"class":203,"line":551},[201,847,464],{"class":355},[201,849,467],{"class":351},[201,851,356],{"class":355},[201,853,495],{"class":211},[201,855,856,858,860],{"class":203,"line":557},[201,857,478],{"class":351},[201,859,356],{"class":355},[201,861,505],{"class":211},[201,863,864,866],{"class":203,"line":563},[201,865,511],{"class":351},[201,867,390],{"class":355},[201,869,870,872,874],{"class":203,"line":575},[201,871,519],{"class":351},[201,873,356],{"class":355},[201,875,524],{"class":211},[201,877,878,880,882,884],{"class":203,"line":584},[201,879,464],{"class":355},[201,881,467],{"class":351},[201,883,356],{"class":355},[201,885,536],{"class":211},[201,887,888,890,892],{"class":203,"line":590},[201,889,542],{"class":351},[201,891,356],{"class":355},[201,893,548],{"class":547},[201,895,896],{"class":203,"line":602},[201,897,554],{"class":211},[201,899,900],{"class":203,"line":611},[201,901,560],{"class":211},[201,903,905,907,909,911],{"class":203,"line":904},26,[201,906,464],{"class":355},[201,908,467],{"class":351},[201,910,356],{"class":355},[201,912,572],{"class":211},[201,914,916,918,920],{"class":203,"line":915},27,[201,917,542],{"class":351},[201,919,356],{"class":355},[201,921,548],{"class":547},[201,923,925],{"class":203,"line":924},28,[201,926,587],{"class":211},[201,928,930,932,934,936],{"class":203,"line":929},29,[201,931,464],{"class":355},[201,933,467],{"class":351},[201,935,356],{"class":355},[201,937,599],{"class":211},[201,939,941,943,945],{"class":203,"line":940},30,[201,942,542],{"class":351},[201,944,356],{"class":355},[201,946,548],{"class":547},[201,948,950],{"class":203,"line":949},31,[201,951,614],{"class":211},[152,953,954,955,957],{},"What does ",[156,956,756],{}," mean?",[959,960,961,977],"table",{},[962,963,964],"thead",{},[965,966,967,971,974],"tr",{},[968,969,970],"th",{},"Field",[968,972,973],{},"Value",[968,975,976],{},"Meaning",[978,979,980,992,1003,1014,1024],"tbody",{},[965,981,982,986,989],{},[983,984,985],"td",{},"Minute",[983,987,988],{},"0",[983,990,991],{},"At the 0th minute",[965,993,994,997,1000],{},[983,995,996],{},"Hour",[983,998,999],{},"9",[983,1001,1002],{},"At 09:00 (9 AM UTC)",[965,1004,1005,1008,1011],{},[983,1006,1007],{},"Day of Month",[983,1009,1010],{},"*",[983,1012,1013],{},"Every day",[965,1015,1016,1019,1021],{},[983,1017,1018],{},"Month",[983,1020,1010],{},[983,1022,1023],{},"Every month",[965,1025,1026,1029,1032],{},[983,1027,1028],{},"Day of Week",[983,1030,1031],{},"1",[983,1033,1034],{},"Monday (0 = Sunday, 1 = Monday, ...)",[152,1036,1037,1038,159],{},"This tells GitHub Actions to run the workflow ",[1039,1040,1041],"strong",{},"every Monday at 9:00 AM UTC",[1043,1044,1045],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":197,"searchDepth":204,"depth":215,"links":1047},[],["Date","2025-10-15T00:00:00.000Z"],"An introduction to GitHub Actions, covering the basics of setting up workflows, common use cases, and best practices for automating tasks in your repositories.","md",null,"/images/cicd.jpg",{},{"title":22,"description":1049},"Harry Swift","iq2sT8mTbGa0A6ovzLvoZUiQoOAo5i9l2lCh-s9lRa4",{"id":1058,"title":1059,"extension":1060,"imgUrl":1061,"meta":1062,"name":1055,"roles":1051,"stem":1063,"__hash__":1064},"people/people/harry-swift.yml","Research Software Engineer","yml","/images/people/harry-swift.jpg",{},"people/harry-swift","9mQlqffvtpoOYKFxi3MUxlzxHGAxdE0IbuJgL46uQHI",[1066,1068],{"title":18,"path":19,"stem":20,"description":1067,"children":-1},"A live demo introduction to Spack, a package manager designed for high-performance computing (HPC) environments.",{"title":26,"path":27,"stem":28,"description":1069,"children":-1},"A talk discussing the problems with inheritance in object-oriented programming and advocating for composition over inheritance.",1778147359780]