[{"data":1,"prerenderedAt":2723},["ShallowReactive",2],{"blog:2020:from-circleci-to-github-actions":3,"blogMore-Development":2709,"comments-from-circleci-to-github-actions":2722},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"category":11,"tags":12,"excerpt":15,"body":39,"_type":2700,"_id":2701,"_source":2702,"_file":2703,"_stem":2704,"_extension":2705,"url":2706,"wordCount":2707,"minutes":208,"commentCount":2708},"/blog/2020/from-circleci-to-github-actions","2020",false,"en","From CircleCI to GitHub Actions for Jekyll publishing","I've been a big fan of static site generation since I switched from WordPress to Jekyll back in 2018. I'm also a big fan of learning new technologies as they come along, and now GitHub Actions are out in the wild; I thought this would be an opportunity to see how I can port my existing custom CircleCI build to Jekyll.","2020-09-21","Development",[13,14],"Jekyll","CI",{"type":16,"children":17},"root",[18,30],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23,26,28],{"type":24,"value":25},"text","I've been a big fan of static site generation since I ",{"type":24,"value":27},"switched from WordPress to Jekyll back in 2018",{"type":24,"value":29},". I'm also a big fan of learning new technologies as they come along, and now GitHub Actions are out in the wild; I thought this would be an opportunity to see how I can port my existing custom CircleCI build to Jekyll.",{"type":19,"tag":20,"props":31,"children":32},{},[33,35,37],{"type":24,"value":34},"A quick recap from ",{"type":24,"value":36},"part 5 - Hosting & Building",{"type":24,"value":38},", my CircleCI configuration was basically two jobs that have subsequently been tweaked since then. They are:",{"type":16,"children":40,"toc":2690},[41,52,59,69,76,90,841,847,862,1473,1479,1484,1489,1528,1541,2611,2616,2622,2627,2664,2670,2675,2684],{"type":19,"tag":20,"props":42,"children":43},{},[44,45,51],{"type":24,"value":25},{"type":19,"tag":46,"props":47,"children":49},"a",{"href":48},"/blog/2018/from-wordpress-to-jekyll/",[50],{"type":24,"value":27},{"type":24,"value":29},{"type":19,"tag":53,"props":54,"children":56},"h2",{"id":55},"the-circleci-job",[57],{"type":24,"value":58},"The CircleCI job",{"type":19,"tag":20,"props":60,"children":61},{},[62,63,68],{"type":24,"value":34},{"type":19,"tag":46,"props":64,"children":66},{"href":65},"/blog/2018/wordpress-to-jekyll-hosting/",[67],{"type":24,"value":36},{"type":24,"value":38},{"type":19,"tag":70,"props":71,"children":73},"h3",{"id":72},"build",[74],{"type":24,"value":75},"Build",{"type":19,"tag":20,"props":77,"children":78},{},[79,81,88],{"type":24,"value":80},"The build job's responsibility was to configure a Ruby environment capable of executing Jekyll to build the site, removing the .html extension from the output filenames, and then indexing the content using Algolia. Here is the start of the ",{"type":19,"tag":82,"props":83,"children":85},"code",{"className":84},[],[86],{"type":24,"value":87},".circleci/config.yml",{"type":24,"value":89}," I was using for that:",{"type":19,"tag":91,"props":92,"children":97},"pre",{"className":93,"code":94,"language":95,"meta":96,"style":96},"language-yml shiki shiki-themes everforest-light dracula","{%raw%}version: 2\njobs:\n  build:\n    docker:\n      - image: circleci/ruby:2.6.1\n    working_directory: ~/jekyll\n    environment:\n      - JEKYLL_ENV=production\n      - NOKOGIRI_USE_SYSTEM_LIBRARIES=true\n      - JOB_RESULTS_PATH=run-results\n    steps:\n      - checkout\n      - restore_cache:\n          key: jekyll-{{ .Branch }}-{{ checksum \"Gemfile\" }}\n      - run:\n          name: Update gems\n          command: gem update --system\n      - run:\n          name: Install dependencies\n          command: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3\n      - save_cache:\n          key: jekyll-{{ .Branch }}-{{ checksum \"Gemfile\" }}\n          paths:\n            - \"vendor/bundle\"\n      - run:\n          name: Create results directory\n          command: mkdir -p $JOB_RESULTS_PATH\n      - run:\n          name: Build site\n          command: bundle exec jekyll build --config _config.yml,_config-publish.yml 2>&1 | tee $JOB_RESULTS_PATH/build-results.txt\n      - run:\n          name: Remove .html suffixes\n          command: find _site -name \"*.html\" -not -name \"index.html\" -exec rename -v 's/\\.html$//' {} \\;\n      - run:\n          name: Index with Algolia\n          command: bundle exec jekyll algolia --config _config.yml,_config-publish.yml\n      - store_artifacts:\n          path: run-results/\n          destination: run-results\n      - persist_to_workspace:\n          root: ~/jekyll\n          paths:\n            - _site\n{%endraw%}\n","yml","",[98],{"type":19,"tag":82,"props":99,"children":100},{"__ignoreMap":96},[101,142,156,169,182,206,224,237,250,263,276,289,302,319,337,354,372,390,406,423,440,457,473,486,511,527,544,561,577,594,611,627,644,661,677,694,711,728,746,764,781,798,810,823],{"type":19,"tag":102,"props":103,"children":106},"span",{"class":104,"line":105},"line",1,[107,113,119,124,130,136],{"type":19,"tag":102,"props":108,"children":110},{"style":109},"--shiki-default:#5C6A72;--shiki-dark:#F8F8F2",[111],{"type":24,"value":112},"{%",{"type":19,"tag":102,"props":114,"children":116},{"style":115},"--shiki-default:#8DA101;--shiki-dark:#F1FA8C",[117],{"type":24,"value":118},"raw%",{"type":19,"tag":102,"props":120,"children":121},{"style":109},[122],{"type":24,"value":123},"}",{"type":19,"tag":102,"props":125,"children":127},{"style":126},"--shiki-default:#F57D26;--shiki-dark:#8BE9FD",[128],{"type":24,"value":129},"version",{"type":19,"tag":102,"props":131,"children":133},{"style":132},"--shiki-default:#939F91;--shiki-dark:#FF79C6",[134],{"type":24,"value":135},":",{"type":19,"tag":102,"props":137,"children":139},{"style":138},"--shiki-default:#DF69BA;--shiki-dark:#BD93F9",[140],{"type":24,"value":141}," 2\n",{"type":19,"tag":102,"props":143,"children":145},{"class":104,"line":144},2,[146,151],{"type":19,"tag":102,"props":147,"children":148},{"style":126},[149],{"type":24,"value":150},"jobs",{"type":19,"tag":102,"props":152,"children":153},{"style":132},[154],{"type":24,"value":155},":\n",{"type":19,"tag":102,"props":157,"children":159},{"class":104,"line":158},3,[160,165],{"type":19,"tag":102,"props":161,"children":162},{"style":126},[163],{"type":24,"value":164},"  build",{"type":19,"tag":102,"props":166,"children":167},{"style":132},[168],{"type":24,"value":155},{"type":19,"tag":102,"props":170,"children":172},{"class":104,"line":171},4,[173,178],{"type":19,"tag":102,"props":174,"children":175},{"style":126},[176],{"type":24,"value":177},"    docker",{"type":19,"tag":102,"props":179,"children":180},{"style":132},[181],{"type":24,"value":155},{"type":19,"tag":102,"props":183,"children":185},{"class":104,"line":184},5,[186,192,197,201],{"type":19,"tag":102,"props":187,"children":189},{"style":188},"--shiki-default:#35A77C;--shiki-dark:#FF79C6",[190],{"type":24,"value":191},"      -",{"type":19,"tag":102,"props":193,"children":194},{"style":126},[195],{"type":24,"value":196}," image",{"type":19,"tag":102,"props":198,"children":199},{"style":132},[200],{"type":24,"value":135},{"type":19,"tag":102,"props":202,"children":203},{"style":115},[204],{"type":24,"value":205}," circleci/ruby:2.6.1\n",{"type":19,"tag":102,"props":207,"children":209},{"class":104,"line":208},6,[210,215,219],{"type":19,"tag":102,"props":211,"children":212},{"style":126},[213],{"type":24,"value":214},"    working_directory",{"type":19,"tag":102,"props":216,"children":217},{"style":132},[218],{"type":24,"value":135},{"type":19,"tag":102,"props":220,"children":221},{"style":115},[222],{"type":24,"value":223}," ~/jekyll\n",{"type":19,"tag":102,"props":225,"children":227},{"class":104,"line":226},7,[228,233],{"type":19,"tag":102,"props":229,"children":230},{"style":126},[231],{"type":24,"value":232},"    environment",{"type":19,"tag":102,"props":234,"children":235},{"style":132},[236],{"type":24,"value":155},{"type":19,"tag":102,"props":238,"children":240},{"class":104,"line":239},8,[241,245],{"type":19,"tag":102,"props":242,"children":243},{"style":188},[244],{"type":24,"value":191},{"type":19,"tag":102,"props":246,"children":247},{"style":115},[248],{"type":24,"value":249}," JEKYLL_ENV=production\n",{"type":19,"tag":102,"props":251,"children":253},{"class":104,"line":252},9,[254,258],{"type":19,"tag":102,"props":255,"children":256},{"style":188},[257],{"type":24,"value":191},{"type":19,"tag":102,"props":259,"children":260},{"style":115},[261],{"type":24,"value":262}," NOKOGIRI_USE_SYSTEM_LIBRARIES=true\n",{"type":19,"tag":102,"props":264,"children":266},{"class":104,"line":265},10,[267,271],{"type":19,"tag":102,"props":268,"children":269},{"style":188},[270],{"type":24,"value":191},{"type":19,"tag":102,"props":272,"children":273},{"style":115},[274],{"type":24,"value":275}," JOB_RESULTS_PATH=run-results\n",{"type":19,"tag":102,"props":277,"children":279},{"class":104,"line":278},11,[280,285],{"type":19,"tag":102,"props":281,"children":282},{"style":126},[283],{"type":24,"value":284},"    steps",{"type":19,"tag":102,"props":286,"children":287},{"style":132},[288],{"type":24,"value":155},{"type":19,"tag":102,"props":290,"children":292},{"class":104,"line":291},12,[293,297],{"type":19,"tag":102,"props":294,"children":295},{"style":188},[296],{"type":24,"value":191},{"type":19,"tag":102,"props":298,"children":299},{"style":115},[300],{"type":24,"value":301}," checkout\n",{"type":19,"tag":102,"props":303,"children":305},{"class":104,"line":304},13,[306,310,315],{"type":19,"tag":102,"props":307,"children":308},{"style":188},[309],{"type":24,"value":191},{"type":19,"tag":102,"props":311,"children":312},{"style":126},[313],{"type":24,"value":314}," restore_cache",{"type":19,"tag":102,"props":316,"children":317},{"style":132},[318],{"type":24,"value":155},{"type":19,"tag":102,"props":320,"children":322},{"class":104,"line":321},14,[323,328,332],{"type":19,"tag":102,"props":324,"children":325},{"style":126},[326],{"type":24,"value":327},"          key",{"type":19,"tag":102,"props":329,"children":330},{"style":132},[331],{"type":24,"value":135},{"type":19,"tag":102,"props":333,"children":334},{"style":115},[335],{"type":24,"value":336}," jekyll-{{ .Branch }}-{{ checksum \"Gemfile\" }}\n",{"type":19,"tag":102,"props":338,"children":340},{"class":104,"line":339},15,[341,345,350],{"type":19,"tag":102,"props":342,"children":343},{"style":188},[344],{"type":24,"value":191},{"type":19,"tag":102,"props":346,"children":347},{"style":126},[348],{"type":24,"value":349}," run",{"type":19,"tag":102,"props":351,"children":352},{"style":132},[353],{"type":24,"value":155},{"type":19,"tag":102,"props":355,"children":357},{"class":104,"line":356},16,[358,363,367],{"type":19,"tag":102,"props":359,"children":360},{"style":126},[361],{"type":24,"value":362},"          name",{"type":19,"tag":102,"props":364,"children":365},{"style":132},[366],{"type":24,"value":135},{"type":19,"tag":102,"props":368,"children":369},{"style":115},[370],{"type":24,"value":371}," Update gems\n",{"type":19,"tag":102,"props":373,"children":375},{"class":104,"line":374},17,[376,381,385],{"type":19,"tag":102,"props":377,"children":378},{"style":126},[379],{"type":24,"value":380},"          command",{"type":19,"tag":102,"props":382,"children":383},{"style":132},[384],{"type":24,"value":135},{"type":19,"tag":102,"props":386,"children":387},{"style":115},[388],{"type":24,"value":389}," gem update --system\n",{"type":19,"tag":102,"props":391,"children":393},{"class":104,"line":392},18,[394,398,402],{"type":19,"tag":102,"props":395,"children":396},{"style":188},[397],{"type":24,"value":191},{"type":19,"tag":102,"props":399,"children":400},{"style":126},[401],{"type":24,"value":349},{"type":19,"tag":102,"props":403,"children":404},{"style":132},[405],{"type":24,"value":155},{"type":19,"tag":102,"props":407,"children":409},{"class":104,"line":408},19,[410,414,418],{"type":19,"tag":102,"props":411,"children":412},{"style":126},[413],{"type":24,"value":362},{"type":19,"tag":102,"props":415,"children":416},{"style":132},[417],{"type":24,"value":135},{"type":19,"tag":102,"props":419,"children":420},{"style":115},[421],{"type":24,"value":422}," Install dependencies\n",{"type":19,"tag":102,"props":424,"children":426},{"class":104,"line":425},20,[427,431,435],{"type":19,"tag":102,"props":428,"children":429},{"style":126},[430],{"type":24,"value":380},{"type":19,"tag":102,"props":432,"children":433},{"style":132},[434],{"type":24,"value":135},{"type":19,"tag":102,"props":436,"children":437},{"style":115},[438],{"type":24,"value":439}," bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3\n",{"type":19,"tag":102,"props":441,"children":443},{"class":104,"line":442},21,[444,448,453],{"type":19,"tag":102,"props":445,"children":446},{"style":188},[447],{"type":24,"value":191},{"type":19,"tag":102,"props":449,"children":450},{"style":126},[451],{"type":24,"value":452}," save_cache",{"type":19,"tag":102,"props":454,"children":455},{"style":132},[456],{"type":24,"value":155},{"type":19,"tag":102,"props":458,"children":460},{"class":104,"line":459},22,[461,465,469],{"type":19,"tag":102,"props":462,"children":463},{"style":126},[464],{"type":24,"value":327},{"type":19,"tag":102,"props":466,"children":467},{"style":132},[468],{"type":24,"value":135},{"type":19,"tag":102,"props":470,"children":471},{"style":115},[472],{"type":24,"value":336},{"type":19,"tag":102,"props":474,"children":476},{"class":104,"line":475},23,[477,482],{"type":19,"tag":102,"props":478,"children":479},{"style":126},[480],{"type":24,"value":481},"          paths",{"type":19,"tag":102,"props":483,"children":484},{"style":132},[485],{"type":24,"value":155},{"type":19,"tag":102,"props":487,"children":489},{"class":104,"line":488},24,[490,495,501,506],{"type":19,"tag":102,"props":491,"children":492},{"style":188},[493],{"type":24,"value":494},"            -",{"type":19,"tag":102,"props":496,"children":498},{"style":497},"--shiki-default:#8DA101;--shiki-dark:#E9F284",[499],{"type":24,"value":500}," \"",{"type":19,"tag":102,"props":502,"children":503},{"style":115},[504],{"type":24,"value":505},"vendor/bundle",{"type":19,"tag":102,"props":507,"children":508},{"style":497},[509],{"type":24,"value":510},"\"\n",{"type":19,"tag":102,"props":512,"children":514},{"class":104,"line":513},25,[515,519,523],{"type":19,"tag":102,"props":516,"children":517},{"style":188},[518],{"type":24,"value":191},{"type":19,"tag":102,"props":520,"children":521},{"style":126},[522],{"type":24,"value":349},{"type":19,"tag":102,"props":524,"children":525},{"style":132},[526],{"type":24,"value":155},{"type":19,"tag":102,"props":528,"children":530},{"class":104,"line":529},26,[531,535,539],{"type":19,"tag":102,"props":532,"children":533},{"style":126},[534],{"type":24,"value":362},{"type":19,"tag":102,"props":536,"children":537},{"style":132},[538],{"type":24,"value":135},{"type":19,"tag":102,"props":540,"children":541},{"style":115},[542],{"type":24,"value":543}," Create results directory\n",{"type":19,"tag":102,"props":545,"children":547},{"class":104,"line":546},27,[548,552,556],{"type":19,"tag":102,"props":549,"children":550},{"style":126},[551],{"type":24,"value":380},{"type":19,"tag":102,"props":553,"children":554},{"style":132},[555],{"type":24,"value":135},{"type":19,"tag":102,"props":557,"children":558},{"style":115},[559],{"type":24,"value":560}," mkdir -p $JOB_RESULTS_PATH\n",{"type":19,"tag":102,"props":562,"children":564},{"class":104,"line":563},28,[565,569,573],{"type":19,"tag":102,"props":566,"children":567},{"style":188},[568],{"type":24,"value":191},{"type":19,"tag":102,"props":570,"children":571},{"style":126},[572],{"type":24,"value":349},{"type":19,"tag":102,"props":574,"children":575},{"style":132},[576],{"type":24,"value":155},{"type":19,"tag":102,"props":578,"children":580},{"class":104,"line":579},29,[581,585,589],{"type":19,"tag":102,"props":582,"children":583},{"style":126},[584],{"type":24,"value":362},{"type":19,"tag":102,"props":586,"children":587},{"style":132},[588],{"type":24,"value":135},{"type":19,"tag":102,"props":590,"children":591},{"style":115},[592],{"type":24,"value":593}," Build site\n",{"type":19,"tag":102,"props":595,"children":597},{"class":104,"line":596},30,[598,602,606],{"type":19,"tag":102,"props":599,"children":600},{"style":126},[601],{"type":24,"value":380},{"type":19,"tag":102,"props":603,"children":604},{"style":132},[605],{"type":24,"value":135},{"type":19,"tag":102,"props":607,"children":608},{"style":115},[609],{"type":24,"value":610}," bundle exec jekyll build --config _config.yml,_config-publish.yml 2>&1 | tee $JOB_RESULTS_PATH/build-results.txt\n",{"type":19,"tag":102,"props":612,"children":614},{"class":104,"line":613},31,[615,619,623],{"type":19,"tag":102,"props":616,"children":617},{"style":188},[618],{"type":24,"value":191},{"type":19,"tag":102,"props":620,"children":621},{"style":126},[622],{"type":24,"value":349},{"type":19,"tag":102,"props":624,"children":625},{"style":132},[626],{"type":24,"value":155},{"type":19,"tag":102,"props":628,"children":630},{"class":104,"line":629},32,[631,635,639],{"type":19,"tag":102,"props":632,"children":633},{"style":126},[634],{"type":24,"value":362},{"type":19,"tag":102,"props":636,"children":637},{"style":132},[638],{"type":24,"value":135},{"type":19,"tag":102,"props":640,"children":641},{"style":115},[642],{"type":24,"value":643}," Remove .html suffixes\n",{"type":19,"tag":102,"props":645,"children":647},{"class":104,"line":646},33,[648,652,656],{"type":19,"tag":102,"props":649,"children":650},{"style":126},[651],{"type":24,"value":380},{"type":19,"tag":102,"props":653,"children":654},{"style":132},[655],{"type":24,"value":135},{"type":19,"tag":102,"props":657,"children":658},{"style":115},[659],{"type":24,"value":660}," find _site -name \"*.html\" -not -name \"index.html\" -exec rename -v 's/\\.html$//' {} \\;\n",{"type":19,"tag":102,"props":662,"children":664},{"class":104,"line":663},34,[665,669,673],{"type":19,"tag":102,"props":666,"children":667},{"style":188},[668],{"type":24,"value":191},{"type":19,"tag":102,"props":670,"children":671},{"style":126},[672],{"type":24,"value":349},{"type":19,"tag":102,"props":674,"children":675},{"style":132},[676],{"type":24,"value":155},{"type":19,"tag":102,"props":678,"children":680},{"class":104,"line":679},35,[681,685,689],{"type":19,"tag":102,"props":682,"children":683},{"style":126},[684],{"type":24,"value":362},{"type":19,"tag":102,"props":686,"children":687},{"style":132},[688],{"type":24,"value":135},{"type":19,"tag":102,"props":690,"children":691},{"style":115},[692],{"type":24,"value":693}," Index with Algolia\n",{"type":19,"tag":102,"props":695,"children":697},{"class":104,"line":696},36,[698,702,706],{"type":19,"tag":102,"props":699,"children":700},{"style":126},[701],{"type":24,"value":380},{"type":19,"tag":102,"props":703,"children":704},{"style":132},[705],{"type":24,"value":135},{"type":19,"tag":102,"props":707,"children":708},{"style":115},[709],{"type":24,"value":710}," bundle exec jekyll algolia --config _config.yml,_config-publish.yml\n",{"type":19,"tag":102,"props":712,"children":714},{"class":104,"line":713},37,[715,719,724],{"type":19,"tag":102,"props":716,"children":717},{"style":188},[718],{"type":24,"value":191},{"type":19,"tag":102,"props":720,"children":721},{"style":126},[722],{"type":24,"value":723}," store_artifacts",{"type":19,"tag":102,"props":725,"children":726},{"style":132},[727],{"type":24,"value":155},{"type":19,"tag":102,"props":729,"children":731},{"class":104,"line":730},38,[732,737,741],{"type":19,"tag":102,"props":733,"children":734},{"style":126},[735],{"type":24,"value":736},"          path",{"type":19,"tag":102,"props":738,"children":739},{"style":132},[740],{"type":24,"value":135},{"type":19,"tag":102,"props":742,"children":743},{"style":115},[744],{"type":24,"value":745}," run-results/\n",{"type":19,"tag":102,"props":747,"children":749},{"class":104,"line":748},39,[750,755,759],{"type":19,"tag":102,"props":751,"children":752},{"style":126},[753],{"type":24,"value":754},"          destination",{"type":19,"tag":102,"props":756,"children":757},{"style":132},[758],{"type":24,"value":135},{"type":19,"tag":102,"props":760,"children":761},{"style":115},[762],{"type":24,"value":763}," run-results\n",{"type":19,"tag":102,"props":765,"children":767},{"class":104,"line":766},40,[768,772,777],{"type":19,"tag":102,"props":769,"children":770},{"style":188},[771],{"type":24,"value":191},{"type":19,"tag":102,"props":773,"children":774},{"style":126},[775],{"type":24,"value":776}," persist_to_workspace",{"type":19,"tag":102,"props":778,"children":779},{"style":132},[780],{"type":24,"value":155},{"type":19,"tag":102,"props":782,"children":784},{"class":104,"line":783},41,[785,790,794],{"type":19,"tag":102,"props":786,"children":787},{"style":126},[788],{"type":24,"value":789},"          root",{"type":19,"tag":102,"props":791,"children":792},{"style":132},[793],{"type":24,"value":135},{"type":19,"tag":102,"props":795,"children":796},{"style":115},[797],{"type":24,"value":223},{"type":19,"tag":102,"props":799,"children":801},{"class":104,"line":800},42,[802,806],{"type":19,"tag":102,"props":803,"children":804},{"style":126},[805],{"type":24,"value":481},{"type":19,"tag":102,"props":807,"children":808},{"style":132},[809],{"type":24,"value":155},{"type":19,"tag":102,"props":811,"children":813},{"class":104,"line":812},43,[814,818],{"type":19,"tag":102,"props":815,"children":816},{"style":188},[817],{"type":24,"value":494},{"type":19,"tag":102,"props":819,"children":820},{"style":115},[821],{"type":24,"value":822}," _site\n",{"type":19,"tag":102,"props":824,"children":826},{"class":104,"line":825},44,[827,831,836],{"type":19,"tag":102,"props":828,"children":829},{"style":109},[830],{"type":24,"value":112},{"type":19,"tag":102,"props":832,"children":833},{"style":115},[834],{"type":24,"value":835},"endraw%",{"type":19,"tag":102,"props":837,"children":838},{"style":109},[839],{"type":24,"value":840},"}\n",{"type":19,"tag":70,"props":842,"children":844},{"id":843},"deploy",[845],{"type":24,"value":846},"Deploy",{"type":19,"tag":20,"props":848,"children":849},{},[850,852,860],{"type":24,"value":851},"Deploy takes the output from the build job and syncs it with the S3 bucket I use to publish the site. It then applies AWS S3-specific commands using the ",{"type":19,"tag":46,"props":853,"children":857},{"href":854,"rel":855},"https://aws.amazon.com/cli/",[856],"nofollow",[858],{"type":24,"value":859},"AWS CLI",{"type":24,"value":861}," tool to ensure metadata, redirects, and caching are correctly set using a Python environment.",{"type":19,"tag":91,"props":863,"children":865},{"className":93,"code":864,"language":95,"meta":96,"style":96},"{%raw%}  deploy:\n    docker:\n      - image: circleci/python:2.7\n    working_directory: ~/jekyll\n    steps:\n      - attach_workspace:\n          at: ~/jekyll\n      - run:\n          name: Install AWS CLI\n          command: sudo pip install awscli\n      - run:\n          name: Deploy to S3\n          command: aws s3 sync _site s3://damieng-static/ --delete --content-type=text/html\n      - run:\n          name: Correct MIME for robots.txt automatically\n          command: aws s3 cp s3://damieng-static/robots.txt s3://damieng-static/robots.txt --metadata-directive=\"REPLACE\"\n      - run:\n          name: Correct MIME for sitemap.xml automatically\n          command: aws s3 cp s3://damieng-static/sitemap.xml s3://damieng-static/sitemap.xml --metadata-directive=\"REPLACE\"\n      - run:\n          name: Correct MIME for Atom feed manually\n          command: aws s3 cp s3://damieng-static/feed.xml s3://damieng-static/feed.xml --no-guess-mime-type --content-type=\"application/atom+xml\" --metadata-directive=\"REPLACE\"\n      - run:\n          name: Redirect /damieng for existing RSS subscribers\n          command: aws s3api put-object --bucket damieng-static --key \"damieng\" --website-redirect-location \"https://damieng.com/feed.xml\"\n      - run:\n          name: Latest Envy Code R redirect\n          command: aws s3api put-object --bucket damieng-static --key \"envy-code-r\" --website-redirect-location \"https://damieng.com/blog/2008/envy-code-r-preview-7-coding-font-released\"\n      - run:\n          name: Latest Envy Code R redirect #2\n          command: aws s3api put-object --bucket damieng-static --key \"fonts/envy-code-r\" --website-redirect-location \"https://damieng.com/blog/2008/envy-code-r-preview-7-coding-font-released\"\n      - run:\n          name: Latest Envy Code R download\n          command: aws s3api put-object --bucket damieng-static --key \"downloads/latest/EnvyCodeR\" --website-redirect-location \"https://dl.damieng.com/fonts/original/EnvyCodeR-PR7.zip\"\n      - run:\n          name: Correct MIME for CSS files\n          command: aws s3 cp s3://damieng-static/css/ s3://damieng-static/css/ --metadata-directive=\"REPLACE\" --recursive\n{%endraw%}\n",[866],{"type":19,"tag":82,"props":867,"children":868},{"__ignoreMap":96},[869,893,904,924,939,950,966,982,997,1013,1029,1044,1060,1076,1091,1107,1123,1138,1154,1170,1185,1201,1217,1232,1248,1264,1279,1295,1311,1326,1348,1364,1379,1395,1411,1426,1442,1458],{"type":19,"tag":102,"props":870,"children":871},{"class":104,"line":105},[872,876,880,885,889],{"type":19,"tag":102,"props":873,"children":874},{"style":109},[875],{"type":24,"value":112},{"type":19,"tag":102,"props":877,"children":878},{"style":115},[879],{"type":24,"value":118},{"type":19,"tag":102,"props":881,"children":882},{"style":109},[883],{"type":24,"value":884},"}  ",{"type":19,"tag":102,"props":886,"children":887},{"style":126},[888],{"type":24,"value":843},{"type":19,"tag":102,"props":890,"children":891},{"style":132},[892],{"type":24,"value":155},{"type":19,"tag":102,"props":894,"children":895},{"class":104,"line":144},[896,900],{"type":19,"tag":102,"props":897,"children":898},{"style":126},[899],{"type":24,"value":177},{"type":19,"tag":102,"props":901,"children":902},{"style":132},[903],{"type":24,"value":155},{"type":19,"tag":102,"props":905,"children":906},{"class":104,"line":158},[907,911,915,919],{"type":19,"tag":102,"props":908,"children":909},{"style":188},[910],{"type":24,"value":191},{"type":19,"tag":102,"props":912,"children":913},{"style":126},[914],{"type":24,"value":196},{"type":19,"tag":102,"props":916,"children":917},{"style":132},[918],{"type":24,"value":135},{"type":19,"tag":102,"props":920,"children":921},{"style":115},[922],{"type":24,"value":923}," circleci/python:2.7\n",{"type":19,"tag":102,"props":925,"children":926},{"class":104,"line":171},[927,931,935],{"type":19,"tag":102,"props":928,"children":929},{"style":126},[930],{"type":24,"value":214},{"type":19,"tag":102,"props":932,"children":933},{"style":132},[934],{"type":24,"value":135},{"type":19,"tag":102,"props":936,"children":937},{"style":115},[938],{"type":24,"value":223},{"type":19,"tag":102,"props":940,"children":941},{"class":104,"line":184},[942,946],{"type":19,"tag":102,"props":943,"children":944},{"style":126},[945],{"type":24,"value":284},{"type":19,"tag":102,"props":947,"children":948},{"style":132},[949],{"type":24,"value":155},{"type":19,"tag":102,"props":951,"children":952},{"class":104,"line":208},[953,957,962],{"type":19,"tag":102,"props":954,"children":955},{"style":188},[956],{"type":24,"value":191},{"type":19,"tag":102,"props":958,"children":959},{"style":126},[960],{"type":24,"value":961}," attach_workspace",{"type":19,"tag":102,"props":963,"children":964},{"style":132},[965],{"type":24,"value":155},{"type":19,"tag":102,"props":967,"children":968},{"class":104,"line":226},[969,974,978],{"type":19,"tag":102,"props":970,"children":971},{"style":126},[972],{"type":24,"value":973},"          at",{"type":19,"tag":102,"props":975,"children":976},{"style":132},[977],{"type":24,"value":135},{"type":19,"tag":102,"props":979,"children":980},{"style":115},[981],{"type":24,"value":223},{"type":19,"tag":102,"props":983,"children":984},{"class":104,"line":239},[985,989,993],{"type":19,"tag":102,"props":986,"children":987},{"style":188},[988],{"type":24,"value":191},{"type":19,"tag":102,"props":990,"children":991},{"style":126},[992],{"type":24,"value":349},{"type":19,"tag":102,"props":994,"children":995},{"style":132},[996],{"type":24,"value":155},{"type":19,"tag":102,"props":998,"children":999},{"class":104,"line":252},[1000,1004,1008],{"type":19,"tag":102,"props":1001,"children":1002},{"style":126},[1003],{"type":24,"value":362},{"type":19,"tag":102,"props":1005,"children":1006},{"style":132},[1007],{"type":24,"value":135},{"type":19,"tag":102,"props":1009,"children":1010},{"style":115},[1011],{"type":24,"value":1012}," Install AWS CLI\n",{"type":19,"tag":102,"props":1014,"children":1015},{"class":104,"line":265},[1016,1020,1024],{"type":19,"tag":102,"props":1017,"children":1018},{"style":126},[1019],{"type":24,"value":380},{"type":19,"tag":102,"props":1021,"children":1022},{"style":132},[1023],{"type":24,"value":135},{"type":19,"tag":102,"props":1025,"children":1026},{"style":115},[1027],{"type":24,"value":1028}," sudo pip install awscli\n",{"type":19,"tag":102,"props":1030,"children":1031},{"class":104,"line":278},[1032,1036,1040],{"type":19,"tag":102,"props":1033,"children":1034},{"style":188},[1035],{"type":24,"value":191},{"type":19,"tag":102,"props":1037,"children":1038},{"style":126},[1039],{"type":24,"value":349},{"type":19,"tag":102,"props":1041,"children":1042},{"style":132},[1043],{"type":24,"value":155},{"type":19,"tag":102,"props":1045,"children":1046},{"class":104,"line":291},[1047,1051,1055],{"type":19,"tag":102,"props":1048,"children":1049},{"style":126},[1050],{"type":24,"value":362},{"type":19,"tag":102,"props":1052,"children":1053},{"style":132},[1054],{"type":24,"value":135},{"type":19,"tag":102,"props":1056,"children":1057},{"style":115},[1058],{"type":24,"value":1059}," Deploy to S3\n",{"type":19,"tag":102,"props":1061,"children":1062},{"class":104,"line":304},[1063,1067,1071],{"type":19,"tag":102,"props":1064,"children":1065},{"style":126},[1066],{"type":24,"value":380},{"type":19,"tag":102,"props":1068,"children":1069},{"style":132},[1070],{"type":24,"value":135},{"type":19,"tag":102,"props":1072,"children":1073},{"style":115},[1074],{"type":24,"value":1075}," aws s3 sync _site s3://damieng-static/ --delete --content-type=text/html\n",{"type":19,"tag":102,"props":1077,"children":1078},{"class":104,"line":321},[1079,1083,1087],{"type":19,"tag":102,"props":1080,"children":1081},{"style":188},[1082],{"type":24,"value":191},{"type":19,"tag":102,"props":1084,"children":1085},{"style":126},[1086],{"type":24,"value":349},{"type":19,"tag":102,"props":1088,"children":1089},{"style":132},[1090],{"type":24,"value":155},{"type":19,"tag":102,"props":1092,"children":1093},{"class":104,"line":339},[1094,1098,1102],{"type":19,"tag":102,"props":1095,"children":1096},{"style":126},[1097],{"type":24,"value":362},{"type":19,"tag":102,"props":1099,"children":1100},{"style":132},[1101],{"type":24,"value":135},{"type":19,"tag":102,"props":1103,"children":1104},{"style":115},[1105],{"type":24,"value":1106}," Correct MIME for robots.txt automatically\n",{"type":19,"tag":102,"props":1108,"children":1109},{"class":104,"line":356},[1110,1114,1118],{"type":19,"tag":102,"props":1111,"children":1112},{"style":126},[1113],{"type":24,"value":380},{"type":19,"tag":102,"props":1115,"children":1116},{"style":132},[1117],{"type":24,"value":135},{"type":19,"tag":102,"props":1119,"children":1120},{"style":115},[1121],{"type":24,"value":1122}," aws s3 cp s3://damieng-static/robots.txt s3://damieng-static/robots.txt --metadata-directive=\"REPLACE\"\n",{"type":19,"tag":102,"props":1124,"children":1125},{"class":104,"line":374},[1126,1130,1134],{"type":19,"tag":102,"props":1127,"children":1128},{"style":188},[1129],{"type":24,"value":191},{"type":19,"tag":102,"props":1131,"children":1132},{"style":126},[1133],{"type":24,"value":349},{"type":19,"tag":102,"props":1135,"children":1136},{"style":132},[1137],{"type":24,"value":155},{"type":19,"tag":102,"props":1139,"children":1140},{"class":104,"line":392},[1141,1145,1149],{"type":19,"tag":102,"props":1142,"children":1143},{"style":126},[1144],{"type":24,"value":362},{"type":19,"tag":102,"props":1146,"children":1147},{"style":132},[1148],{"type":24,"value":135},{"type":19,"tag":102,"props":1150,"children":1151},{"style":115},[1152],{"type":24,"value":1153}," Correct MIME for sitemap.xml automatically\n",{"type":19,"tag":102,"props":1155,"children":1156},{"class":104,"line":408},[1157,1161,1165],{"type":19,"tag":102,"props":1158,"children":1159},{"style":126},[1160],{"type":24,"value":380},{"type":19,"tag":102,"props":1162,"children":1163},{"style":132},[1164],{"type":24,"value":135},{"type":19,"tag":102,"props":1166,"children":1167},{"style":115},[1168],{"type":24,"value":1169}," aws s3 cp s3://damieng-static/sitemap.xml s3://damieng-static/sitemap.xml --metadata-directive=\"REPLACE\"\n",{"type":19,"tag":102,"props":1171,"children":1172},{"class":104,"line":425},[1173,1177,1181],{"type":19,"tag":102,"props":1174,"children":1175},{"style":188},[1176],{"type":24,"value":191},{"type":19,"tag":102,"props":1178,"children":1179},{"style":126},[1180],{"type":24,"value":349},{"type":19,"tag":102,"props":1182,"children":1183},{"style":132},[1184],{"type":24,"value":155},{"type":19,"tag":102,"props":1186,"children":1187},{"class":104,"line":442},[1188,1192,1196],{"type":19,"tag":102,"props":1189,"children":1190},{"style":126},[1191],{"type":24,"value":362},{"type":19,"tag":102,"props":1193,"children":1194},{"style":132},[1195],{"type":24,"value":135},{"type":19,"tag":102,"props":1197,"children":1198},{"style":115},[1199],{"type":24,"value":1200}," Correct MIME for Atom feed manually\n",{"type":19,"tag":102,"props":1202,"children":1203},{"class":104,"line":459},[1204,1208,1212],{"type":19,"tag":102,"props":1205,"children":1206},{"style":126},[1207],{"type":24,"value":380},{"type":19,"tag":102,"props":1209,"children":1210},{"style":132},[1211],{"type":24,"value":135},{"type":19,"tag":102,"props":1213,"children":1214},{"style":115},[1215],{"type":24,"value":1216}," aws s3 cp s3://damieng-static/feed.xml s3://damieng-static/feed.xml --no-guess-mime-type --content-type=\"application/atom+xml\" --metadata-directive=\"REPLACE\"\n",{"type":19,"tag":102,"props":1218,"children":1219},{"class":104,"line":475},[1220,1224,1228],{"type":19,"tag":102,"props":1221,"children":1222},{"style":188},[1223],{"type":24,"value":191},{"type":19,"tag":102,"props":1225,"children":1226},{"style":126},[1227],{"type":24,"value":349},{"type":19,"tag":102,"props":1229,"children":1230},{"style":132},[1231],{"type":24,"value":155},{"type":19,"tag":102,"props":1233,"children":1234},{"class":104,"line":488},[1235,1239,1243],{"type":19,"tag":102,"props":1236,"children":1237},{"style":126},[1238],{"type":24,"value":362},{"type":19,"tag":102,"props":1240,"children":1241},{"style":132},[1242],{"type":24,"value":135},{"type":19,"tag":102,"props":1244,"children":1245},{"style":115},[1246],{"type":24,"value":1247}," Redirect /damieng for existing RSS subscribers\n",{"type":19,"tag":102,"props":1249,"children":1250},{"class":104,"line":513},[1251,1255,1259],{"type":19,"tag":102,"props":1252,"children":1253},{"style":126},[1254],{"type":24,"value":380},{"type":19,"tag":102,"props":1256,"children":1257},{"style":132},[1258],{"type":24,"value":135},{"type":19,"tag":102,"props":1260,"children":1261},{"style":115},[1262],{"type":24,"value":1263}," aws s3api put-object --bucket damieng-static --key \"damieng\" --website-redirect-location \"https://damieng.com/feed.xml\"\n",{"type":19,"tag":102,"props":1265,"children":1266},{"class":104,"line":529},[1267,1271,1275],{"type":19,"tag":102,"props":1268,"children":1269},{"style":188},[1270],{"type":24,"value":191},{"type":19,"tag":102,"props":1272,"children":1273},{"style":126},[1274],{"type":24,"value":349},{"type":19,"tag":102,"props":1276,"children":1277},{"style":132},[1278],{"type":24,"value":155},{"type":19,"tag":102,"props":1280,"children":1281},{"class":104,"line":546},[1282,1286,1290],{"type":19,"tag":102,"props":1283,"children":1284},{"style":126},[1285],{"type":24,"value":362},{"type":19,"tag":102,"props":1287,"children":1288},{"style":132},[1289],{"type":24,"value":135},{"type":19,"tag":102,"props":1291,"children":1292},{"style":115},[1293],{"type":24,"value":1294}," Latest Envy Code R redirect\n",{"type":19,"tag":102,"props":1296,"children":1297},{"class":104,"line":563},[1298,1302,1306],{"type":19,"tag":102,"props":1299,"children":1300},{"style":126},[1301],{"type":24,"value":380},{"type":19,"tag":102,"props":1303,"children":1304},{"style":132},[1305],{"type":24,"value":135},{"type":19,"tag":102,"props":1307,"children":1308},{"style":115},[1309],{"type":24,"value":1310}," aws s3api put-object --bucket damieng-static --key \"envy-code-r\" --website-redirect-location \"https://damieng.com/blog/2008/envy-code-r-preview-7-coding-font-released\"\n",{"type":19,"tag":102,"props":1312,"children":1313},{"class":104,"line":579},[1314,1318,1322],{"type":19,"tag":102,"props":1315,"children":1316},{"style":188},[1317],{"type":24,"value":191},{"type":19,"tag":102,"props":1319,"children":1320},{"style":126},[1321],{"type":24,"value":349},{"type":19,"tag":102,"props":1323,"children":1324},{"style":132},[1325],{"type":24,"value":155},{"type":19,"tag":102,"props":1327,"children":1328},{"class":104,"line":596},[1329,1333,1337,1342],{"type":19,"tag":102,"props":1330,"children":1331},{"style":126},[1332],{"type":24,"value":362},{"type":19,"tag":102,"props":1334,"children":1335},{"style":132},[1336],{"type":24,"value":135},{"type":19,"tag":102,"props":1338,"children":1339},{"style":115},[1340],{"type":24,"value":1341}," Latest Envy Code R redirect",{"type":19,"tag":102,"props":1343,"children":1345},{"style":1344},"--shiki-default:#939F91;--shiki-default-font-style:italic;--shiki-dark:#6272A4;--shiki-dark-font-style:inherit",[1346],{"type":24,"value":1347}," #2\n",{"type":19,"tag":102,"props":1349,"children":1350},{"class":104,"line":613},[1351,1355,1359],{"type":19,"tag":102,"props":1352,"children":1353},{"style":126},[1354],{"type":24,"value":380},{"type":19,"tag":102,"props":1356,"children":1357},{"style":132},[1358],{"type":24,"value":135},{"type":19,"tag":102,"props":1360,"children":1361},{"style":115},[1362],{"type":24,"value":1363}," aws s3api put-object --bucket damieng-static --key \"fonts/envy-code-r\" --website-redirect-location \"https://damieng.com/blog/2008/envy-code-r-preview-7-coding-font-released\"\n",{"type":19,"tag":102,"props":1365,"children":1366},{"class":104,"line":629},[1367,1371,1375],{"type":19,"tag":102,"props":1368,"children":1369},{"style":188},[1370],{"type":24,"value":191},{"type":19,"tag":102,"props":1372,"children":1373},{"style":126},[1374],{"type":24,"value":349},{"type":19,"tag":102,"props":1376,"children":1377},{"style":132},[1378],{"type":24,"value":155},{"type":19,"tag":102,"props":1380,"children":1381},{"class":104,"line":646},[1382,1386,1390],{"type":19,"tag":102,"props":1383,"children":1384},{"style":126},[1385],{"type":24,"value":362},{"type":19,"tag":102,"props":1387,"children":1388},{"style":132},[1389],{"type":24,"value":135},{"type":19,"tag":102,"props":1391,"children":1392},{"style":115},[1393],{"type":24,"value":1394}," Latest Envy Code R download\n",{"type":19,"tag":102,"props":1396,"children":1397},{"class":104,"line":663},[1398,1402,1406],{"type":19,"tag":102,"props":1399,"children":1400},{"style":126},[1401],{"type":24,"value":380},{"type":19,"tag":102,"props":1403,"children":1404},{"style":132},[1405],{"type":24,"value":135},{"type":19,"tag":102,"props":1407,"children":1408},{"style":115},[1409],{"type":24,"value":1410}," aws s3api put-object --bucket damieng-static --key \"downloads/latest/EnvyCodeR\" --website-redirect-location \"https://dl.damieng.com/fonts/original/EnvyCodeR-PR7.zip\"\n",{"type":19,"tag":102,"props":1412,"children":1413},{"class":104,"line":679},[1414,1418,1422],{"type":19,"tag":102,"props":1415,"children":1416},{"style":188},[1417],{"type":24,"value":191},{"type":19,"tag":102,"props":1419,"children":1420},{"style":126},[1421],{"type":24,"value":349},{"type":19,"tag":102,"props":1423,"children":1424},{"style":132},[1425],{"type":24,"value":155},{"type":19,"tag":102,"props":1427,"children":1428},{"class":104,"line":696},[1429,1433,1437],{"type":19,"tag":102,"props":1430,"children":1431},{"style":126},[1432],{"type":24,"value":362},{"type":19,"tag":102,"props":1434,"children":1435},{"style":132},[1436],{"type":24,"value":135},{"type":19,"tag":102,"props":1438,"children":1439},{"style":115},[1440],{"type":24,"value":1441}," Correct MIME for CSS files\n",{"type":19,"tag":102,"props":1443,"children":1444},{"class":104,"line":713},[1445,1449,1453],{"type":19,"tag":102,"props":1446,"children":1447},{"style":126},[1448],{"type":24,"value":380},{"type":19,"tag":102,"props":1450,"children":1451},{"style":132},[1452],{"type":24,"value":135},{"type":19,"tag":102,"props":1454,"children":1455},{"style":115},[1456],{"type":24,"value":1457}," aws s3 cp s3://damieng-static/css/ s3://damieng-static/css/ --metadata-directive=\"REPLACE\" --recursive\n",{"type":19,"tag":102,"props":1459,"children":1460},{"class":104,"line":730},[1461,1465,1469],{"type":19,"tag":102,"props":1462,"children":1463},{"style":109},[1464],{"type":24,"value":112},{"type":19,"tag":102,"props":1466,"children":1467},{"style":115},[1468],{"type":24,"value":835},{"type":19,"tag":102,"props":1470,"children":1471},{"style":109},[1472],{"type":24,"value":840},{"type":19,"tag":53,"props":1474,"children":1476},{"id":1475},"github-actions",[1477],{"type":24,"value":1478},"GitHub Actions",{"type":19,"tag":20,"props":1480,"children":1481},{},[1482],{"type":24,"value":1483},"So how could I go about this in GitHub Actions? I have to admit I spent far too long poking around and examining existing Jekyll actions. I have a bunch of steps here I need fine control of, especially around Algolia and S3. I finally ended up on what was quite a simple port.",{"type":19,"tag":20,"props":1485,"children":1486},{},[1487],{"type":24,"value":1488},"Unlike the CircleCI configuration, I did not split these into two separate jobs because:",{"type":19,"tag":1490,"props":1491,"children":1492},"ol",{},[1493,1513,1518,1523],{"type":19,"tag":1494,"props":1495,"children":1496},"li",{},[1497,1499,1505,1507],{"type":24,"value":1498},"There is no exact equivalent to ",{"type":19,"tag":82,"props":1500,"children":1502},{"className":1501},[],[1503],{"type":24,"value":1504},"persist_to_workspace",{"type":24,"value":1506}," and ",{"type":19,"tag":82,"props":1508,"children":1510},{"className":1509},[],[1511],{"type":24,"value":1512},"attach_workspace",{"type":19,"tag":1494,"props":1514,"children":1515},{},[1516],{"type":24,"value":1517},"The alternative of storing and restoring the artifacts leaves large useless artifacts around",{"type":19,"tag":1494,"props":1519,"children":1520},{},[1521],{"type":24,"value":1522},"I never ended up running the jobs separately",{"type":19,"tag":1494,"props":1524,"children":1525},{},[1526],{"type":24,"value":1527},"GitHub Actions provides an environment with both Ruby and AWS CLI installed",{"type":19,"tag":20,"props":1529,"children":1530},{},[1531,1533,1539],{"type":24,"value":1532},"So, on to the configuration which lives in ",{"type":19,"tag":82,"props":1534,"children":1536},{"className":1535},[],[1537],{"type":24,"value":1538},".github/workflows/jekyll.yml",{"type":24,"value":1540}," in my case:",{"type":19,"tag":91,"props":1542,"children":1544},{"className":93,"code":1543,"language":95,"meta":96,"style":96},"{%raw%}name: Build site and deploy\n\non:\n  push:\n    branches: [ master ]\n\njobs:\n  build:\n    name: Build + Deploy\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v2\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: 2.6.1\n\n      - name: Ruby gem cache\n        uses: actions/cache@v1\n        with:\n          path: vendor/bundle\n          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}\n          restore-keys: |\n            ${{ runner.os }}-gems-\n\n      - name: Install dependencies\n        run: |\n          bundle config path vendor/bundle\n          bundle install --jobs 4 --retry 3\n\n      - name: Build Jekyll site\n        run:  bundle exec jekyll build --config _config.yml,_config-publish.yml\n\n      - name: Remove .html suffixes except for index.html\n        run: find _site -name \"*.html\" -not -name \"index.html\" | while read f; do mv \"$f\" \"${f%.html}\"; done\n\n      - name: Index with Algolia\n        env:\n          ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}\n        run:  bundle exec jekyll algolia --config _config.yml,_config-publish.yml\n\n      - name: Configure AWS credentials\n        uses: aws-actions/configure-aws-credentials@v1\n        with:\n          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n          aws-region: us-east-1\n\n      - name: Sync site with S3\n        run:  aws s3 sync _site s3://damieng-static/ --delete --content-type=text/html\n\n      - name: Correct MIME types\n        run: |\n          aws s3 cp s3://damieng-static/ s3://damieng-static/ --exclude \"*\" --include \"*.txt\" --metadata-directive=\"REPLACE\"\n          aws s3 cp s3://damieng-static/sitemap.xml s3://damieng-static/sitemap.xml --metadata-directive=\"REPLACE\"\n          aws s3 cp s3://damieng-static/feed.xml s3://damieng-static/feed.xml --no-guess-mime-type --content-type \"application/atom+xml\" --metadata-directive \"REPLACE\"\n          aws s3 cp s3://damieng-static/css/ s3://damieng-static/css/ --metadata-directive \"REPLACE\" --recursive\n          aws s3 cp s3://damieng-static/js/ s3://damieng-static/js/ --metadata-directive \"REPLACE\" --recursive\n\n      - name: Redirect /damieng for existing RSS subscribers\n        run:  aws s3api put-object --bucket damieng-static --key \"damieng\" --website-redirect-location \"https://damieng.com/feed.xml\"\n\n      - name: Latest Envy Code R redirects\n        run:  |\n          aws s3api put-object --bucket damieng-static --key \"fonts/envy-code-r\" --website-redirect-location \"https://damieng.com/blog/2008/envy-code-r-preview-7-coding-font-released\"\n          aws s3api put-object --bucket damieng-static --key \"downloads/latest/EnvyCodeR\" --website-redirect-location \"https://dl.damieng.com/fonts/original/EnvyCodeR-PR7.zip\"\n\n      - name: Set caching for images at 30 days\n        run:  aws s3 cp s3://damieng-static/ s3://damieng-static/ --exclude \"*\" --include \"*.svg\" --include \"*.ico\" --include \"*.jpg\" --include \"*.png\" --include \"*.webp\" --include \"*.gif\" --recursive --metadata-directive REPLACE --expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public\n\n      - name: Set caching for CSS and JS at 1 hour\n        run:  aws s3 cp s3://damieng-static/ s3://damieng-static/ --exclude \"*\" --include \"*.css\" --include \"*.js\" --recursive --metadata-directive REPLACE --expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=3600,public\n{%endraw%}\n",[1545],{"type":19,"tag":82,"props":1546,"children":1547},{"__ignoreMap":96},[1548,1577,1586,1598,1610,1637,1644,1655,1666,1683,1700,1711,1732,1749,1756,1776,1792,1804,1821,1828,1848,1864,1875,1891,1907,1925,1933,1940,1959,1975,1983,1991,1998,2018,2034,2041,2061,2077,2084,2103,2115,2132,2148,2155,2175,2192,2204,2222,2240,2258,2266,2287,2304,2312,2333,2349,2358,2367,2376,2385,2394,2402,2422,2439,2447,2468,2485,2494,2503,2511,2532,2549,2557,2578,2595],{"type":19,"tag":102,"props":1549,"children":1550},{"class":104,"line":105},[1551,1555,1559,1563,1568,1572],{"type":19,"tag":102,"props":1552,"children":1553},{"style":109},[1554],{"type":24,"value":112},{"type":19,"tag":102,"props":1556,"children":1557},{"style":115},[1558],{"type":24,"value":118},{"type":19,"tag":102,"props":1560,"children":1561},{"style":109},[1562],{"type":24,"value":123},{"type":19,"tag":102,"props":1564,"children":1565},{"style":126},[1566],{"type":24,"value":1567},"name",{"type":19,"tag":102,"props":1569,"children":1570},{"style":132},[1571],{"type":24,"value":135},{"type":19,"tag":102,"props":1573,"children":1574},{"style":115},[1575],{"type":24,"value":1576}," Build site and deploy\n",{"type":19,"tag":102,"props":1578,"children":1579},{"class":104,"line":144},[1580],{"type":19,"tag":102,"props":1581,"children":1583},{"emptyLinePlaceholder":1582},true,[1584],{"type":24,"value":1585},"\n",{"type":19,"tag":102,"props":1587,"children":1588},{"class":104,"line":158},[1589,1594],{"type":19,"tag":102,"props":1590,"children":1591},{"style":138},[1592],{"type":24,"value":1593},"on",{"type":19,"tag":102,"props":1595,"children":1596},{"style":132},[1597],{"type":24,"value":155},{"type":19,"tag":102,"props":1599,"children":1600},{"class":104,"line":171},[1601,1606],{"type":19,"tag":102,"props":1602,"children":1603},{"style":126},[1604],{"type":24,"value":1605},"  push",{"type":19,"tag":102,"props":1607,"children":1608},{"style":132},[1609],{"type":24,"value":155},{"type":19,"tag":102,"props":1611,"children":1612},{"class":104,"line":184},[1613,1618,1622,1627,1632],{"type":19,"tag":102,"props":1614,"children":1615},{"style":126},[1616],{"type":24,"value":1617},"    branches",{"type":19,"tag":102,"props":1619,"children":1620},{"style":132},[1621],{"type":24,"value":135},{"type":19,"tag":102,"props":1623,"children":1624},{"style":109},[1625],{"type":24,"value":1626}," [ ",{"type":19,"tag":102,"props":1628,"children":1629},{"style":115},[1630],{"type":24,"value":1631},"master",{"type":19,"tag":102,"props":1633,"children":1634},{"style":109},[1635],{"type":24,"value":1636}," ]\n",{"type":19,"tag":102,"props":1638,"children":1639},{"class":104,"line":208},[1640],{"type":19,"tag":102,"props":1641,"children":1642},{"emptyLinePlaceholder":1582},[1643],{"type":24,"value":1585},{"type":19,"tag":102,"props":1645,"children":1646},{"class":104,"line":226},[1647,1651],{"type":19,"tag":102,"props":1648,"children":1649},{"style":126},[1650],{"type":24,"value":150},{"type":19,"tag":102,"props":1652,"children":1653},{"style":132},[1654],{"type":24,"value":155},{"type":19,"tag":102,"props":1656,"children":1657},{"class":104,"line":239},[1658,1662],{"type":19,"tag":102,"props":1659,"children":1660},{"style":126},[1661],{"type":24,"value":164},{"type":19,"tag":102,"props":1663,"children":1664},{"style":132},[1665],{"type":24,"value":155},{"type":19,"tag":102,"props":1667,"children":1668},{"class":104,"line":252},[1669,1674,1678],{"type":19,"tag":102,"props":1670,"children":1671},{"style":126},[1672],{"type":24,"value":1673},"    name",{"type":19,"tag":102,"props":1675,"children":1676},{"style":132},[1677],{"type":24,"value":135},{"type":19,"tag":102,"props":1679,"children":1680},{"style":115},[1681],{"type":24,"value":1682}," Build + Deploy\n",{"type":19,"tag":102,"props":1684,"children":1685},{"class":104,"line":265},[1686,1691,1695],{"type":19,"tag":102,"props":1687,"children":1688},{"style":126},[1689],{"type":24,"value":1690},"    runs-on",{"type":19,"tag":102,"props":1692,"children":1693},{"style":132},[1694],{"type":24,"value":135},{"type":19,"tag":102,"props":1696,"children":1697},{"style":115},[1698],{"type":24,"value":1699}," ubuntu-latest\n",{"type":19,"tag":102,"props":1701,"children":1702},{"class":104,"line":278},[1703,1707],{"type":19,"tag":102,"props":1704,"children":1705},{"style":126},[1706],{"type":24,"value":284},{"type":19,"tag":102,"props":1708,"children":1709},{"style":132},[1710],{"type":24,"value":155},{"type":19,"tag":102,"props":1712,"children":1713},{"class":104,"line":291},[1714,1718,1723,1727],{"type":19,"tag":102,"props":1715,"children":1716},{"style":188},[1717],{"type":24,"value":191},{"type":19,"tag":102,"props":1719,"children":1720},{"style":126},[1721],{"type":24,"value":1722}," name",{"type":19,"tag":102,"props":1724,"children":1725},{"style":132},[1726],{"type":24,"value":135},{"type":19,"tag":102,"props":1728,"children":1729},{"style":115},[1730],{"type":24,"value":1731}," Checkout code\n",{"type":19,"tag":102,"props":1733,"children":1734},{"class":104,"line":304},[1735,1740,1744],{"type":19,"tag":102,"props":1736,"children":1737},{"style":126},[1738],{"type":24,"value":1739},"        uses",{"type":19,"tag":102,"props":1741,"children":1742},{"style":132},[1743],{"type":24,"value":135},{"type":19,"tag":102,"props":1745,"children":1746},{"style":115},[1747],{"type":24,"value":1748}," actions/checkout@v2\n",{"type":19,"tag":102,"props":1750,"children":1751},{"class":104,"line":321},[1752],{"type":19,"tag":102,"props":1753,"children":1754},{"emptyLinePlaceholder":1582},[1755],{"type":24,"value":1585},{"type":19,"tag":102,"props":1757,"children":1758},{"class":104,"line":339},[1759,1763,1767,1771],{"type":19,"tag":102,"props":1760,"children":1761},{"style":188},[1762],{"type":24,"value":191},{"type":19,"tag":102,"props":1764,"children":1765},{"style":126},[1766],{"type":24,"value":1722},{"type":19,"tag":102,"props":1768,"children":1769},{"style":132},[1770],{"type":24,"value":135},{"type":19,"tag":102,"props":1772,"children":1773},{"style":115},[1774],{"type":24,"value":1775}," Setup Ruby\n",{"type":19,"tag":102,"props":1777,"children":1778},{"class":104,"line":356},[1779,1783,1787],{"type":19,"tag":102,"props":1780,"children":1781},{"style":126},[1782],{"type":24,"value":1739},{"type":19,"tag":102,"props":1784,"children":1785},{"style":132},[1786],{"type":24,"value":135},{"type":19,"tag":102,"props":1788,"children":1789},{"style":115},[1790],{"type":24,"value":1791}," ruby/setup-ruby@v1\n",{"type":19,"tag":102,"props":1793,"children":1794},{"class":104,"line":374},[1795,1800],{"type":19,"tag":102,"props":1796,"children":1797},{"style":126},[1798],{"type":24,"value":1799},"        with",{"type":19,"tag":102,"props":1801,"children":1802},{"style":132},[1803],{"type":24,"value":155},{"type":19,"tag":102,"props":1805,"children":1806},{"class":104,"line":392},[1807,1812,1816],{"type":19,"tag":102,"props":1808,"children":1809},{"style":126},[1810],{"type":24,"value":1811},"          ruby-version",{"type":19,"tag":102,"props":1813,"children":1814},{"style":132},[1815],{"type":24,"value":135},{"type":19,"tag":102,"props":1817,"children":1818},{"style":138},[1819],{"type":24,"value":1820}," 2.6.1\n",{"type":19,"tag":102,"props":1822,"children":1823},{"class":104,"line":408},[1824],{"type":19,"tag":102,"props":1825,"children":1826},{"emptyLinePlaceholder":1582},[1827],{"type":24,"value":1585},{"type":19,"tag":102,"props":1829,"children":1830},{"class":104,"line":425},[1831,1835,1839,1843],{"type":19,"tag":102,"props":1832,"children":1833},{"style":188},[1834],{"type":24,"value":191},{"type":19,"tag":102,"props":1836,"children":1837},{"style":126},[1838],{"type":24,"value":1722},{"type":19,"tag":102,"props":1840,"children":1841},{"style":132},[1842],{"type":24,"value":135},{"type":19,"tag":102,"props":1844,"children":1845},{"style":115},[1846],{"type":24,"value":1847}," Ruby gem cache\n",{"type":19,"tag":102,"props":1849,"children":1850},{"class":104,"line":442},[1851,1855,1859],{"type":19,"tag":102,"props":1852,"children":1853},{"style":126},[1854],{"type":24,"value":1739},{"type":19,"tag":102,"props":1856,"children":1857},{"style":132},[1858],{"type":24,"value":135},{"type":19,"tag":102,"props":1860,"children":1861},{"style":115},[1862],{"type":24,"value":1863}," actions/cache@v1\n",{"type":19,"tag":102,"props":1865,"children":1866},{"class":104,"line":459},[1867,1871],{"type":19,"tag":102,"props":1868,"children":1869},{"style":126},[1870],{"type":24,"value":1799},{"type":19,"tag":102,"props":1872,"children":1873},{"style":132},[1874],{"type":24,"value":155},{"type":19,"tag":102,"props":1876,"children":1877},{"class":104,"line":475},[1878,1882,1886],{"type":19,"tag":102,"props":1879,"children":1880},{"style":126},[1881],{"type":24,"value":736},{"type":19,"tag":102,"props":1883,"children":1884},{"style":132},[1885],{"type":24,"value":135},{"type":19,"tag":102,"props":1887,"children":1888},{"style":115},[1889],{"type":24,"value":1890}," vendor/bundle\n",{"type":19,"tag":102,"props":1892,"children":1893},{"class":104,"line":488},[1894,1898,1902],{"type":19,"tag":102,"props":1895,"children":1896},{"style":126},[1897],{"type":24,"value":327},{"type":19,"tag":102,"props":1899,"children":1900},{"style":132},[1901],{"type":24,"value":135},{"type":19,"tag":102,"props":1903,"children":1904},{"style":115},[1905],{"type":24,"value":1906}," ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}\n",{"type":19,"tag":102,"props":1908,"children":1909},{"class":104,"line":513},[1910,1915,1919],{"type":19,"tag":102,"props":1911,"children":1912},{"style":126},[1913],{"type":24,"value":1914},"          restore-keys",{"type":19,"tag":102,"props":1916,"children":1917},{"style":132},[1918],{"type":24,"value":135},{"type":19,"tag":102,"props":1920,"children":1922},{"style":1921},"--shiki-default:#F85552;--shiki-dark:#FF79C6",[1923],{"type":24,"value":1924}," |\n",{"type":19,"tag":102,"props":1926,"children":1927},{"class":104,"line":529},[1928],{"type":19,"tag":102,"props":1929,"children":1930},{"style":115},[1931],{"type":24,"value":1932},"            ${{ runner.os }}-gems-\n",{"type":19,"tag":102,"props":1934,"children":1935},{"class":104,"line":546},[1936],{"type":19,"tag":102,"props":1937,"children":1938},{"emptyLinePlaceholder":1582},[1939],{"type":24,"value":1585},{"type":19,"tag":102,"props":1941,"children":1942},{"class":104,"line":563},[1943,1947,1951,1955],{"type":19,"tag":102,"props":1944,"children":1945},{"style":188},[1946],{"type":24,"value":191},{"type":19,"tag":102,"props":1948,"children":1949},{"style":126},[1950],{"type":24,"value":1722},{"type":19,"tag":102,"props":1952,"children":1953},{"style":132},[1954],{"type":24,"value":135},{"type":19,"tag":102,"props":1956,"children":1957},{"style":115},[1958],{"type":24,"value":422},{"type":19,"tag":102,"props":1960,"children":1961},{"class":104,"line":579},[1962,1967,1971],{"type":19,"tag":102,"props":1963,"children":1964},{"style":126},[1965],{"type":24,"value":1966},"        run",{"type":19,"tag":102,"props":1968,"children":1969},{"style":132},[1970],{"type":24,"value":135},{"type":19,"tag":102,"props":1972,"children":1973},{"style":1921},[1974],{"type":24,"value":1924},{"type":19,"tag":102,"props":1976,"children":1977},{"class":104,"line":596},[1978],{"type":19,"tag":102,"props":1979,"children":1980},{"style":115},[1981],{"type":24,"value":1982},"          bundle config path vendor/bundle\n",{"type":19,"tag":102,"props":1984,"children":1985},{"class":104,"line":613},[1986],{"type":19,"tag":102,"props":1987,"children":1988},{"style":115},[1989],{"type":24,"value":1990},"          bundle install --jobs 4 --retry 3\n",{"type":19,"tag":102,"props":1992,"children":1993},{"class":104,"line":629},[1994],{"type":19,"tag":102,"props":1995,"children":1996},{"emptyLinePlaceholder":1582},[1997],{"type":24,"value":1585},{"type":19,"tag":102,"props":1999,"children":2000},{"class":104,"line":646},[2001,2005,2009,2013],{"type":19,"tag":102,"props":2002,"children":2003},{"style":188},[2004],{"type":24,"value":191},{"type":19,"tag":102,"props":2006,"children":2007},{"style":126},[2008],{"type":24,"value":1722},{"type":19,"tag":102,"props":2010,"children":2011},{"style":132},[2012],{"type":24,"value":135},{"type":19,"tag":102,"props":2014,"children":2015},{"style":115},[2016],{"type":24,"value":2017}," Build Jekyll site\n",{"type":19,"tag":102,"props":2019,"children":2020},{"class":104,"line":663},[2021,2025,2029],{"type":19,"tag":102,"props":2022,"children":2023},{"style":126},[2024],{"type":24,"value":1966},{"type":19,"tag":102,"props":2026,"children":2027},{"style":132},[2028],{"type":24,"value":135},{"type":19,"tag":102,"props":2030,"children":2031},{"style":115},[2032],{"type":24,"value":2033},"  bundle exec jekyll build --config _config.yml,_config-publish.yml\n",{"type":19,"tag":102,"props":2035,"children":2036},{"class":104,"line":679},[2037],{"type":19,"tag":102,"props":2038,"children":2039},{"emptyLinePlaceholder":1582},[2040],{"type":24,"value":1585},{"type":19,"tag":102,"props":2042,"children":2043},{"class":104,"line":696},[2044,2048,2052,2056],{"type":19,"tag":102,"props":2045,"children":2046},{"style":188},[2047],{"type":24,"value":191},{"type":19,"tag":102,"props":2049,"children":2050},{"style":126},[2051],{"type":24,"value":1722},{"type":19,"tag":102,"props":2053,"children":2054},{"style":132},[2055],{"type":24,"value":135},{"type":19,"tag":102,"props":2057,"children":2058},{"style":115},[2059],{"type":24,"value":2060}," Remove .html suffixes except for index.html\n",{"type":19,"tag":102,"props":2062,"children":2063},{"class":104,"line":713},[2064,2068,2072],{"type":19,"tag":102,"props":2065,"children":2066},{"style":126},[2067],{"type":24,"value":1966},{"type":19,"tag":102,"props":2069,"children":2070},{"style":132},[2071],{"type":24,"value":135},{"type":19,"tag":102,"props":2073,"children":2074},{"style":115},[2075],{"type":24,"value":2076}," find _site -name \"*.html\" -not -name \"index.html\" | while read f; do mv \"$f\" \"${f%.html}\"; done\n",{"type":19,"tag":102,"props":2078,"children":2079},{"class":104,"line":730},[2080],{"type":19,"tag":102,"props":2081,"children":2082},{"emptyLinePlaceholder":1582},[2083],{"type":24,"value":1585},{"type":19,"tag":102,"props":2085,"children":2086},{"class":104,"line":748},[2087,2091,2095,2099],{"type":19,"tag":102,"props":2088,"children":2089},{"style":188},[2090],{"type":24,"value":191},{"type":19,"tag":102,"props":2092,"children":2093},{"style":126},[2094],{"type":24,"value":1722},{"type":19,"tag":102,"props":2096,"children":2097},{"style":132},[2098],{"type":24,"value":135},{"type":19,"tag":102,"props":2100,"children":2101},{"style":115},[2102],{"type":24,"value":693},{"type":19,"tag":102,"props":2104,"children":2105},{"class":104,"line":766},[2106,2111],{"type":19,"tag":102,"props":2107,"children":2108},{"style":126},[2109],{"type":24,"value":2110},"        env",{"type":19,"tag":102,"props":2112,"children":2113},{"style":132},[2114],{"type":24,"value":155},{"type":19,"tag":102,"props":2116,"children":2117},{"class":104,"line":783},[2118,2123,2127],{"type":19,"tag":102,"props":2119,"children":2120},{"style":126},[2121],{"type":24,"value":2122},"          ALGOLIA_API_KEY",{"type":19,"tag":102,"props":2124,"children":2125},{"style":132},[2126],{"type":24,"value":135},{"type":19,"tag":102,"props":2128,"children":2129},{"style":115},[2130],{"type":24,"value":2131}," ${{ secrets.ALGOLIA_API_KEY }}\n",{"type":19,"tag":102,"props":2133,"children":2134},{"class":104,"line":800},[2135,2139,2143],{"type":19,"tag":102,"props":2136,"children":2137},{"style":126},[2138],{"type":24,"value":1966},{"type":19,"tag":102,"props":2140,"children":2141},{"style":132},[2142],{"type":24,"value":135},{"type":19,"tag":102,"props":2144,"children":2145},{"style":115},[2146],{"type":24,"value":2147},"  bundle exec jekyll algolia --config _config.yml,_config-publish.yml\n",{"type":19,"tag":102,"props":2149,"children":2150},{"class":104,"line":812},[2151],{"type":19,"tag":102,"props":2152,"children":2153},{"emptyLinePlaceholder":1582},[2154],{"type":24,"value":1585},{"type":19,"tag":102,"props":2156,"children":2157},{"class":104,"line":825},[2158,2162,2166,2170],{"type":19,"tag":102,"props":2159,"children":2160},{"style":188},[2161],{"type":24,"value":191},{"type":19,"tag":102,"props":2163,"children":2164},{"style":126},[2165],{"type":24,"value":1722},{"type":19,"tag":102,"props":2167,"children":2168},{"style":132},[2169],{"type":24,"value":135},{"type":19,"tag":102,"props":2171,"children":2172},{"style":115},[2173],{"type":24,"value":2174}," Configure AWS credentials\n",{"type":19,"tag":102,"props":2176,"children":2178},{"class":104,"line":2177},45,[2179,2183,2187],{"type":19,"tag":102,"props":2180,"children":2181},{"style":126},[2182],{"type":24,"value":1739},{"type":19,"tag":102,"props":2184,"children":2185},{"style":132},[2186],{"type":24,"value":135},{"type":19,"tag":102,"props":2188,"children":2189},{"style":115},[2190],{"type":24,"value":2191}," aws-actions/configure-aws-credentials@v1\n",{"type":19,"tag":102,"props":2193,"children":2195},{"class":104,"line":2194},46,[2196,2200],{"type":19,"tag":102,"props":2197,"children":2198},{"style":126},[2199],{"type":24,"value":1799},{"type":19,"tag":102,"props":2201,"children":2202},{"style":132},[2203],{"type":24,"value":155},{"type":19,"tag":102,"props":2205,"children":2207},{"class":104,"line":2206},47,[2208,2213,2217],{"type":19,"tag":102,"props":2209,"children":2210},{"style":126},[2211],{"type":24,"value":2212},"          aws-access-key-id",{"type":19,"tag":102,"props":2214,"children":2215},{"style":132},[2216],{"type":24,"value":135},{"type":19,"tag":102,"props":2218,"children":2219},{"style":115},[2220],{"type":24,"value":2221}," ${{ secrets.AWS_ACCESS_KEY_ID }}\n",{"type":19,"tag":102,"props":2223,"children":2225},{"class":104,"line":2224},48,[2226,2231,2235],{"type":19,"tag":102,"props":2227,"children":2228},{"style":126},[2229],{"type":24,"value":2230},"          aws-secret-access-key",{"type":19,"tag":102,"props":2232,"children":2233},{"style":132},[2234],{"type":24,"value":135},{"type":19,"tag":102,"props":2236,"children":2237},{"style":115},[2238],{"type":24,"value":2239}," ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n",{"type":19,"tag":102,"props":2241,"children":2243},{"class":104,"line":2242},49,[2244,2249,2253],{"type":19,"tag":102,"props":2245,"children":2246},{"style":126},[2247],{"type":24,"value":2248},"          aws-region",{"type":19,"tag":102,"props":2250,"children":2251},{"style":132},[2252],{"type":24,"value":135},{"type":19,"tag":102,"props":2254,"children":2255},{"style":115},[2256],{"type":24,"value":2257}," us-east-1\n",{"type":19,"tag":102,"props":2259,"children":2261},{"class":104,"line":2260},50,[2262],{"type":19,"tag":102,"props":2263,"children":2264},{"emptyLinePlaceholder":1582},[2265],{"type":24,"value":1585},{"type":19,"tag":102,"props":2267,"children":2269},{"class":104,"line":2268},51,[2270,2274,2278,2282],{"type":19,"tag":102,"props":2271,"children":2272},{"style":188},[2273],{"type":24,"value":191},{"type":19,"tag":102,"props":2275,"children":2276},{"style":126},[2277],{"type":24,"value":1722},{"type":19,"tag":102,"props":2279,"children":2280},{"style":132},[2281],{"type":24,"value":135},{"type":19,"tag":102,"props":2283,"children":2284},{"style":115},[2285],{"type":24,"value":2286}," Sync site with S3\n",{"type":19,"tag":102,"props":2288,"children":2290},{"class":104,"line":2289},52,[2291,2295,2299],{"type":19,"tag":102,"props":2292,"children":2293},{"style":126},[2294],{"type":24,"value":1966},{"type":19,"tag":102,"props":2296,"children":2297},{"style":132},[2298],{"type":24,"value":135},{"type":19,"tag":102,"props":2300,"children":2301},{"style":115},[2302],{"type":24,"value":2303},"  aws s3 sync _site s3://damieng-static/ --delete --content-type=text/html\n",{"type":19,"tag":102,"props":2305,"children":2307},{"class":104,"line":2306},53,[2308],{"type":19,"tag":102,"props":2309,"children":2310},{"emptyLinePlaceholder":1582},[2311],{"type":24,"value":1585},{"type":19,"tag":102,"props":2313,"children":2315},{"class":104,"line":2314},54,[2316,2320,2324,2328],{"type":19,"tag":102,"props":2317,"children":2318},{"style":188},[2319],{"type":24,"value":191},{"type":19,"tag":102,"props":2321,"children":2322},{"style":126},[2323],{"type":24,"value":1722},{"type":19,"tag":102,"props":2325,"children":2326},{"style":132},[2327],{"type":24,"value":135},{"type":19,"tag":102,"props":2329,"children":2330},{"style":115},[2331],{"type":24,"value":2332}," Correct MIME types\n",{"type":19,"tag":102,"props":2334,"children":2336},{"class":104,"line":2335},55,[2337,2341,2345],{"type":19,"tag":102,"props":2338,"children":2339},{"style":126},[2340],{"type":24,"value":1966},{"type":19,"tag":102,"props":2342,"children":2343},{"style":132},[2344],{"type":24,"value":135},{"type":19,"tag":102,"props":2346,"children":2347},{"style":1921},[2348],{"type":24,"value":1924},{"type":19,"tag":102,"props":2350,"children":2352},{"class":104,"line":2351},56,[2353],{"type":19,"tag":102,"props":2354,"children":2355},{"style":115},[2356],{"type":24,"value":2357},"          aws s3 cp s3://damieng-static/ s3://damieng-static/ --exclude \"*\" --include \"*.txt\" --metadata-directive=\"REPLACE\"\n",{"type":19,"tag":102,"props":2359,"children":2361},{"class":104,"line":2360},57,[2362],{"type":19,"tag":102,"props":2363,"children":2364},{"style":115},[2365],{"type":24,"value":2366},"          aws s3 cp s3://damieng-static/sitemap.xml s3://damieng-static/sitemap.xml --metadata-directive=\"REPLACE\"\n",{"type":19,"tag":102,"props":2368,"children":2370},{"class":104,"line":2369},58,[2371],{"type":19,"tag":102,"props":2372,"children":2373},{"style":115},[2374],{"type":24,"value":2375},"          aws s3 cp s3://damieng-static/feed.xml s3://damieng-static/feed.xml --no-guess-mime-type --content-type \"application/atom+xml\" --metadata-directive \"REPLACE\"\n",{"type":19,"tag":102,"props":2377,"children":2379},{"class":104,"line":2378},59,[2380],{"type":19,"tag":102,"props":2381,"children":2382},{"style":115},[2383],{"type":24,"value":2384},"          aws s3 cp s3://damieng-static/css/ s3://damieng-static/css/ --metadata-directive \"REPLACE\" --recursive\n",{"type":19,"tag":102,"props":2386,"children":2388},{"class":104,"line":2387},60,[2389],{"type":19,"tag":102,"props":2390,"children":2391},{"style":115},[2392],{"type":24,"value":2393},"          aws s3 cp s3://damieng-static/js/ s3://damieng-static/js/ --metadata-directive \"REPLACE\" --recursive\n",{"type":19,"tag":102,"props":2395,"children":2397},{"class":104,"line":2396},61,[2398],{"type":19,"tag":102,"props":2399,"children":2400},{"emptyLinePlaceholder":1582},[2401],{"type":24,"value":1585},{"type":19,"tag":102,"props":2403,"children":2405},{"class":104,"line":2404},62,[2406,2410,2414,2418],{"type":19,"tag":102,"props":2407,"children":2408},{"style":188},[2409],{"type":24,"value":191},{"type":19,"tag":102,"props":2411,"children":2412},{"style":126},[2413],{"type":24,"value":1722},{"type":19,"tag":102,"props":2415,"children":2416},{"style":132},[2417],{"type":24,"value":135},{"type":19,"tag":102,"props":2419,"children":2420},{"style":115},[2421],{"type":24,"value":1247},{"type":19,"tag":102,"props":2423,"children":2425},{"class":104,"line":2424},63,[2426,2430,2434],{"type":19,"tag":102,"props":2427,"children":2428},{"style":126},[2429],{"type":24,"value":1966},{"type":19,"tag":102,"props":2431,"children":2432},{"style":132},[2433],{"type":24,"value":135},{"type":19,"tag":102,"props":2435,"children":2436},{"style":115},[2437],{"type":24,"value":2438},"  aws s3api put-object --bucket damieng-static --key \"damieng\" --website-redirect-location \"https://damieng.com/feed.xml\"\n",{"type":19,"tag":102,"props":2440,"children":2442},{"class":104,"line":2441},64,[2443],{"type":19,"tag":102,"props":2444,"children":2445},{"emptyLinePlaceholder":1582},[2446],{"type":24,"value":1585},{"type":19,"tag":102,"props":2448,"children":2450},{"class":104,"line":2449},65,[2451,2455,2459,2463],{"type":19,"tag":102,"props":2452,"children":2453},{"style":188},[2454],{"type":24,"value":191},{"type":19,"tag":102,"props":2456,"children":2457},{"style":126},[2458],{"type":24,"value":1722},{"type":19,"tag":102,"props":2460,"children":2461},{"style":132},[2462],{"type":24,"value":135},{"type":19,"tag":102,"props":2464,"children":2465},{"style":115},[2466],{"type":24,"value":2467}," Latest Envy Code R redirects\n",{"type":19,"tag":102,"props":2469,"children":2471},{"class":104,"line":2470},66,[2472,2476,2480],{"type":19,"tag":102,"props":2473,"children":2474},{"style":126},[2475],{"type":24,"value":1966},{"type":19,"tag":102,"props":2477,"children":2478},{"style":132},[2479],{"type":24,"value":135},{"type":19,"tag":102,"props":2481,"children":2482},{"style":1921},[2483],{"type":24,"value":2484},"  |\n",{"type":19,"tag":102,"props":2486,"children":2488},{"class":104,"line":2487},67,[2489],{"type":19,"tag":102,"props":2490,"children":2491},{"style":115},[2492],{"type":24,"value":2493},"          aws s3api put-object --bucket damieng-static --key \"fonts/envy-code-r\" --website-redirect-location \"https://damieng.com/blog/2008/envy-code-r-preview-7-coding-font-released\"\n",{"type":19,"tag":102,"props":2495,"children":2497},{"class":104,"line":2496},68,[2498],{"type":19,"tag":102,"props":2499,"children":2500},{"style":115},[2501],{"type":24,"value":2502},"          aws s3api put-object --bucket damieng-static --key \"downloads/latest/EnvyCodeR\" --website-redirect-location \"https://dl.damieng.com/fonts/original/EnvyCodeR-PR7.zip\"\n",{"type":19,"tag":102,"props":2504,"children":2506},{"class":104,"line":2505},69,[2507],{"type":19,"tag":102,"props":2508,"children":2509},{"emptyLinePlaceholder":1582},[2510],{"type":24,"value":1585},{"type":19,"tag":102,"props":2512,"children":2514},{"class":104,"line":2513},70,[2515,2519,2523,2527],{"type":19,"tag":102,"props":2516,"children":2517},{"style":188},[2518],{"type":24,"value":191},{"type":19,"tag":102,"props":2520,"children":2521},{"style":126},[2522],{"type":24,"value":1722},{"type":19,"tag":102,"props":2524,"children":2525},{"style":132},[2526],{"type":24,"value":135},{"type":19,"tag":102,"props":2528,"children":2529},{"style":115},[2530],{"type":24,"value":2531}," Set caching for images at 30 days\n",{"type":19,"tag":102,"props":2533,"children":2535},{"class":104,"line":2534},71,[2536,2540,2544],{"type":19,"tag":102,"props":2537,"children":2538},{"style":126},[2539],{"type":24,"value":1966},{"type":19,"tag":102,"props":2541,"children":2542},{"style":132},[2543],{"type":24,"value":135},{"type":19,"tag":102,"props":2545,"children":2546},{"style":115},[2547],{"type":24,"value":2548},"  aws s3 cp s3://damieng-static/ s3://damieng-static/ --exclude \"*\" --include \"*.svg\" --include \"*.ico\" --include \"*.jpg\" --include \"*.png\" --include \"*.webp\" --include \"*.gif\" --recursive --metadata-directive REPLACE --expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public\n",{"type":19,"tag":102,"props":2550,"children":2552},{"class":104,"line":2551},72,[2553],{"type":19,"tag":102,"props":2554,"children":2555},{"emptyLinePlaceholder":1582},[2556],{"type":24,"value":1585},{"type":19,"tag":102,"props":2558,"children":2560},{"class":104,"line":2559},73,[2561,2565,2569,2573],{"type":19,"tag":102,"props":2562,"children":2563},{"style":188},[2564],{"type":24,"value":191},{"type":19,"tag":102,"props":2566,"children":2567},{"style":126},[2568],{"type":24,"value":1722},{"type":19,"tag":102,"props":2570,"children":2571},{"style":132},[2572],{"type":24,"value":135},{"type":19,"tag":102,"props":2574,"children":2575},{"style":115},[2576],{"type":24,"value":2577}," Set caching for CSS and JS at 1 hour\n",{"type":19,"tag":102,"props":2579,"children":2581},{"class":104,"line":2580},74,[2582,2586,2590],{"type":19,"tag":102,"props":2583,"children":2584},{"style":126},[2585],{"type":24,"value":1966},{"type":19,"tag":102,"props":2587,"children":2588},{"style":132},[2589],{"type":24,"value":135},{"type":19,"tag":102,"props":2591,"children":2592},{"style":115},[2593],{"type":24,"value":2594},"  aws s3 cp s3://damieng-static/ s3://damieng-static/ --exclude \"*\" --include \"*.css\" --include \"*.js\" --recursive --metadata-directive REPLACE --expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=3600,public\n",{"type":19,"tag":102,"props":2596,"children":2598},{"class":104,"line":2597},75,[2599,2603,2607],{"type":19,"tag":102,"props":2600,"children":2601},{"style":109},[2602],{"type":24,"value":112},{"type":19,"tag":102,"props":2604,"children":2605},{"style":115},[2606],{"type":24,"value":835},{"type":19,"tag":102,"props":2608,"children":2609},{"style":109},[2610],{"type":24,"value":840},{"type":19,"tag":20,"props":2612,"children":2613},{},[2614],{"type":24,"value":2615},"I also took the opportunity to fix a long-running issue in that my S3 objects would lose my manually-applied cache settings (and new posts and files would not have any).",{"type":19,"tag":70,"props":2617,"children":2619},{"id":2618},"gotchas",[2620],{"type":24,"value":2621},"Gotchas",{"type":19,"tag":20,"props":2623,"children":2624},{},[2625],{"type":24,"value":2626},"There were only a couple of bumps in the road once I decided on a straight-port rather than trying to leverage higher-level existing actions:",{"type":19,"tag":1490,"props":2628,"children":2629},{},[2630,2643],{"type":19,"tag":1494,"props":2631,"children":2632},{},[2633,2635,2641],{"type":24,"value":2634},"The secrets configured in the repo settings were not automatically exposed to the commands running in the action. Instead, you have to expose them using the ",{"type":19,"tag":82,"props":2636,"children":2638},{"className":2637},[],[2639],{"type":24,"value":2640},"${{ secrets.KEY_NAME }}",{"type":24,"value":2642}," syntax.",{"type":19,"tag":1494,"props":2644,"children":2645},{},[2646,2648,2654,2656,2662],{"type":24,"value":2647},"I was using ",{"type":19,"tag":82,"props":2649,"children":2651},{"className":2650},[],[2652],{"type":24,"value":2653},"rename",{"type":24,"value":2655}," instead of ",{"type":19,"tag":82,"props":2657,"children":2659},{"className":2658},[],[2660],{"type":24,"value":2661},"mv",{"type":24,"value":2663},". I don't recall why. Perhaps it was my Windows-ness creeping in. Rename has been dropped in newer distros.",{"type":19,"tag":70,"props":2665,"children":2667},{"id":2666},"summary",[2668],{"type":24,"value":2669},"Summary",{"type":19,"tag":20,"props":2671,"children":2672},{},[2673],{"type":24,"value":2674},"The syntax is surprisingly similar with build-times about the same as CircleCI. It's just nice to have it in one place. Time to port some other repos over!",{"type":19,"tag":20,"props":2676,"children":2677},{},[2678],{"type":19,"tag":2679,"props":2680,"children":2681},"em",{},[2682],{"type":24,"value":2683},"[)amien",{"type":19,"tag":2685,"props":2686,"children":2687},"style",{},[2688],{"type":24,"value":2689},"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);}",{"title":96,"searchDepth":144,"depth":144,"links":2691},[2692,2696],{"id":55,"depth":144,"text":58,"children":2693},[2694,2695],{"id":72,"depth":158,"text":75},{"id":843,"depth":158,"text":846},{"id":1475,"depth":144,"text":1478,"children":2697},[2698,2699],{"id":2618,"depth":158,"text":2621},{"id":2666,"depth":158,"text":2669},"markdown","content:blog:2020:from-circleci-to-github-actions.md","content","blog/2020/from-circleci-to-github-actions.md","blog/2020/from-circleci-to-github-actions","md","/blog/2020/from-circleci-to-github-actions/",1276,0,[2710,2714,2718],{"title":2711,"date":2712,"url":2713},"HTML5 Video Cheatsheet: Optimizing videos for the web","2025-12-05T00:00:00Z","/blog/2025/html5-video-cheatsheet/",{"title":2715,"date":2716,"url":2717},"Transactions in the MongoDB EF Core Provider","2025-10-25","/blog/2025/mongodb-explicit-transactions/",{"title":2719,"date":2720,"url":2721},"Queryable Encryption with the MongoDB EF Core Provider","2025-09-22","/blog/2025/mongodb-queryable-encryption/",[],1779224641939]