1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[671],{355:function(e,n,a){(window.__NEXT_P=window.__NEXT_P||[]).push(["/articles/scheduled-github-actions-sync-repo",function(){return a(5087)}])},5087:function(e,n,a){"use strict";a.r(n),a.d(n,{default:function(){return o},meta:function(){return c}});var s=a(5893),t=a(1151),r=a(312);let c={author:"ractoon",date:"2022-10-16",title:"Using Scheduled GitHub Actions to Sync Repos",tags:["GitHub"],description:"An experiment using a scheduled GitHub action to sync from a separate repository."},l=e=>(0,s.jsx)(r.B,{meta:c,...e});function i(e){let n={a:"a",code:"code",p:"p",pre:"pre",span:"span",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"GitHub actions are a powerful tool used for CI/CD and other development workflows. But did you know you can also run scheduled actions, similar to a cron job?"}),"\n",(0,s.jsxs)(n.p,{children:["As a proof-of-concept I was curious if it would be possible to automatically keep one of my repositories in sync with another repo. For this experiment I had a branch that added a Docker configuration to ",(0,s.jsx)(n.a,{href:"https://github.com/laravel/laravel",children:"Laravel"})," projects at ",(0,s.jsx)(n.a,{href:"https://github.com/ractoon/laravel-docker",children:"ractoon/laravel-docker"}),". As Laravel released updates this branch would be missing the latest changes."]}),"\n",(0,s.jsxs)(n.p,{children:["The workflow below is located at ",(0,s.jsx)(n.code,{children:".github/workflows/laravel-sync.yml"})," in the ",(0,s.jsx)(n.code,{children:"ractoon/laravel-docker"})," repo:"]}),"\n",(0,s.jsx)(n.pre,{className:"language-yaml",children:(0,s.jsxs)(n.code,{className:"language-yaml",children:[(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Laravel Sync\n\n",(0,s.jsx)(n.span,{className:"token key atrule",children:"on"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"schedule"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"cron"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ",(0,s.jsx)(n.span,{className:"token string",children:'"17 * * * *"'}),"\n\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"workflow_dispatch"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n\n",(0,s.jsx)(n.span,{className:"token key atrule",children:"jobs"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"sync"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"runs-on"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ubuntu",(0,s.jsx)(n.span,{className:"token punctuation",children:"-"}),"latest\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"steps"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Checkout\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"uses"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," actions/checkout@v2\n\n ",(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Set Env\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"run"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"|"}),(0,s.jsx)(n.span,{className:"token scalar string",children:"\n echo \"current_version=$(curl -Ls https://api.github.com/repos/ractoon/laravel-docker/tags | jq -r '.[0].name')\" >> $GITHUB_ENV\n echo \"laravel_version=$(curl -Ls https://api.github.com/repos/laravel/laravel/tags | jq -r '.[0].name')\" >> $GITHUB_ENV"}),"\n ",(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Sync Latest Laravel\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"run"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"|"}),(0,s.jsx)(n.span,{className:"token scalar string",children:'\n echo "Checking Laravel repo..."\n if [[ "${{ env.current_version }}" != "${{ env.laravel_version }}" ]]; then\n curl -Ls https://api.github.com/repos/laravel/laravel/tarball -o ${{ runner.temp }}/laravel.tar\n echo "Extracting and updating repo files..."\n find . -maxdepth 1 ! -name .git ! -name .github ! -name .gitignore ! -name laravel.tar ! -name "docker" ! -name "cmd" ! -name "docker-compose.yml" ! -name . -exec rm -r {} \\; && tar xzf ${{ runner.temp }}/laravel.tar --strip-components 1 --exclude=\'README.md\' -C . && sed -i -e \'s/^DB_HOST.*$/D
1B_HOST=mysql/g\' ".env.example" && sed -i -e \'s/^REDIS_HOST.*$/REDIS_HOST=redis/g\' ".env.example"\n if git show-ref --tags "${{ env.laravel_version }}" --quiet; then\n echo "Tag ${{ env.laravel_version }} exists."\n else\n echo "Updating files to ${{ env.laravel_version }}"\n git config user.name github-actions\n git config user.email [email protected]\n git add .\n if [[ `git status --porcelain` ]]; then\n echo "Committing changes..."\n git commit -m "Auto-update Laravel ${{ env.laravel_version }}"\n git tag ${{ env.laravel_version }}\n git push --atomic origin master ${{ env.laravel_version }}\n else\n echo "No changes to commit."\n fi\n fi\n else\n echo "Up to date."\n fi'}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Breaking this down here's what's going on."}),"\n",(0,s.jsx)(n.pre,{className:"language-yaml",children:(0,s.jsxs)(n.code,{className:"language-yaml",children:[(0,s.jsx)(n.span,{className:"token key atrule",children:"on"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"schedule"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"}),"\n ",(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"cron"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ",(0,s.jsx)(n.span,{className:"token string",children:'"17 * * * *"'}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Schedule this action to run at 17 minutes past the hour, every hour."}),"\n",(0,s.jsx)(n.pre,{className:"language-yaml",children:(0,s.jsxs)(n.code,{className:"language-yaml",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Checkout\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"uses"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," actions/checkout@v2\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Use the checkout action to grab the required repos."}),"\n",(0,s.jsx)(n.pre,{className:"language-yaml",children:(0,s.jsxs)(n.code,{className:"language-yaml",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Set Env\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"run"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"|"}),(0,s.jsx)(n.span,{className:"token scalar string",children:"\n echo \"current_version=$(curl -Ls https://api.github.com/repos/ractoon/laravel-docker/tags | jq -r '.[0].name')\" >> $GITHUB_ENV\n echo \"laravel_version=$(curl -Ls https://api.github.com/repos/laravel/laravel/tags | jq -r '.[0].name')\" >> $GITHUB_ENV"}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Set a couple environment variables for my repos current tagged version, and the current tagged version from the Laravel repo."}),"\n",(0,s.jsx)(n.pre,{className:"language-yaml",children:(0,s.jsxs)(n.code,{className:"language-yaml",children:[(0,s.jsx)(n.span,{className:"token punctuation",children:"-"})," ",(0,s.jsx)(n.span,{className:"token key atrule",children:"name"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," Sync Latest Laravel\n ",(0,s.jsx)(n.span,{className:"token key atrule",children:"run"}),(0,s.jsx)(n.span,{className:"token punctuation",children:":"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"|"}),(0,s.jsx)(n.span,{className:"token scalar string",children:'\n echo "Checking Laravel repo..."\n if [[ "${{ env.current_version }}" != "${{ env.laravel_version }}" ]]; then\n ...\n else\n echo "Up to date."\n fi'}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Check if the latest Laravel version is different from my repo. If it's the same we're up to date. If not we need to do some additional work."}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token function",children:"curl"})," -Ls https://api.github.com/repos/laravel/laravel/tarball -o ",(0,s.jsx)(n.span,{className:"token variable",children:"${{ runner.temp }"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"}"}),"/laravel.tar\n",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"echo"})," ",(0,s.jsx)(n.span,{className:"token string",children:'"Extracting and updating repo files..."'}),"\n",(0,s.jsx)(n.span,{className:"token function",children:"find"})," ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"."})," -maxdepth ",(0,s.jsx)(n.span,{className:"token number",children:"1"})," ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name .git ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name .github ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name .gitignore ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name laravel.tar ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name ",(0,s.jsx)(n.span,{className:"token string",children:'"docker"'})," ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name ",(0,s.jsx)(n.span,{className:"token string",children:'"cmd"'})," ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name ",(0,s.jsx)(n.span,{className:"token string",children:'"docker-compose.yml"'})," ",(0,s.jsx)(n.span,{className:"token operator",children:"!"})," -name ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"."})," -exec ",(0,s.jsx)(n.span,{className:"token function",children:"rm"})," -r ",(0,s.jsx)(n.span,{className:"token punctuation",children:"{"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"}"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"\\"}),(0,s.jsx)(n.span,{className:"token punctuation",children:";"})," ",(0,s.jsx)(n.span,{className:"token operator",children:"&&"})," ",(0,s.jsx)(n.span,{className:"token function",children:"tar"})," xzf ",(0,s.jsx)(n.span,{className:"token variable",children:"${{ runner.temp }"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"}"}),"/laravel.tar --strip-components ",(0,s.jsx)(n.span,{className:"token number",children:"1"})," --exclude",(0,s.jsx)(n.span,{className:"token operator",children:"="}),(0,s.jsx)(n.span,{className:"token string",children:"'README.md'"})," -C ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"."})," ",(0,s.jsx)(n.span,{className:"token operator",children:"&&"})," ",(0,s.jsx)(n.span,{className:"token function",children:"sed"})," -i -e ",(0,s.jsx)(n.span,{className:"token string",children:"'s/^DB_HOST.*$/D
1B_HOST=mysql/g'"})," ",(0,s.jsx)(n.span,{className:"token string",children:'".env.example"'})," ",(0,s.jsx)(n.span,{className:"token operator",children:"&&"})," ",(0,s.jsx)(n.span,{className:"token function",children:"sed"})," -i -e ",(0,s.jsx)(n.span,{className:"token string",children:"'s/^REDIS_HOST.*$/REDIS_HOST=redis/g'"})," ",(0,s.jsx)(n.span,{className:"token string",children:'".env.example"'}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"First we need to download the Laravel repo files and extract them. Then perform some cleanup on the files retrieved so we can preserve our changes, including adding Docker and some configuration."}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token keyword",children:"if"})," ",(0,s.jsx)(n.span,{className:"token function",children:"git"})," show-ref --tags ",(0,s.jsxs)(n.span,{className:"token string",children:['"',(0,s.jsx)(n.span,{className:"token variable",children:"${{ env.laravel_version }"}),'}"']})," --quiet",(0,s.jsx)(n.span,{className:"token punctuation",children:";"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"then"}),"\n ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"echo"})," ",(0,s.jsxs)(n.span,{className:"token string",children:['"Tag ',(0,s.jsx)(n.span,{className:"token variable",children:"${{ env.laravel_version }"}),'} exists."']}),"\n",(0,s.jsx)(n.span,{className:"token keyword",children:"else"}),"\n ",(0,s.jsx)(n.span,{className:"token punctuation",children:".."}),".\n",(0,s.jsx)(n.span,{className:"token keyword",children:"fi"}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"If this repo already has a tagged release matching that of the latest Larvel version, then don't do anything. Otherwise we need to update the files."}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token builtin class-name",children:"echo"})," ",(0,s.jsxs)(n.span,{className:"token string",children:['"Updating files to ',(0,s.jsx)(n.span,{className:"token variable",children:"${{ env.laravel_version }"}),'}"']}),"\n",(0,s.jsx)(n.span,{className:"token function",children:"git"})," config user.name github-actions\n",(0,s.jsx)(n.span,{className:"token function",children:"git"})," config user.email [email protected]\n",(0,s.jsx)(n.span,{className:"token function",children:"git"})," ",(0,s.jsx)(n.span,{className:"token function",children:"add"})," ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"."}),"\n"]})}),"\n",(0,s.jsx)(n.p,{children:"Set the git configuration and add changes to be committed."}),"\n",(0,s.jsx)(n.pre,{className:"language-bash",children:(0,s.jsxs)(n.code,{className:"language-bash",children:[(0,s.jsx)(n.span,{className:"token keyword",children:"if"})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"["}),(0,s.jsx)(n.span,{className:"token punctuation",children:"["})," ",(0,s.jsxs)(n.span,{className:"token variable",children:[(0,s.jsx)(n.span,{className:"token variable",children:"`"}),(0,s.jsx)(n.span,{className:"token function",children:"git"})," status --porcelain",(0,s.jsx)(n.span,{className:"token variable",children:"`"})]})," ",(0,s.jsx)(n.span,{className:"token punctuation",children:"]"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"]"}),(0,s.jsx)(n.span,{className:"token punctuation",children:";"})," ",(0,s.jsx)(n.span,{className:"token keyword",children:"then"}),"\n ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"echo"})," ",(0,s.jsx)(n.span,{className:"token string",children:'"Committing changes..."'}),"\n ",(0,s.jsx)(n.span,{className:"token function",children:"git"})," commit -m ",(0,s.jsxs)(n.span,{className:"token string",children:['"Auto-update Laravel ',(0,s.jsx)(n.span,{className:"token variable",children:"${{ env.laravel_version }"}),'}"']}),"\n ",(0,s.jsx)(n.span,{className:"token function",children:"git"})," tag ",(0,s.jsx)(n.span,{className:"token variable",children:"${{ env.laravel_version }"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"}"}),"\n ",(0,s.jsx)(n.span,{className:"token function",children:"git"})," push --atomic origin master ",(0,s.jsx)(n.span,{className:"token variable",children:"${{ env.laravel_version }"}),(0,s.jsx)(n.span,{className:"token punctuation",children:"}"}),"\n",(0,s.jsx)(n.span,{className:"token keyword",children:"else"}),"\n ",(0,s.jsx)(n.span,{className:"token builtin class-name",children:"echo"})," ",(0,s.jsx)(n.span,{className:"token string",children:'"No changes to commit."'}),"\n",(0,s.jsx)(n.span,{className:"token keyword",children:"fi"}),"\n"]})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"--porcelain"})," flag here makes the output easier to parse in scripts, which makes it easier to use in the boolean condition here. If there are changes to commit then they are committed here with a message saying which version of Laravel the updates belong to. A tag is added to the repo for the current Laravel version to keep things matched up. The
1n changes are pushed to the repo."]})]})}function o(e={}){return(0,s.jsx)(l,{...e,children:(0,s.jsx)(i,{...e})})}},312:function(e,n,a){"use strict";a.d(n,{B:function(){return x}});var s=a(5893),t=a(9008),r=a.n(t),c=a(1664),l=a.n(c),i=a(1163),o=a(3223),d=a(6434),h=a(512);function u({children:e,className:n}){return(0,s.jsx)("div",{className:(0,h.Z)(n,"prose dark:prose-invert"),children:e})}var m=a(7330);function p(e){return(0,s.jsx)("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",...e,children:(0,s.jsx)("path",{d:"M7.25 11.25 3.75 8m0 0 3.5-3.25M3.75 8h8.5",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({children:e,meta:n,isRssFeed:a=!1,previousPathname:t}){if(a)return e;let c=(0,i.useRouter)();return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(r(),{children:[(0,s.jsx)("title",{children:`${n.title} | ractoon`}),(0,s.jsx)("meta",{name:"description",content:n.description})]}),(0,s.jsx)(o.W,{className:"mt-16 lg:mt-32",children:(0,s.jsx)("div",{className:"xl:relative",children:(0,s.jsxs)("div",{className:"mx-auto max-w-2xl",children:[t&&(0,s.jsx)("button",{type:"button",onClick:()=>c.back(),"aria-label":"Go back to articles",className:"group mb-8 flex h-10 w-10 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 transition dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0 dark:ring-white/10 dark:hover:border-zinc-700 dark:hover:ring-white/20 lg:absolute lg:-left-5 lg:mb-0 lg:-mt-2 xl:-top-1.5 xl:left-0 xl:mt-0",children:(0,s.jsx)(p,{className:"h-4 w-4 stroke-zinc-500 transition group-hover:stroke-zinc-700 dark:stroke-zinc-500 dark:group-hover:stroke-zinc-400"})}),(0,s.jsxs)("article",{children:[(0,s.jsxs)("header",{className:"flex flex-col",children:[(0,s.jsx)("h1",{className:"bg-gradient-to-br from-ractoon-blue-light to-ractoon-blue-dark text-transparent bg-clip-text mt-6 text-4xl font-bold tracking-tight sm:leading-[4rem] sm:text-5xl",children:n.title}),(0,s.jsxs)("time",{dateTime:n.date,className:"order-first flex items-center text-base text-zinc-400 dark:text-zinc-500",children:[(0,s.jsx)("span",{className:"h-4 w-0.5 rounded-full bg-zinc-200 dark:bg-zinc-500"}),(0,s.jsx)("span",{className:"ml-3",children:(0,m.p)(n.date)})]})]}),(0,s.jsx)(u,{className:"mt-8",children:e})]}),(0,s.jsx)("aside",{children:(0,s.jsx)(d.m,{className:"mt-24"})}),(0,s.jsx)("footer",{children:(0,s.jsx)(u,{children:(0,s.jsxs)("p",{className:"text-center",children:["Questions or comments? Hit me up on Twitter ",(0,s.jsx)(l(),{href:"https://twitter.com/ractoon",target:"_blank",children:"@ractoon"})]})})})]})})})]})}},5534:function(e,n,a){"use strict";a.d(n,{z:function(){return i}});var s=a(5893),t=a(1664),r=a.n(t),c=a(512);let l={primary:"bg-zinc-600 font-semibold text-zinc-100 hover:bg-zinc-700 active:bg-zinc-800 active:text-zinc-100/70 dark:bg-zinc-700 dark:hover:bg-zinc-600 dark:active:bg-zinc-700 dark:active:text-zinc-100/70",secondary:"bg-zinc-50 font-medium text-zinc-900 hover:bg-zinc-100 active:bg-zinc-100 active:text-zinc-900/60 dark:bg-zinc-800/50 dark:text-zinc-300 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 dark:active:bg-zinc-800/50 dark:active:text-zinc-50/70",brand:"border border-ractoon-blue-dark/50 font-semibold text-ractoon-blue-dark dark:text-ractoon-blue hover:border-ractoon-blue hover:text-ractoon-blue active:border-ractoon-blue/60 dark:border-ractoon-blue/50 dark:hover:border-ractoon-blue-light dark:hover:text-ractoon-blue-light dark:active:border-ractoon-blue-light/70"};function i({variant:e="primary",className:n,href:a,...t}){return n=(0,c.Z)("inline-flex items-center gap-2 justify-center rounded-md py-2 px-3 text-sm outline-offset-2 transition active:transition-none",l[e],n),a?(0,s.jsx)(r(),{href:a,className:n,...t}):(0,s.jsx)("button",{className:n,...t})}},6434:function(e,n,a){"use strict";a.d(n,{m:function(){return l}});var s=a(5893),t=a(512),r=a(5534);function c(e){return(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:"1.5",stroke:"currentColor",...e,children:(0,s.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75",className:"fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500"})})}function l({className:e}){return e=(0,t.Z)("bg-white/90 backdrop-blur-sm rounded-2xl border border-zinc-100 p-6 dark:bg-zinc-900/90 dark:border-zinc-700/40",e),(0,s.jsxs)("form",{action:"https://app.convertkit.com/forms/3928602/subscriptions",method:"post",target:"_blank",className:e,children:[(0,s.jsxs)("h2",{className:"flex text-sm font-semibold text-zinc-900 dark:text-zinc-100",children:[(0,s.jsx)(c,{className:"h-6 w-6 flex-none"}),(0,s.jsx)("span",{className:"ml-2",children:"Stay up to date"})]}),(0,s.jsx)("p",{className:"mt-2 text-sm text-zinc-600 dark:text-zinc-400",children:"Get notified when I publish something new, and unsubscribe at any time."}),(0,s.jsxs)("div",{className:"mt-6 flex",children:[(0,s.jsx)("input",{type:"email",placeholder:"Email address","aria-label":"Email address",name:"email_address",required:!0,className:"min-w-0 flex-auto appearance-none rounded-md border border-zinc-900/10 bg-white px-3 py-[calc(theme(sp
1acing.2)-1px)] shadow-md shadow-zinc-800/5 placeholder:text-zinc-400 focus:border-ractoon-blue focus:outline-none focus:ring-4 focus:ring-ractoon-blue/10 dark:border-zinc-700 dark:bg-zinc-700/[0.15] dark:text-zinc-200 dark:placeholder:text-zinc-500 dark:focus:border-ractoon-blue-light dark:focus:ring-ractoon-blue-light/10 sm:text-sm"}),(0,s.jsx)(r.z,{type:"submit",className:"ml-4 flex-none",children:"Join"})]})]})}},7330:function(e,n,a){"use strict";function s(e){return new Date(`${e}T00:00:00Z`).toLocaleDateString("en-US",{day:"numeric",month:"long",year:"numeric",timeZone:"UTC"})}a.d(n,{p:function(){return s}})},9008:function(e,n,a){e.exports=a(7828)},1151:function(e,n,a){"use strict";a.d(n,{a:function(){return r}});var s=a(7294);let t=s.createContext({});function r(e){let n=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}}},function(e){e.O(0,[888,774,179],function(){return e(e.s=355)}),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.