DEV Community: TED Vortex (Teodor Eugen Duțulescu) The latest articles on DEV Community by TED Vortex (Teodor Eugen Duțulescu) (@0vortex). https://dev.to/0vortex https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F169707%2Fb6ca4efe-c3a1-4227-8444-97b26bf62220.jpeg DEV Community: TED Vortex (Teodor Eugen Duțulescu) https://dev.to/0vortex en Deploy a GitHub Application to Cloudflare Workers TED Vortex (Teodor Eugen Duțulescu) Tue, 22 Feb 2022 23:56:47 +0000 https://dev.to/opensauced/deploy-a-github-application-to-cloudflare-workers-2gpm https://dev.to/opensauced/deploy-a-github-application-to-cloudflare-workers-2gpm <h2> Introduction </h2> <blockquote> <p>"why, why, WHY?"</p> </blockquote> <p>After seeing <a href="proxy.php?url=https://dev.to/bdougieyo">@bdougieyo</a> build a <a href="proxy.php?url=https://bdougie.github.io/sls-probot-guide/" rel="noopener noreferrer">ProBot</a> app and <a href="proxy.php?url=https://dev.to/blackgirlbytes">@blackgirlbytes</a> fresh take on <a href="proxy.php?url=https://dev.to/github/deploying-my-probot-app-to-a-serverless-lambda-352h">deploying ProBot to AWS Lambda</a>, I figured I would spice things up a bit by researching the most cost-effective solution to run a serverless GitHub application.</p> <p>Before I go on, you might be thinking things like:</p> <ul> <li>only care about money?!</li> <li>AWS Lambda is dirt cheap!</li> <li>it's all a configuration war you cannot win!</li> </ul> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jsmgbn96w3dyk2r2e9f.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jsmgbn96w3dyk2r2e9f.png" alt="there is no serverless"></a> </p> <p>Thinking about these hypothetical objections, my inner dialogue goes on:<br> Me: "Hold up, whaaaat?!"<br> Other me: "Yes it's <a href="proxy.php?url=https://workers.cloudflare.com" rel="noopener noreferrer">CloudFlare Workers</a>!"</p> <p><a href="proxy.php?url=https://i.giphy.com/media/21I1WOUDnct4EmSNa6/giphy.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://i.giphy.com/media/21I1WOUDnct4EmSNa6/giphy.gif" alt="man trying to do math in in his head"></a></p> <p>The simple explanation is that I'm proposing use of the Service Worker API. Cloudflare offers a flat, free, 100k requests a day if you <a href="proxy.php?url=https://developers.cloudflare.com/workers/platform/limits#worker-limits" rel="noopener noreferrer">can keep it cutting edge</a>, has local development and testing options with <a href="proxy.php?url=https://miniflare.dev" rel="noopener noreferrer">miniflare</a> and a <a href="proxy.php?url=https://www.cloudflare.com/en-gb/products/workers-kv/" rel="noopener noreferrer">key/value (KV) store</a>.</p> <p>If you still have your doubts, it might be because you know that the build system would be using Webpack 4 out of the box. However, this means it can do Rollup, and so it can do Vite. Yes, <a href="proxy.php?url=https://dev.to/mtfoley">@mtfoley</a>, this is preparing to be another <a href="proxy.php?url=https://dev.to/mtfoley/series/16147">converting to Vite series</a>!</p> <p>We'll be applying our solution to <a href="proxy.php?url=https://github.com/open-sauced/catsup-app" rel="noopener noreferrer">catsup-app</a> GitHub application being developed in the Open Sauced org. For each repo that has the application installed, our Discord will be updated when an issue has the <code>good first issue</code> label applied.</p> <h2> Technical part </h2> <blockquote> <p>"how to how-to X!"</p> </blockquote> <h3> Requirements </h3> <p>This is going to hurt:</p> <ul> <li>make the existing Probot code compatible</li> <li>writing less-than-browser-compatible code</li> <li>&lt;10 ms CPU execution time due to the workers' limits</li> <li>automated releases over an open-source repository </li> <li>secure deployments</li> </ul> <h3> Code </h3> <p>Assuming <a href="proxy.php?url=https://github.com/open-sauced/catsup-app/pull/2" rel="noopener noreferrer">the workers PR</a> will eventually be production ready, the code should be visible over at:</p> <div class="ltag-github-readme-tag"> <div class="readme-overview"> <h2> <img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"> <a href="proxy.php?url=https://github.com/open-sauced" rel="noopener noreferrer"> open-sauced </a> / <a href="proxy.php?url=https://github.com/open-sauced/catsup" rel="noopener noreferrer"> catsup </a> </h2> <h3> This app will index your pr and issue data. </h3> </div> <div class="ltag-github-body"> <div id="readme" class="md"> <div> <br> <a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/29efb82f11676acbc4e738ed600193015006d530da033e9814ae8ca30f5d5c4b/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67"><img alt="Open Sauced" src="proxy.php?url=https://camo.githubusercontent.com/29efb82f11676acbc4e738ed600193015006d530da033e9814ae8ca30f5d5c4b/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67" width="300px"></a> <div class="markdown-heading"> <h1 class="heading-element">🍕 Open Sauced Catsup App 🍕</h1> </div> <strong>The path to your next Open Source contribution</strong> </div> <br> <p> <a href="proxy.php?url=https://github.com/open-sauced/catsup-app/actions/workflows/release.yml" rel="noopener noreferrer"> <img src="proxy.php?url=https://github.com/open-sauced/catsup-app/actions/workflows/release.yml/badge.svg" alt="Release"> </a> <a href="proxy.php?url=https://github.com/open-sauced/catsup-app/actions/workflows/compliance.yml" rel="noopener noreferrer"> <img src="proxy.php?url=https://github.com/open-sauced/catsup-app/actions/workflows/compliance.yml/badge.svg" alt="Compliance"> </a> <a href="proxy.php?url=https://github.com/open-sauced/catsup-app/actions/workflows/codeql-analysis.yml" rel="noopener noreferrer"> <img src="proxy.php?url=https://github.com/open-sauced/catsup-app/actions/workflows/codeql-analysis.yml/badge.svg" alt="CodeQL"> </a> <a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/1278395f3b4a896c6b3560ac4339169ea3b90dbcb460350c7cc793c8224141d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6f70656e2d7361756365642f6361747375702d617070"><img src="proxy.php?url=https://camo.githubusercontent.com/1278395f3b4a896c6b3560ac4339169ea3b90dbcb460350c7cc793c8224141d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6f70656e2d7361756365642f6361747375702d617070" alt="GitHub code size in bytes"></a> <a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/d3d0720d5fa43a5363e9691cd2543292452b0ca40d38fd0a5d5987d616faab90/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f6f70656e2d7361756365642f6361747375702d617070"><img src="proxy.php?url=https://camo.githubusercontent.com/d3d0720d5fa43a5363e9691cd2543292452b0ca40d38fd0a5d5987d616faab90/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f6f70656e2d7361756365642f6361747375702d617070" alt="GitHub commit activity"></a> <a href="proxy.php?url=https://github.com/open-sauced/catsup-app/issues" rel="noopener noreferrer"> <img src="proxy.php?url=https://camo.githubusercontent.com/37703dfd4ff833daf9b48ca2321ff5a6d8d8b7edaa397e1e005feed79adbba14/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6f70656e2d7361756365642f6361747375702d617070" alt="GitHub issues"> </a> <a href="proxy.php?url=https://github.com/open-sauced/catsup-app/releases" rel="noopener noreferrer"> <img src="proxy.php?url=https://camo.githubusercontent.com/fa09323ceed6da6de1ef4d5474c136c2a71b2de712a398157b9d45ee61d83b18/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6f70656e2d7361756365642f6361747375702d6170702e7376673f7374796c653d666c6174" alt="GitHub Release"> </a> <a href="proxy.php?url=https://discord.gg/U2peSNf23P" rel="nofollow noopener noreferrer"> <img src="proxy.php?url=https://camo.githubusercontent.com/24a002130335cc39964e02cd93940c9788cc7d15961e1e16861538999a2ac30a/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3731343639383536313038313730343532392e7376673f6c6162656c3d266c6f676f3d646973636f7264266c6f676f436f6c6f723d66666666666626636f6c6f723d373338394438266c6162656c436f6c6f723d364137454332" alt="Discord"> </a> <a href="proxy.php?url=https://twitter.com/saucedopen" rel="nofollow noopener noreferrer"> <img src="proxy.php?url=https://camo.githubusercontent.com/728007b849c6305395eef098fb46120997d65a0f99edb176cbacdd52218e8e96/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f7361756365646f70656e3f6c6162656c3d466f6c6c6f77267374796c653d736f6369616c" alt="Twitter"> </a> </p> <div class="markdown-heading"> <h2 class="heading-element">📖 Prerequisites</h2> </div> <p>In order to run the project locally we need <code>node&gt;=16</code> and <code>npm&gt;=8</code> installed on our development machines.</p> <div class="markdown-heading"> <h2 class="heading-element">🖥️ Local development</h2> </div> <p>To run the GitHub App code against a test repository, add <code>TEST_REPOSITORY</code> to your local <code>.env</code> file.</p> <p>To start the server locally at port <code>8888</code>:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"> <pre>npm start</pre> </div> <div class="markdown-heading"> <h2 class="heading-element">📦 Deploy to production</h2> </div> <div class="markdown-heading"> <h3 class="heading-element">Netlify account</h3> </div> <p>Install the Netlify GitHub app in the repository and configure the environment variables listed in <a href="proxy.php?url=https://github.com/open-sauced/catsup.env.example" rel="noopener noreferrer">.env.example</a>.</p> <div class="markdown-heading"> <h3 class="heading-element">GitHub App</h3> </div> <p><a href="proxy.php?url=https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app" rel="noopener noreferrer">Register a new GitHub application</a> with the permissions <code>issues:write</code> and <code>metadata:read</code>. Set the webhook URL to <code>&lt;your netlify domain&gt;/api/github/webhooks</code>.</p> <p>Once registered, you will be able to obtain all the <code>GITHUB_APP_*</code> credentials from the app settings.</p> <p>It is advised you generate the <code>WEBHOOK_SECRET</code> using the following command:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"> <pre><span class="pl-c"><span class="pl-c">#</span> random key strokes can work too if you don't have ruby(??)</span> ruby</pre>… </div> </div> </div> <div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/open-sauced/catsup" rel="noopener noreferrer">View on GitHub</a></div> </div> <p>In order for the project to be shipped as a service function, the node environment can not be used in any of the production code. Reviewing Probot source, one might see a dead end in that it uses <a href="proxy.php?url=https://github.com/probot/probot/blob/5d232e2d86c72cff541d193a877a4ccf90cea6d7/src/bin/probot.ts#L5" rel="noopener noreferrer"><code>require("dotenv").config()</code></a>. However, its underlying framework, <a href="proxy.php?url=https://github.com/octokit/octokit.js" rel="noopener noreferrer">OctoKit</a> does not come with any opinionated code in this regard.</p> <p>Simply expanding the script into the Probot equivalent while dodging the node imports was very easy and has been done before. Being able to see existing working code made the process a lot more enjoyable:</p> <div class="ltag-github-readme-tag"> <div class="readme-overview"> <h2> <img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"> <a href="proxy.php?url=https://github.com/gr2m" rel="noopener noreferrer"> gr2m </a> / <a href="proxy.php?url=https://github.com/gr2m/cloudflare-worker-github-app-example" rel="noopener noreferrer"> cloudflare-worker-github-app-example </a> </h2> <h3> A Cloudflare Worker + GitHub App Example </h3> </div> <div class="ltag-github-body"> <div id="readme" class="md"> <div class="markdown-heading"> <h1 class="heading-element">cloudflare-worker-github-app-example</h1> </div> <blockquote> <p>A Cloudflare Worker + GitHub App Example</p> </blockquote> <p>The <a href="proxy.php?url=https://github.com/gr2m/cloudflare-worker-github-app-exampleworker.js" rel="noopener noreferrer">worker.js</a> file is a <a href="proxy.php?url=https://workers.cloudflare.com/" rel="nofollow noopener noreferrer">Cloudflare Worker</a> which is continuously deployed using GitHub Actions (see <a href="proxy.php?url=https://github.com/gr2m/cloudflare-worker-github-app-example.github/workflows/deploy.yml" rel="noopener noreferrer">.github/workflows/deploy.yml</a>).</p> <p>The worker does 2 things</p> <ol> <li> <code>GET</code> requests: respond with an HTML website with links and a live counter of installations.</li> <li> <code>POST</code> requests: handle webhook request from GitHub</li> </ol> <p>⚠️ The requests from GitHub are currently not verified using the signature, because <a href="proxy.php?url=https://github.com/octokit/webhooks.js/blob/0e03e470034ac769a28ed37acb524b94e304bf96/src/sign/index.ts#L1" rel="noopener noreferrer">the code is currently using Node's crypto package</a>. This will be resolved once I create a universal webhook verification package, similar to <a href="proxy.php?url=https://github.com/gr2m/universal-github-app-jwt/#readme" rel="noopener noreferrer"><code>universal-github-app-jwt</code></a>. For the time being, you could define a secret path that that webhook requests by GitHub are sent to, in order to prevent anyone who knows your workers URL from sending fake webhook requests. See <a href="proxy.php?url=https://github.com/gr2m/cloudflare-worker-github-app-example/issues/1" rel="noopener noreferrer">#1</a></p> <p><a rel="noopener noreferrer" href="proxy.php?url=https://github.com/gr2m/cloudflare-worker-github-app-exampleassets/hello-there-cloudflare-worker.gif"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgr2m%2Fcloudflare-worker-github-app-exampleassets%2Fhello-there-cloudflare-worker.gif" alt="screen recording of GitHub app creating a comment on a new GitHub issue"></a></p> <div class="markdown-heading"> <h2 class="heading-element">Step-by-step instructions to create your own</h2> </div> <p>Note that you require access to the new GitHub Actions for the automated deployment to work.</p> <ol> <li> <p>Fork this…</p> </li> </ol> </div> </div> <div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/gr2m/cloudflare-worker-github-app-example" rel="noopener noreferrer">View on GitHub</a></div> </div> <p>Using the same <a href="proxy.php?url=https://github.com/probot/smee-client" rel="noopener noreferrer">probot/smee-client</a> shipped by Probot we divert the webhook URL to one on localhost for the development application, and for the production application we will enter a custom route.</p> <p>While it might look like an anti-pattern, setting up a private local-only application in the workers configuration file is perfectly safe and meant as the most basic way to ensure all environment variables are encrypted for the production environment. In fact, a helpful property of workers lies in the fact that we are unable to deploy the app if the requisite environment variables don't exist, and the only way to add them is by encrypting them as secrets.</p> <p>The above secrets definition pattern requires that we set up the GitHub application and Discord hooks before trying to deploy the service worker, as it would otherwise fail with unencrypted or loose values.</p> <h3> Setting up the service worker </h3> <h4> 1. Cloudflare worker </h4> <p>Set up a cloudflare account and enable workers, change <code>account_id</code> in <a href="proxy.php?url=//./wrangler.toml">wrangler.toml</a> to your account id. </p> <p>Go to your workers dashboard and create a new worker, select any template, adjust <code>name</code> in <a href="proxy.php?url=//./wrangler.toml">wrangler.toml</a> if the existing one is taken.</p> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpliws7ldyalrlksvciq1.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpliws7ldyalrlksvciq1.png" alt="Cloudflare Workers create new service"></a> </p> <p>Write the "Routes" URL provided by the worker down somewhere for the next parts. It will serve as webhook return URL.</p> <h4> 2. GitHub application </h4> <p>Create a new GitHub application with scopes <code>issues:write</code> and <code>metadata:read</code> while also enabling tracking events.</p> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv04p6rck6ohth9pychua.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv04p6rck6ohth9pychua.png" alt="GitHub App enable issues"></a></p> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cmlqlhaa5e3rjrt6phs.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cmlqlhaa5e3rjrt6phs.png" alt="GitHub App enable tracking issues"></a></p> <p>Upon creation you should have plain-text values for <code>APP_ID</code>, <code>CLIENT_ID</code>. </p> <p>Click the "Generate a new client secret" button and copy the resulting value of <code>CLIENT_SECRET</code>.</p> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcekr31x4yho1bpchtkz4.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcekr31x4yho1bpchtkz4.png" alt="GitHub App webhook secret"></a> </p> <p>In the webhook return URL copy the value of your worker route as described in the last step of the Cloudflare setup. </p> <p>If you have Ruby installed, it is advised you generate the <code>WEBHOOK_SECRET</code> using the following command:</p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> <span class="c"># random key strokes can work too if you don't have ruby</span> ruby <span class="nt">-rsecurerandom</span> <span class="nt">-e</span> <span class="s1">'puts SecureRandom.hex(20)'</span> </code></pre> </div> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78jfthj3qjy1dup0z8fu.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78jfthj3qjy1dup0z8fu.png" alt="GitHub App webhook URL"></a> </p> <p>Now, go to the very bottom and click "Generate a new private key" and open a terminal in the location of the downloaded file. </p> <p>Rename this file to <code>private-key.pem</code> for the next command to work: </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> openssl pkcs8 <span class="nt">-topk8</span> <span class="nt">-inform</span> PEM <span class="nt">-outform</span> PEM <span class="nt">-nocrypt</span> <span class="nt">-in</span> private-key.pem <span class="nt">-out</span> private-key-pkcs8.key </code></pre> </div> <p>Copy the contents of <code>private-key-pkcs8.key</code> to <code>APP_PK</code>.</p> <h4> 3. Discord webhook </h4> <p>Go to your server of choice, click "Settings" and then "Integrations", create a new webhook and copy the URL and paste that value into <code>DISCORD_URL</code>. </p> <p>Now you are good to use the wrangler release workflows and deploy to production!</p> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fep9rmmro4av4eqxq7kgf.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fep9rmmro4av4eqxq7kgf.png" alt="Discord webhook creation"></a> </p> <h4> 4. Environment variables </h4> <p>Select the "Settings" tab on your newly created worker and click "Variables", add the following variables with the values described in the previous steps:</p> <ul> <li> <code>APP_ID</code> </li> <li> <code>APP_PK</code> </li> <li> <code>DISCORD_URL</code> </li> <li> <code>CLIENT_ID</code> </li> <li> <code>CLIENT_SECRET</code> </li> <li> <code>WEBHOOK_SECRET</code> </li> </ul> <p>Encrypt all of them and deployment will start working both locally and in the CI workflows!</p> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxz6ah7nx7dtz0vu7xi1.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxz6ah7nx7dtz0vu7xi1.png" alt="Cloudflare Workers encrypt variables"></a> </p> <h3> Deployment </h3> <p>The PR code, as well as the maintainers, are not yet sure of the best way to approach deployment to multiple environments. There is a minor concern for the CI action leaking the target URL which would give the possibility of service disruption. Making the deployment target fully private, i.e. deploying from <code>wrangler</code> locally, would make the discovery process partially visible to us in application installations and limit outbound attack vectors considerably. Sitting behind 2 of the biggest global CDNs would also help a lot!</p> <h4> Local publish </h4> <p>Login to cloudflare with your account credentials, letting the browser open an OAuth dialog with: </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> npm run wrangler <span class="nt">--</span> login </code></pre> </div> <p>Now you can test all the variables are correct by publishing from the terminal: </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> <span class="c"># npm run wrangler -- publish </span> npm run publish </code></pre> </div> <p>Open up a production real time log using: </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> <p>npm run wrangler <span class="nt">--</span> <span class="nb">tail</span></p> </code></pre> </div> <h4> <br> <br> <br> GitHub actions<br> </h4> <p>Create a new GitHub actions secret named <code>CF_API_TOKEN</code>, get its value from Cloudflare's <a href="proxy.php?url=https://dash.cloudflare.com/profile/api-tokens" rel="noopener noreferrer">create a new token</a> using the "Edit Cloudflare Workers" template. </p> <p>Push new code to the server, after a release the new code should be sent to the server and instantly propagate.</p> <h2> Conclusion </h2> <blockquote> <p>"easy, what next?!"</p> </blockquote> <p>Some things come to mind as potential improvements:</p> <ul> <li>switching the build system to vite</li> <li>implement testing and coverage commands</li> <li>move secrets to KV namespaces for easier environment deployments</li> <li>dockerize repository</li> </ul> node github devops serverless Automatically update git major tags on GitHub marketplace release TED Vortex (Teodor Eugen Duțulescu) Tue, 07 Dec 2021 08:08:46 +0000 https://dev.to/opensauced/automatically-update-git-major-tags-on-github-marketplace-release-1mgk https://dev.to/opensauced/automatically-update-git-major-tags-on-github-marketplace-release-1mgk <h3> Motivation </h3> <p>Having previously dockerized our semantic release configuration in <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config">@open-sauced/semantic-release-conventional-config</a>, a manual step was needed to publish the action in the GitHub marketplace.</p> <p>This meant that forcing a major tag update with <a href="proxy.php?url=https://github.com/semantic-release/exec">@semantic-release/exec</a> as part of the release process was possible, but would result in the major tag (for example v3) linking to a valid repository commit SHA that is not actually released in the marketplace.</p> <p>Sensibly solving these issues required:</p> <ul> <li>keeping the semantic release configuration intact</li> <li>testing the action container in another repository</li> <li>having a maintainer manually edit and save the release </li> <li>letting the <code>marketplace.yml</code> workflow update major tags in the curated release context</li> </ul> <p>It may sound tedious but in practice, all a maintainer has to do to update the marketplace tags is edit a published release and press the save button. That's exactly 2 clicks from the repository front page and the simplest way to have <a href="proxy.php?url=https://en.wikipedia.org/wiki/Acceptance_testing">acceptance testing</a>.</p> <h3> My Workflow </h3> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Action</span><span class="nv"> </span><span class="s">major</span><span class="nv"> </span><span class="s">version</span><span class="nv"> </span><span class="s">tag"</span> <span class="na">on</span><span class="pi">:</span> <span class="na">release</span><span class="pi">:</span> <span class="na">types</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">published</span> <span class="pi">-</span> <span class="s">edited</span> <span class="na">jobs</span><span class="pi">:</span> <span class="na">latest</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Update action tags</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">ref</span><span class="pi">:</span> <span class="s">${{ github.ref }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">publish</span><span class="nv"> </span><span class="s">action"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">Actions-R-Us/actions-tagger@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">publish_latest_tag</span><span class="pi">:</span> <span class="no">false</span> <span class="na">prefer_branch_releases</span><span class="pi">:</span> <span class="no">false</span> </code></pre> </div> <p>The full workflow is available here: <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/blob/main/.github/workflows/marketplace.yml">.github/workflows/marketplace.yml</a></p> <h3> Submission Category: Maintainer Must-Haves </h3> <h3> Yaml File or Link to Code </h3> <p>Live repository using this workflow:<br> </p> <div class="ltag-github-readme-tag"> <div class="readme-overview"> <h2> <img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"> <a href="proxy.php?url=https://github.com/open-sauced"> open-sauced </a> / <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config"> semantic-release-conventional-config </a> </h2> <h3> semantic-release shareable config to publish to npm and/or ghcr </h3> </div> <div class="ltag-github-body"> <div id="readme" class="md"> <p><em>This project has been archived in favor of <a href="proxy.php?url=https://github.com/open-sauced/release">open-sauced/release</a></em></p> <div> <a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/a04f53b57fbf8d1500e38822ae5a35084088bedbbfa70f7e96a7fd6e9d27d0aa/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67"><img alt="Open Sauced" src="proxy.php?url=https://camo.githubusercontent.com/a04f53b57fbf8d1500e38822ae5a35084088bedbbfa70f7e96a7fd6e9d27d0aa/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67" width="300px"></a> <h1> @open-sauced/semantic-release-conventional-config</h1> <blockquote> <p><a href="proxy.php?url=https://github.com/semantic-release/semantic-release"><strong>semantic-release</strong></a> shareable config to publish to <code>npm</code> and/or <code>ghcr</code>.</p> </blockquote> <blockquote> <p>now available as a <a href="proxy.php?url=https://github.com/marketplace/actions/open-sauced-semantic-release-conventional-config">GitHub Marketplace action</a></p> </blockquote> <p><a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/pulse"><img src="proxy.php?url=https://camo.githubusercontent.com/6cdb31096e6a3d0090609a5fe967b63c8f565530f7408d6b6a5d8960c35b26b8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f6f70656e2d7361756365642f73656d616e7469632d72656c656173652d636f6e76656e74696f6e616c2d636f6e6669673f7374796c653d666c6174" alt="Commits"></a> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/issues"><img src="proxy.php?url=https://camo.githubusercontent.com/fdf12a0d1304d579e770283938e1780c8bc86c2c378d2321078d7805776cea54/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6f70656e2d7361756365642f73656d616e7469632d72656c656173652d636f6e76656e74696f6e616c2d636f6e6669672e7376673f7374796c653d666c6174" alt="Issues"></a> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/releases"><img src="proxy.php?url=https://camo.githubusercontent.com/244cc726216c4c489d6ac5cf189959dda4cf0b8ebf5fca5968968b55bcd13533/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6f70656e2d7361756365642f73656d616e7469632d72656c656173652d636f6e76656e74696f6e616c2d636f6e6669672e7376673f7374796c653d666c6174" alt="Releases"></a> <a href="proxy.php?url=https://discord.gg/U2peSNf23P" rel="nofollow"><img src="proxy.php?url=https://camo.githubusercontent.com/eaef2d80ac219bcc45df03f3eb580f62f61cd81a1fd80665b256014573f7aaa0/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3731343639383536313038313730343532392e7376673f6c6162656c3d266c6f676f3d646973636f7264266c6f676f436f6c6f723d66666666666626636f6c6f723d373338394438266c6162656c436f6c6f723d364137454332" alt="Discord"></a> <a href="proxy.php?url=https://twitter.com/saucedopen" rel="nofollow"><img src="proxy.php?url=https://camo.githubusercontent.com/944ad9b38e1d49d04da75b41310bd052eda0c73635c5a52484375152c8c8bc43/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f7361756365646f70656e3f6c6162656c3d466f6c6c6f77267374796c653d736f6369616c" alt="Twitter"></a></p> </div> <h2> 📦 Plugins</h2> <p>This shareable configuration use the following plugins:</p> <ul> <li><a href="proxy.php?url=https://github.com/semantic-release/commit-analyzer"><code>@semantic-release/commit-analyzer</code></a></li> <li><a href="proxy.php?url=https://github.com/semantic-release/release-notes-generator"><code>@semantic-release/release-notes-generator</code></a></li> <li><a href="proxy.php?url=https://github.com/semantic-release/changelog"><code>@semantic-release/changelog</code></a></li> <li><a href="proxy.php?url=https://github.com/conventional-changelog/conventional-changelog"><code>conventional-changelog-conventionalcommits</code></a></li> <li><a href="proxy.php?url=https://github.com/semantic-release/npm"><code>@semantic-release/npm</code></a></li> <li><a href="proxy.php?url=https://github.com/google/semantic-release-replace-plugin"><code>@google/semantic-release-replace-plugin</code></a></li> <li><a href="proxy.php?url=https://github.com/cbhq/semantic-release-license"><code>semantic-release-license</code></a></li> <li><a href="proxy.php?url=https://github.com/semantic-release/git"><code>@semantic-release/git</code></a></li> <li><a href="proxy.php?url=https://github.com/semantic-release/github"><code>@semantic-release/github</code></a></li> <li><a href="proxy.php?url=https://github.com/eclass/semantic-release-docker"><code>@eclass/semantic-release-docker</code></a></li> <li><a href="proxy.php?url=https://github.com/semantic-release/exec"><code>@semantic-release/exec</code></a></li> <li><a href="proxy.php?url=https://github.com/sindresorhus/execa"><code>execa</code></a></li> <li><a href="proxy.php?url=https://github.com/npm/npmlog"><code>npmlog</code></a></li> </ul> <h2> 🖥️ Requirements</h2> <p>Most important limitations are:</p> <ul> <li> <code>GITHUB_TOKEN</code> for everything</li> <li> <code>NPM_TOKEN</code> for public <code>npm</code> library</li> <li> <code>docker</code> containers need to be built beforehand</li> </ul> <p>You can skip here if you are using elevated <a href="proxy.php?url=https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token">Private Access Token</a>, however we don't recommend going down that path.</p> <p>No force push or admin cherries branch protections for the following branches:</p> <ul> <li> <code>main</code> - required</li> <li> <code>next</code> - optional, next channel</li> <li> <code>next-major</code> - optional, next major</li> <li> <code>alpha</code> - optional, pre-release branch</li> <li> <code>beta</code> - optional, pre-release branch</li> <li> <code>vX[.X.X]</code> - maintenance releases</li> </ul> <p>If you use more than the main branch, optionally create an environment that is limiting where pushes can come from…</p> </div> </div> <br> <div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config">View on GitHub</a></div> <br> </div> <br> <h3> Additional Resources / Info </h3> <p>Here are all the open source actions we are using to power this release workflow:</p> <ul> <li> <a href="proxy.php?url=https://github.com/Actions-R-Us/actions-tagger">Actions-R-Us/actions-tagger@v2</a> - updates major tag on release</li> </ul> <p>Be sure to include the DEV usernames of your collaborators:<br> </p> <div class="ltag__user ltag__user__id__391207"> <a href="proxy.php?url=/mtfoley" class="ltag__user__link profile-image-link"> <div class="ltag__user__pic"> <img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--6WYweNSs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s----P_WZWH--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/391207/3ea20bd5-0891-4025-bf72-51490099a21b.jpg" alt="mtfoley image"> </div> </a> <div class="ltag__user__content"> <h2> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">Matthew Foley</a>Follow </h2> <div class="ltag__user__summary"> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">I write code for fun, and sometimes for work</a> </div> </div> </div> actionshackathon21 github actions Semantic release to npm and/or ghcr without any tooling TED Vortex (Teodor Eugen Duțulescu) Tue, 07 Dec 2021 08:08:29 +0000 https://dev.to/opensauced/semantic-release-to-npm-andor-ghcr-without-any-tooling-5730 https://dev.to/opensauced/semantic-release-to-npm-andor-ghcr-without-any-tooling-5730 <h3> Motivation </h3> <p>Having our semantic release process available as a scoped package was a useful practice but it became obvious that having it installed in our development dependencies across multiple repositories would pose a challenge for other maintainers while increasing our build times.</p> <p>The only thing that could simplify this process was to have all the release dependencies offloaded to a <a href="proxy.php?url=https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action" rel="noopener noreferrer">Docker container action</a> we could tag major versions and reduce maintenance cost by deploying release configuration improvements without touching workflows.</p> <h3> My Workflow </h3> <p>This action is a thoroughly engineered semantic-release shareable configuration, meant to simplify configuration and workflow environment variables to just <code>GITHUB_TOKEN</code> and, if you are deploying to npmjs, <code>NPM_TOKEN</code>. </p> <p>There are 2 ways of using this action in a workflow:</p> <ol> <li><p>From a docker container without an updated marketplace tag, we use this technique to test if the action is fully working for GitHub marketplace users, before deploying and updating our major action tag. Running it this way the preferred outputs are stored to environment variables.</p></li> <li><p>From the GitHub marketplace, ensuring stability and having workflow step outputs that can be cross-referenced.</p></li> </ol> <p>There are multiple use cases for this action/workflow, we will go through them all in the next sections.</p> <h4> Any kind of npm package </h4> <p>The simplest use case for a typical NPM package, almost zero setup time on GitHub actions and no additional installed tools. Assuming there are no build steps, setting up node/npm is not required.</p> <p>Release to npm from <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/pkgs/container/semantic-release-conventional-config" rel="noopener noreferrer">ghcr container</a>:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Release"</span> <span class="na">on</span><span class="pi">:</span> <span class="na">push</span><span class="pi">:</span> <span class="na">branches</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">main</span> <span class="pi">-</span> <span class="s">alpha</span> <span class="pi">-</span> <span class="s">beta</span> <span class="pi">-</span> <span class="s">next</span> <span class="pi">-</span> <span class="s">next-major</span> <span class="na">jobs</span><span class="pi">:</span> <span class="na">release</span><span class="pi">:</span> <span class="na">environment</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">production</span> <span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/${{ github.repository }}/releases/tag/${{ env.RELEASE_TAG }}</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">0</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">release"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">semantic-release</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker://ghcr.io/open-sauced/semantic-release-conventional-config:3.0.0</span> <span class="na">env</span><span class="pi">:</span> <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span> <span class="na">NPM_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.NPM_TOKEN }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s1">'</span><span class="s">♻️</span><span class="nv"> </span><span class="s">cleanup'</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">echo ${{ env.RELEASE_TAG }}</span> <span class="s">echo ${{ env.RELEASE_VERSION }}</span> </code></pre> </div> <p>Release to npm from <a href="proxy.php?url=https://github.com/marketplace/actions/open-sauced-semantic-release-conventional-config" rel="noopener noreferrer">marketplace action</a>:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Release"</span> <span class="na">on</span><span class="pi">:</span> <span class="na">push</span><span class="pi">:</span> <span class="na">branches</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">main</span> <span class="pi">-</span> <span class="s">alpha</span> <span class="pi">-</span> <span class="s">beta</span> <span class="pi">-</span> <span class="s">next</span> <span class="pi">-</span> <span class="s">next-major</span> <span class="na">jobs</span><span class="pi">:</span> <span class="na">release</span><span class="pi">:</span> <span class="na">environment</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">production</span> <span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/${{ github.repository }}/releases/tag/${{ steps.semantic-release.outputs.release-tag }}</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Semantic release</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">0</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">release"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">semantic-release</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">open-sauced/semantic-release-conventional-config@v3</span> <span class="na">env</span><span class="pi">:</span> <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span> <span class="na">NPM_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.NPM_TOKEN }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s1">'</span><span class="s">♻️</span><span class="nv"> </span><span class="s">cleanup'</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">echo ${{ steps.semantic-release.outputs.release-tag }}</span> <span class="s">echo ${{ steps.semantic-release.outputs.release-version }}</span> </code></pre> </div> <h4> Containerised nodejs application </h4> <p>This is a typical example for NodeJS backend applications or React frontends. Assuming there are no build steps or the package is set as private, setting up node/npm is not required and the docker build job will take care of all the limitations.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Release"</span> <span class="na">on</span><span class="pi">:</span> <span class="na">push</span><span class="pi">:</span> <span class="na">branches</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">main</span> <span class="pi">-</span> <span class="s">alpha</span> <span class="pi">-</span> <span class="s">beta</span> <span class="pi">-</span> <span class="s">next</span> <span class="pi">-</span> <span class="s">next-major</span> <span class="na">jobs</span><span class="pi">:</span> <span class="na">docker</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build container</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">setup</span><span class="nv"> </span><span class="s">buildx"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/setup-buildx-action@v1</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">cache</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">layers"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/.buildx-cache</span> <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-buildx-${{ github.sha }}</span> <span class="na">restore-keys</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">${{ runner.os }}-buildx-</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">meta"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">meta</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/metadata-action@v3</span> <span class="na">with</span><span class="pi">:</span> <span class="na">images</span><span class="pi">:</span> <span class="s">${{ github.repository }}</span> <span class="na">tags</span><span class="pi">:</span> <span class="s">latest</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">build"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/build-push-action@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">context</span><span class="pi">:</span> <span class="s">.</span> <span class="na">tags</span><span class="pi">:</span> <span class="s">${{ steps.meta.outputs.tags }}</span> <span class="na">labels</span><span class="pi">:</span> <span class="s">${{ steps.meta.outputs.labels }}</span> <span class="na">outputs</span><span class="pi">:</span> <span class="s">type=docker,dest=/tmp/docker.tar</span> <span class="na">push</span><span class="pi">:</span> <span class="kc">false</span> <span class="na">cache-from</span><span class="pi">:</span> <span class="s">type=gha, scope=${{ github.workflow }}</span> <span class="na">cache-to</span><span class="pi">:</span> <span class="s">type=gha, scope=${{ github.workflow }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">docker</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/docker.tar</span> <span class="na">release</span><span class="pi">:</span> <span class="na">environment</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">production</span> <span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/${{ github.repository }}/releases/tag/${{ steps.semantic-release.outputs.release-tag }}</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Semantic release</span> <span class="na">needs</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">docker</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">0</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">download</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">docker</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">load</span><span class="nv"> </span><span class="s">tag"</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">docker load --input /tmp/docker.tar</span> <span class="s">docker image ls -a</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">release"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">semantic-release</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">open-sauced/semantic-release-conventional-config@v3</span> <span class="na">env</span><span class="pi">:</span> <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">♻️</span><span class="nv"> </span><span class="s">cleanup"</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">echo ${{ steps.semantic-release.outputs.release-tag }}</span> <span class="s">echo ${{ steps.semantic-release.outputs.release-version }}</span> </code></pre> </div> <h4> Containerised nodejs GitHub action </h4> <p>This is the most niche usage, it requires building and storing the build artifact, releasing the docker container, and then updating the <code>action.yml</code> as part of the release process. This requires manually editing the release to push to the marketplace and updating the major action tag.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Release"</span> <span class="na">on</span><span class="pi">:</span> <span class="na">push</span><span class="pi">:</span> <span class="na">branches</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">main</span> <span class="pi">-</span> <span class="s">alpha</span> <span class="pi">-</span> <span class="s">beta</span> <span class="pi">-</span> <span class="s">next</span> <span class="pi">-</span> <span class="s">next-major</span> <span class="na">jobs</span><span class="pi">:</span> <span class="na">docker</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build container</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">setup</span><span class="nv"> </span><span class="s">buildx"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/setup-buildx-action@v1</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">cache</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">layers"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/.buildx-cache</span> <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-buildx-${{ github.sha }}</span> <span class="na">restore-keys</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">${{ runner.os }}-buildx-</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">meta"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">meta</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/metadata-action@v3</span> <span class="na">with</span><span class="pi">:</span> <span class="na">images</span><span class="pi">:</span> <span class="s">${{ github.repository }}</span> <span class="na">tags</span><span class="pi">:</span> <span class="s">latest</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">build"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/build-push-action@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">context</span><span class="pi">:</span> <span class="s">.</span> <span class="na">tags</span><span class="pi">:</span> <span class="s">${{ steps.meta.outputs.tags }}</span> <span class="na">labels</span><span class="pi">:</span> <span class="s">${{ steps.meta.outputs.labels }}</span> <span class="na">outputs</span><span class="pi">:</span> <span class="s">type=docker,dest=/tmp/docker.tar</span> <span class="na">push</span><span class="pi">:</span> <span class="kc">false</span> <span class="na">cache-from</span><span class="pi">:</span> <span class="s">type=gha, scope=${{ github.workflow }}</span> <span class="na">cache-to</span><span class="pi">:</span> <span class="s">type=gha, scope=${{ github.workflow }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">docker</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/docker.tar</span> <span class="na">release</span><span class="pi">:</span> <span class="na">environment</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">production</span> <span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/${{ github.repository }}/releases/tag/${{ steps.semantic-release.outputs.release-tag }}</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Semantic release</span> <span class="na">needs</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">docker</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">0</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">setup</span><span class="nv"> </span><span class="s">node"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/[email protected]</span> <span class="na">with</span><span class="pi">:</span> <span class="na">node-version</span><span class="pi">:</span> <span class="m">16</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">npm@latest"</span> <span class="na">run</span><span class="pi">:</span> <span class="s">npm i -g npm@latest</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">dependencies"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">bahmutov/npm-install@v1</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">download</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">docker</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">load</span><span class="nv"> </span><span class="s">tag"</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">docker load --input /tmp/docker.tar</span> <span class="s">docker image ls -a</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">release"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">semantic-release</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">open-sauced/[email protected]</span> <span class="na">env</span><span class="pi">:</span> <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span> <span class="na">cleanup</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cleanup actions</span> <span class="na">needs</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">release</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">♻️</span><span class="nv"> </span><span class="s">remove</span><span class="nv"> </span><span class="s">build</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">geekyeggo/delete-artifact@v1</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">docker</span> </code></pre> </div> <p>We thought about enabling some flexibility for users wanting minimal visual changes without them having to fork the repository and release another semantic configuration. </p> <p>It's possible to release the container to another private GitHub repository or the docker registry by manipulating these variables:</p> <ul> <li><code>DOCKER_USERNAME=$GITHUB_REPOSITORY_OWNER</code></li> <li><code>DOCKER_PASSWORD=$GITHUB_TOKEN</code></li> </ul> <p>It's possible to change the release commit name and author by manipulating these variables:</p> <ul> <li><code>GIT_COMMITTER_NAME="open-sauced[bot]"</code></li> <li><code>GIT_COMMITTER_EMAIL="63161813+open-sauced[bot]@users.noreply.github.com"</code></li> <li><code>GIT_AUTHOR_NAME=$GITHUB_SHA.authorName</code></li> <li><code>GIT_AUTHOR_EMAIL=$GITHUB_SHA.authorEmail</code></li> </ul> <p>Here are all the <a href="proxy.php?url=https://github.com/semantic-release/semantic-release" rel="noopener noreferrer">semantic-release</a> plugins and steps explained:</p> <ul> <li> <a href="proxy.php?url=https://github.com/semantic-release/commit-analyzer" rel="noopener noreferrer"><code>@semantic-release/commit-analyzer</code></a> - analyzes conventional commits deciding if they are bumping a patch, minor or major release tag</li> <li> <a href="proxy.php?url=https://github.com/semantic-release/release-notes-generator" rel="noopener noreferrer"><code>@semantic-release/release-notes-generator</code></a> - generates release notes based on the analysed commits </li> <li> <a href="proxy.php?url=https://github.com/semantic-release/changelog" rel="noopener noreferrer"><code>@semantic-release/changelog</code></a> - generates a fancy changelog using the repository name the workflow was run for as a title and cool emojis [example]</li> <li> <a href="proxy.php?url=https://github.com/conventional-changelog/conventional-changelog" rel="noopener noreferrer"><code>conventional-changelog-conventionalcommits</code></a> - the conventional commit specification configuration preset</li> <li><a href="proxy.php?url=https://github.com/semantic-release/npm" rel="noopener noreferrer"><code>@semantic-release/npm</code></a></li> <li> <a href="proxy.php?url=https://github.com/google/semantic-release-replace-plugin" rel="noopener noreferrer"><code>@google/semantic-release-replace-plugin</code></a> - if the repository is deploying a containerised action, this updates <code>action.yml</code> with the recently released version tag</li> <li> <a href="proxy.php?url=https://github.com/cbhq/semantic-release-license" rel="noopener noreferrer"><code>semantic-release-license</code></a> - if the repository has a <code>LICENSE*</code> file, this updates the year</li> <li> <a href="proxy.php?url=https://github.com/semantic-release/git" rel="noopener noreferrer"><code>@semantic-release/git</code></a> - this creates the GitHub release commit [example]</li> <li> <a href="proxy.php?url=https://github.com/semantic-release/github" rel="noopener noreferrer"><code>@semantic-release/github</code></a> - generates GitHub release notes with added release channel links at the bottom [example]</li> <li> <a href="proxy.php?url=https://github.com/eclass/semantic-release-docker" rel="noopener noreferrer"><code>@eclass/semantic-release-docker</code></a> - if the repository has a <code>Dockerfile</code>, this takes care of releasing the container to ghcr.io [example]</li> <li> <a href="proxy.php?url=https://github.com/semantic-release/exec" rel="noopener noreferrer"><code>@semantic-release/exec</code></a> - used to set GitHub action environment variables when run as from docker container and GitHub action outputs when run as a marketplace action</li> <li> <a href="proxy.php?url=https://github.com/sindresorhus/execa" rel="noopener noreferrer"><code>execa</code></a> - used to check the commit author and check for various settings in the repository using this action</li> <li> <a href="proxy.php?url=https://github.com/npm/npmlog" rel="noopener noreferrer"><code>npmlog</code></a> - used to log the setup process</li> </ul> <h3> Submission Category: DIY Deployments </h3> <h3> Yaml File or Link to Code </h3> <p>Live repository using this action in a workflow:</p> <div class="ltag-github-readme-tag"> <div class="readme-overview"> <h2> <img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"> <a href="proxy.php?url=https://github.com/0-vortex" rel="noopener noreferrer"> 0-vortex </a> / <a href="proxy.php?url=https://github.com/0-vortex/semantic-release-docker-test" rel="noopener noreferrer"> semantic-release-docker-test </a> </h2> <h3> Experimenting with dockerized semantic-release configuration repository for opensauced.pizza </h3> </div> <div class="ltag-github-body"> <div id="readme" class="md"> <div> <a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/29efb82f11676acbc4e738ed600193015006d530da033e9814ae8ca30f5d5c4b/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67"><img alt="Open Sauced" src="proxy.php?url=https://camo.githubusercontent.com/29efb82f11676acbc4e738ed600193015006d530da033e9814ae8ca30f5d5c4b/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67" width="300px"></a> <div class="markdown-heading"> <h1 class="heading-element">semantic-release-docker-test</h1> </div> <blockquote> <p>showcasing the usage of @open-sauced/semantic-release-conventional-config</p> </blockquote> <p><a href="proxy.php?url=https://github.com/0-vortex/semantic-release-docker-test/pulse" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/d63faf78433e9a195e95b5e7404ed81fb2b186eb4a527d42ac2cc2f53f3fc116/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f302d766f727465782f73656d616e7469632d72656c656173652d646f636b65722d746573743f7374796c653d666c6174" alt="Commits"></a> <a href="proxy.php?url=https://github.com/0-vortex/semantic-release-docker-test/issues" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/9e30771661468c466b6a0669c9033fae9542a468345c535259d5accb5b95d25e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f302d766f727465782f73656d616e7469632d72656c656173652d646f636b65722d746573742e7376673f7374796c653d666c6174" alt="Issues"></a> <a href="proxy.php?url=https://github.com/0-vortex/semantic-release-docker-test/releases" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/d19b596be98dd58ff2672fc2950dd60af1b55395063e05d68eb7907d2db4bd8f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f302d766f727465782f73656d616e7469632d72656c656173652d646f636b65722d746573742e7376673f7374796c653d666c6174" alt="Releases"></a> <a href="proxy.php?url=https://discord.gg/U2peSNf23P" rel="nofollow noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/24a002130335cc39964e02cd93940c9788cc7d15961e1e16861538999a2ac30a/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3731343639383536313038313730343532392e7376673f6c6162656c3d266c6f676f3d646973636f7264266c6f676f436f6c6f723d66666666666626636f6c6f723d373338394438266c6162656c436f6c6f723d364137454332" alt="Discord"></a> <a href="proxy.php?url=https://twitter.com/saucedopen" rel="nofollow noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/728007b849c6305395eef098fb46120997d65a0f99edb176cbacdd52218e8e96/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f7361756365646f70656e3f6c6162656c3d466f6c6c6f77267374796c653d736f6369616c" alt="Twitter"></a></p> </div> <p><a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/79637b765f961af80fc788229d8d146273a869520eb63080903ad9d4cabaad3b/68747470733a2f2f692e6962622e636f2f434a66573138482f736869702e676966"><img src="proxy.php?url=https://camo.githubusercontent.com/79637b765f961af80fc788229d8d146273a869520eb63080903ad9d4cabaad3b/68747470733a2f2f692e6962622e636f2f434a66573138482f736869702e676966" width="200"></a></p> <div class="markdown-heading"> <h2 class="heading-element">🍕 Community</h2> </div> <p>Got Questions? Join the conversation in our <a href="proxy.php?url=https://discord.gg/U2peSNf23P" rel="nofollow noopener noreferrer">Discord</a>.<br> Find Open Sauced videos and release overviews on our <a href="proxy.php?url=https://www.youtube.com/channel/UCklWxKrTti61ZCROE1e5-MQ" rel="nofollow noopener noreferrer">YouTube Channel</a>.</p> <div class="markdown-heading"> <h2 class="heading-element">⚖️ LICENSE</h2> </div> <p>MIT © <a href="proxy.php?url=https://github.com/0-vortex/semantic-release-docker-testLICENSE" rel="noopener noreferrer">Open Sauced</a></p> </div> </div> <br> <div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/0-vortex/semantic-release-docker-test" rel="noopener noreferrer">View on GitHub</a></div> <br> </div> <br> <p>GitHub action: <br> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/blob/main/action.yml" rel="noopener noreferrer">@open-sauced/semantic-release-conventional-config/action.yml</a></p> <p>GitHub container registry Dockerfile:<br> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/blob/main/Dockerfile" rel="noopener noreferrer">@open-sauced/semantic-release-conventional-config/Dockerfile</a></p> <p>Full semantic release configuration:<br> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config/blob/main/release.config.js" rel="noopener noreferrer">@open-sauced/semantic-release-conventional-config/release.config.js</a></p> <h3> Additional Resources / Info </h3> <p>Here are all the open source actions we are using to power this release workflow in our repositories and examples:</p> <ul> <li> <a href="proxy.php?url=https://github.com/actions/checkout" rel="noopener noreferrer">actions/checkout@v2</a> - most performant git checkout</li> <li> <a href="proxy.php?url=https://github.com/actions/setup-node" rel="noopener noreferrer">actions/[email protected]</a> - we use it to set the <code>node</code> version to 16</li> <li> <a href="proxy.php?url=https://github.com/actions/upload-artifact" rel="noopener noreferrer">actions/upload-artifact@v2</a> - we use it to transport our artifacts in between jobs</li> <li> <a href="proxy.php?url=https://github.com/actions/download-artifact" rel="noopener noreferrer">actions/download-artifact@v2</a> - we use it to download our artifacts in between jobs</li> <li> <a href="proxy.php?url=https://github.com/docker/setup-buildx-action" rel="noopener noreferrer">docker/setup-buildx-action@v1</a> - we use it to setup the docker builder</li> <li> <a href="proxy.php?url=https://github.com/actions/cache" rel="noopener noreferrer">actions/cache@v2</a> - we use it to cache docker layers</li> <li> <a href="proxy.php?url=https://github.com/docker/metadata-action" rel="noopener noreferrer">docker/metadata-action@v3</a> - we use it to normalise most of our docker container values</li> <li> <a href="proxy.php?url=https://github.com/docker/build-push-action" rel="noopener noreferrer">docker/build-push-action@v2</a> - we use this to build the container</li> <li> <a href="proxy.php?url=https://github.com/bahmutov/npm-install" rel="noopener noreferrer">bahmutov/npm-install@v1</a> - lightning fast <code>npm ci</code> with built-in cache</li> <li> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config" rel="noopener noreferrer">open-sauced/semantic-release-conventional-config@v3</a> - semantic-release configuration, docker container and GitHub action</li> <li> <a href="proxy.php?url=https://github.com/GeekyEggo/delete-artifact" rel="noopener noreferrer">geekyeggo/delete-artifact@v1</a> - deletes produced artifacts</li> </ul> <p>Be sure to include the DEV usernames of your collaborators:<br> </p> <div class="ltag__user ltag__user__id__391207"> <a href="proxy.php?url=/mtfoley" class="ltag__user__link profile-image-link"> <div class="ltag__user__pic"> <img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F391207%2F3ea20bd5-0891-4025-bf72-51490099a21b.jpg" alt="mtfoley image"> </div> </a> <div class="ltag__user__content"> <h2> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">Matthew Foley</a>Follow </h2> <div class="ltag__user__summary"> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">I write code for fun, and sometimes for work</a> </div> </div> </div> actionshackathon21 github docker node How to lint PRs and welcome contributors using GitHub Actions TED Vortex (Teodor Eugen Duțulescu) Tue, 07 Dec 2021 08:07:30 +0000 https://dev.to/opensauced/how-to-lint-prs-and-welcome-contributors-using-github-actions-4elo https://dev.to/opensauced/how-to-lint-prs-and-welcome-contributors-using-github-actions-4elo <h3> Motivation </h3> <p>Expanding the <a href="proxy.php?url=https://github.com/open-sauced">@open-sauced ecosystem</a>, it became tedious to apply all the necessary tooling available in <a href="proxy.php?url=https://github.com/open-sauced/open-sauced">open-sauced/open-sauced</a> to newly created repositories and synchronising existing ones with minor updates.</p> <p>Having <a href="proxy.php?url=https://github.blog/2021-11-29-github-actions-reusable-workflows-is-generally-available/">github actions reusable workflows</a>, we figured it would make a lot of sense to centralise our workflows and referencing them in other repositories.</p> <p>The process was very simple and we want to showcase how to apply a similar process for your own organisation.</p> <h3> My Workflow </h3> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Compliance"</span> <span class="na">on</span><span class="pi">:</span> <span class="na">pull_request_target</span><span class="pi">:</span> <span class="na">types</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">opened</span> <span class="pi">-</span> <span class="s">edited</span> <span class="pi">-</span> <span class="s">synchronize</span> <span class="na">permissions</span><span class="pi">:</span> <span class="na">pull-requests</span><span class="pi">:</span> <span class="s">write</span> <span class="na">jobs</span><span class="pi">:</span> <span class="na">compliance</span><span class="pi">:</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">open-sauced/open-sauced/.github/workflows/compliance.yml@main</span> </code></pre> </div> <p>The full workflow is available here: <a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/blob/main/.github/workflows/compliance.yml">.github/workflows/compliance.yml</a></p> <h3> Submission Category: Maintainer Must-Haves </h3> <h3> Yaml File or Link to Code </h3> <p>Live repository using this workflow:</p> <div class="ltag-github-readme-tag"> <div class="readme-overview"> <h2> <img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"> <a href="proxy.php?url=https://github.com/open-sauced"> open-sauced </a> / <a href="proxy.php?url=https://github.com/open-sauced/conventional-commit"> conventional-commit </a> </h2> <h3> commit binary powered by commitizen with conventional commit standard </h3> </div> <div class="ltag-github-body"> <div id="readme" class="md"> <div> <a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/a04f53b57fbf8d1500e38822ae5a35084088bedbbfa70f7e96a7fd6e9d27d0aa/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67"><img alt="Open Sauced" src="proxy.php?url=https://camo.githubusercontent.com/a04f53b57fbf8d1500e38822ae5a35084088bedbbfa70f7e96a7fd6e9d27d0aa/68747470733a2f2f692e6962622e636f2f376a505874305a2f6c6f676f312d39326631613837662e706e67" width="300px"></a> <h1> @open-sauced/conventional-commit</h1> <blockquote> <p>Never miss a conventional commit with <a href="proxy.php?url=https://www.npmjs.com/package/npm-install-checks" rel="nofollow"><strong>commitizen</strong></a> running on <a href="proxy.php?url=https://www.npmjs.com/package/commitizen" rel="nofollow"><strong>npx</strong></a>.</p> </blockquote> <p><a href="proxy.php?url=https://github.com/open-sauced/conventional-commit/pulse"><img src="proxy.php?url=https://camo.githubusercontent.com/3175ded3f2bf049a57d58b5b8cd223f5af3a5354e6bbd8a7d2c50f8c1f68ba69/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f6f70656e2d7361756365642f636f6e76656e74696f6e616c2d636f6d6d69743f7374796c653d666c6174" alt="Commits"></a> <a href="proxy.php?url=https://github.com/open-sauced/conventional-commit/issues"><img src="proxy.php?url=https://camo.githubusercontent.com/fd8e45afe5a7d5d4ab6c4f1838b521f54b551ba3e86e4fda23f901ab7048338c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6f70656e2d7361756365642f636f6e76656e74696f6e616c2d636f6d6d69742e7376673f7374796c653d666c6174" alt="Issues"></a> <a href="proxy.php?url=https://github.com/open-sauced/conventional-commit/releases"><img src="proxy.php?url=https://camo.githubusercontent.com/a38d3323b7521058d602e79a87a45d345709a58da561ce3281f6738ab20daf36/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6f70656e2d7361756365642f636f6e76656e74696f6e616c2d636f6d6d69742e7376673f7374796c653d666c6174" alt="Releases"></a> <a href="proxy.php?url=https://discord.gg/U2peSNf23P" rel="nofollow"><img src="proxy.php?url=https://camo.githubusercontent.com/eaef2d80ac219bcc45df03f3eb580f62f61cd81a1fd80665b256014573f7aaa0/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3731343639383536313038313730343532392e7376673f6c6162656c3d266c6f676f3d646973636f7264266c6f676f436f6c6f723d66666666666626636f6c6f723d373338394438266c6162656c436f6c6f723d364137454332" alt="Discord"></a> <a href="proxy.php?url=https://twitter.com/saucedopen" rel="nofollow"><img src="proxy.php?url=https://camo.githubusercontent.com/944ad9b38e1d49d04da75b41310bd052eda0c73635c5a52484375152c8c8bc43/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f7361756365646f70656e3f6c6162656c3d466f6c6c6f77267374796c653d736f6369616c" alt="Twitter"></a></p> </div> <h2> 📦 Install</h2> <p>This package is binary and doesn't require installation however you can add it to your repository as a <code>devDependency</code>:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"> <pre>npm install --save-dev @open-sauced/conventional-commit</pre> </div> <h2> 🚀 Usage</h2> <p>All you have to do is run the script next to your <code>package.json</code>:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"> <pre>npx @open-sauced/conventional-commit <span class="pl-c"><span class="pl-c">#</span> or</span> npx conventional-commit</pre> </div> <h2> 🔧 Configuration</h2> <p>The most common use case for this package is to run it instead of the <code>git commit</code> command inside your <code>npm</code> scripts:</p> <div class="highlight highlight-source-json notranslate position-relative overflow-auto js-code-highlight"> <pre>{ <span class="pl-ent">"scripts"</span>: { <span class="pl-ent">"push"</span>: <span class="pl-s"><span class="pl-pds">"</span>npx @open-sauced/conventional-commit<span class="pl-pds">"</span></span> } }</pre> </div> <p>or</p> <div class="highlight highlight-source-json notranslate position-relative overflow-auto js-code-highlight"> <pre>{ <span class="pl-ent">"scripts"</span>: { <span class="pl-ent">"push"</span>: <span class="pl-s"><span class="pl-pds">"</span>npx conventional-commit<span class="pl-pds">"</span></span> } }</pre> </div> <p>If you want to ensure local-only usage:</p> <div class="highlight highlight-source-json notranslate position-relative overflow-auto js-code-highlight"> <pre>{ <span class="pl-ent">"scripts"</span>: { <span class="pl-ent">"push"</span>: <span class="pl-s"><span class="pl-pds">"</span>conventional-commit<span class="pl-pds">"</span></span> } }</pre> </div> <h2> 🤝 Contributing</h2> <p>We encourage you to contribute to Open Sauced! Please check out the <a href="proxy.php?url=https://docs.opensauced.pizza/" rel="nofollow">Contributing guide</a> for guidelines about how to proceed.</p> <p>If…</p> </div> </div> <div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/open-sauced/conventional-commit">View on GitHub</a></div> </div> <p>Yaml file link: <br> <a href="proxy.php?url=https://github.com/open-sauced/open-sauced/blob/main/.github/workflows/compliance.yml">@open-sauced/open-sauced/.github/workflows/compliance.yml</a></p> <h3> Additional Resources / Info </h3> <p>Here are all the open source actions we are using to power this compliance workflow:</p> <ul> <li> <a href="proxy.php?url=https://github.com/actions/first-interaction">actions/first-interaction@v1</a> - welcomes first time contributors and invites them to <a href="proxy.php?url=https://discord.gg/U2peSNf23P">@open-sauced discord</a> </li> <li> <a href="proxy.php?url=https://github.com/amannn/action-semantic-pull-request">amannn/[email protected]</a> - ensures pull request title matches <a href="proxy.php?url=https://www.conventionalcommits.org/en/v1.0.0/">conventional commits specification</a> </li> <li> <a href="proxy.php?url=https://github.com/mtfoley/pr-compliance-action">mtfoley/[email protected]</a> - check PR for compliance on title, linked issues, and files changed </li> </ul> <p>Be sure to include the DEV usernames of your collaborators:<br> </p> <div class="ltag__user ltag__user__id__391207"> <a href="proxy.php?url=/mtfoley" class="ltag__user__link profile-image-link"> <div class="ltag__user__pic"> <img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--6WYweNSs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s----P_WZWH--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/391207/3ea20bd5-0891-4025-bf72-51490099a21b.jpg" alt="mtfoley image"> </div> </a> <div class="ltag__user__content"> <h2> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">Matthew Foley</a>Follow </h2> <div class="ltag__user__summary"> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">I write code for fun, and sometimes for work</a> </div> </div> </div> actionshackathon21 github opensource Generate PDF handbook with Docusaurus using GitHub Actions TED Vortex (Teodor Eugen Duțulescu) Tue, 07 Dec 2021 08:04:29 +0000 https://dev.to/opensauced/generate-pdf-handbook-with-docusaurus-using-github-actions-lfb https://dev.to/opensauced/generate-pdf-handbook-with-docusaurus-using-github-actions-lfb <h3> Motivation </h3> <p>Having <a href="proxy.php?url=https://docs.opensauced.pizza" rel="noopener noreferrer">@open-sauced docs</a> built using <a href="proxy.php?url=https://docusaurus.io" rel="noopener noreferrer">Docusaurus</a>, we started exploring the plugin ecosystem and identified various improvements we could apply.</p> <p>One of the community plugins we found during that process was <a href="proxy.php?url=https://github.com/signcl/docusaurus-prince-pdf" rel="noopener noreferrer">signcl/docusaurus-prince-pdf</a>, an npm package leveraging <a href="proxy.php?url=https://github.com/sindresorhus/got" rel="noopener noreferrer">sindresorhus/got</a> to crawl all the documentation and generate a PDF version.</p> <p>Having a portable document generated as a <a href="proxy.php?url=https://docs.opensauced.pizza/open-sauced-docs.pdf" rel="noopener noreferrer">downloadable release asset</a>, we could more easily share the entirety of our docs and have that document available for offline use.</p> <p>We faced the challenge of having to access the upcoming version during the deployment workflow, installing additional binaries, and deploying the generated asset as part of the release.</p> <h3> My Workflow </h3> <p>The full workflow is available here: <a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/blob/main/.github/workflows/release.yml" rel="noopener noreferrer">.github/workflows/release.yml</a></p> <p>In order to generate a handbook out of a <a href="proxy.php?url=https://docusaurus.io" rel="noopener noreferrer">Docusaurus</a> instance we need to build the application in a container before uploading it as a build artifact for later workflow steps.</p> <p>This is all taken care of in the new <code>docker</code> job that was created for the hackaton:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">jobs</span><span class="pi">:</span> <span class="na">docker</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build container</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">setup</span><span class="nv"> </span><span class="s">buildx"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/setup-buildx-action@v1</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">cache</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">layers"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/.buildx-cache</span> <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-buildx-${{ github.sha }}</span> <span class="na">restore-keys</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">${{ runner.os }}-buildx-</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">meta"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">meta</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/metadata-action@v3</span> <span class="na">with</span><span class="pi">:</span> <span class="na">images</span><span class="pi">:</span> <span class="s">${{ github.repository }}</span> <span class="na">tags</span><span class="pi">:</span> <span class="s">latest</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">build"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker/build-push-action@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">context</span><span class="pi">:</span> <span class="s">.</span> <span class="na">tags</span><span class="pi">:</span> <span class="s">${{ steps.meta.outputs.tags }}</span> <span class="na">labels</span><span class="pi">:</span> <span class="s">${{ steps.meta.outputs.labels }}</span> <span class="na">outputs</span><span class="pi">:</span> <span class="s">type=docker,dest=/tmp/docker.tar</span> <span class="na">push</span><span class="pi">:</span> <span class="kc">false</span> <span class="na">cache-from</span><span class="pi">:</span> <span class="s">type=gha, scope=${{ github.workflow }}</span> <span class="na">cache-to</span><span class="pi">:</span> <span class="s">type=gha, scope=${{ github.workflow }}</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">docker</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/docker.tar</span> </code></pre> </div> <p>Concurrently, the <code>build</code> job prepares static <code>npm</code> assets and uploads them as an artifact for a subsequent job:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">jobs</span><span class="pi">:</span> <span class="na">build</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build application</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">setup</span><span class="nv"> </span><span class="s">node"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/[email protected]</span> <span class="na">with</span><span class="pi">:</span> <span class="na">node-version</span><span class="pi">:</span> <span class="m">16</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">npm@latest"</span> <span class="na">run</span><span class="pi">:</span> <span class="s">npm i -g npm@latest</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">dependencies"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">bahmutov/npm-install@v1</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">static</span><span class="nv"> </span><span class="s">app"</span> <span class="na">run</span><span class="pi">:</span> <span class="s">npm run build</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">production</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">build</span> <span class="na">path</span><span class="pi">:</span> <span class="s">build</span> </code></pre> </div> <p>We then move to the <code>release</code> job, downloading all the artifacts and running our custom configuration <a href="proxy.php?url=https://github.com/marketplace/actions/open-sauced-semantic-release-conventional-config" rel="noopener noreferrer">@open-sauced/semantic-release-conventional-config</a> from a <a href="proxy.php?url=https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions" rel="noopener noreferrer">docker socket</a>:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">jobs</span><span class="pi">:</span> <span class="na">release</span><span class="pi">:</span> <span class="na">environment</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">production</span> <span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/${{ github.repository }}/releases/tag/${{ env.RELEASE_TAG }}</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Semantic release</span> <span class="na">needs</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">docker</span> <span class="pi">-</span> <span class="s">build</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">0</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">download</span><span class="nv"> </span><span class="s">docker</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">docker</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">load</span><span class="nv"> </span><span class="s">tag"</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">docker load --input /tmp/docker.tar</span> <span class="s">docker image ls -a</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">download</span><span class="nv"> </span><span class="s">build</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">build</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/tmp/build</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">release"</span> <span class="na">id</span><span class="pi">:</span> <span class="s">semantic-release</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">docker://ghcr.io/open-sauced/semantic-release-conventional-config:3.0.0</span> <span class="na">env</span><span class="pi">:</span> <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span> </code></pre> </div> <p>The next step is a little verbose, in order to crawl our <a href="proxy.php?url=https://docs.opensauced.pizza" rel="noopener noreferrer">docs website</a> we need to:</p> <ul> <li>mount the previously built container on port <code>8080</code> </li> <li>install <a href="proxy.php?url=https://www.princexml.com" rel="noopener noreferrer">Prince 14</a> </li> <li>run <a href="proxy.php?url=https://github.com/signcl/docusaurus-prince-pdf" rel="noopener noreferrer">docusaurus-prince-pdf</a> </li> <li>deploy to static <a href="proxy.php?url=https://pages.github.com" rel="noopener noreferrer">gh-pages</a> </li> </ul> <p>The <code>deploy</code> job is doing all the heavy lifting:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">jobs</span><span class="pi">:</span> <span class="na">deploy</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to static</span> <span class="na">needs</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">build</span> <span class="pi">-</span> <span class="s">release</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">services</span><span class="pi">:</span> <span class="na">docs</span><span class="pi">:</span> <span class="na">image</span><span class="pi">:</span> <span class="s">ghcr.io/${{ github.repository }}:latest</span> <span class="na">ports</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">8080:80</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">☁️</span><span class="nv"> </span><span class="s">checkout</span><span class="nv"> </span><span class="s">repository"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">download</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v2</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">build</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/home/runner/build</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Prince</span> <span class="na">run</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">curl https://www.princexml.com/download/prince-14.2-linux-generic-x86_64.tar.gz -O</span> <span class="s">tar zxf prince-14.2-linux-generic-x86_64.tar.gz</span> <span class="s">cd prince-14.2-linux-generic-x86_64</span> <span class="s">yes "" | sudo ./install.sh</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">setup</span><span class="nv"> </span><span class="s">node"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/[email protected]</span> <span class="na">with</span><span class="pi">:</span> <span class="na">node-version</span><span class="pi">:</span> <span class="m">16</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🔧</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">npm@latest"</span> <span class="na">run</span><span class="pi">:</span> <span class="s">npm i -g npm@latest</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📦</span><span class="nv"> </span><span class="s">install</span><span class="nv"> </span><span class="s">dependencies"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">bahmutov/npm-install@v1</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">📂</span><span class="nv"> </span><span class="s">copy</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">run</span><span class="pi">:</span> <span class="s">cp -R /home/runner/build .</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">generate</span><span class="nv"> </span><span class="s">pdf"</span> <span class="na">run</span><span class="pi">:</span> <span class="s">npm run pdf</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">🚀</span><span class="nv"> </span><span class="s">deploy</span><span class="nv"> </span><span class="s">static"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">peaceiris/actions-gh-pages@v3</span> <span class="na">with</span><span class="pi">:</span> <span class="na">github_token</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span> <span class="na">publish_dir</span><span class="pi">:</span> <span class="s">./build</span> <span class="na">commit_message</span><span class="pi">:</span> <span class="s">${{ github.event.head_commit.message }}</span> <span class="na">enable_jekyll</span><span class="pi">:</span> <span class="kc">false</span> <span class="na">cname</span><span class="pi">:</span> <span class="s">docs.opensauced.pizza</span> </code></pre> </div> <p>As a final step, we need to clean up our <code>build</code> and <code>docker</code> artifacts, a simple but necessary step:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">jobs</span><span class="pi">:</span> <span class="na">cleanup</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cleanup actions</span> <span class="na">needs</span><span class="pi">:</span> <span class="pi">-</span> <span class="s">deploy</span> <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span> <span class="na">steps</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">♻️</span><span class="nv"> </span><span class="s">remove</span><span class="nv"> </span><span class="s">build</span><span class="nv"> </span><span class="s">artifacts"</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">geekyeggo/delete-artifact@v1</span> <span class="na">with</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="pi">|</span> <span class="s">build</span> <span class="s">docker</span> </code></pre> </div> <h3> Submission Category: DIY Deployments </h3> <h3> Yaml File or Link to Code </h3> <p>Live repository using this workflow:</p> <div class="ltag-github-readme-tag"> <div class="readme-overview"> <h2> <img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"> <a href="proxy.php?url=https://github.com/open-sauced" rel="noopener noreferrer"> open-sauced </a> / <a href="proxy.php?url=https://github.com/open-sauced/docs" rel="noopener noreferrer"> docs </a> </h2> <h3> OpenSauced documentation built with docusaurus </h3> </div> <div class="ltag-github-body"> <div id="readme" class="md"> <div> <br> <p><a href="proxy.php?url=https://opensauced.pizza" rel="nofollow noopener noreferrer"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fopen-sauced%2Fassets%2Fraw%2Fmain%2Flogos%2Flogo-on-dark.png" alt="OpenSauced"></a></p> <div class="markdown-heading"> <h1 class="heading-element">🍕 OpenSauced Docs 🍕</h1> </div> <blockquote> <p>The path to your next Open Source contribution</p> </blockquote> <p><a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/pulse" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/860979e488df36c5160e6afd70ec810b753b223dba697629e1df596d90294f6f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6f70656e2d7361756365642f646f63732e6f70656e7361756365642e70697a7a613f7374796c653d666c6174" alt="Code Size"></a> <a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/pulse" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/25ee4fb241a3b5bfea8ee853e3865dae29c1184c7703013d0522af6388a65aaf/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f6f70656e2d7361756365642f646f63732e6f70656e7361756365642e70697a7a613f7374796c653d666c6174" alt="Commits"></a> <a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/issues" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/11998d61954cfdc54088816df193480dabb27098f4a82747bd63b330f0c3bc76/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6f70656e2d7361756365642f646f63732e6f70656e7361756365642e70697a7a612e7376673f7374796c653d666c6174" alt="Issues"></a> <a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/releases" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/42d0044f292635be914607871d09bff7aafe6e6913ed87160fa2ec6edebbcafa/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6f70656e2d7361756365642f646f63732e6f70656e7361756365642e70697a7a612e7376673f7374796c653d666c6174" alt="Releases"></a> <a href="proxy.php?url=https://twitter.com/saucedopen" rel="nofollow noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/728007b849c6305395eef098fb46120997d65a0f99edb176cbacdd52218e8e96/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f7361756365646f70656e3f6c6162656c3d466f6c6c6f77267374796c653d736f6369616c" alt="Twitter"></a></p> </div> <div class="markdown-heading"> <h2 class="heading-element">🤝 Contributing</h2> </div> <p>We encourage you to contribute to OpenSauced! All contributors are required to abide by our <a href="proxy.php?url=https://github.com/open-sauced/.github/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer">Code of Conduct</a>. Please check out the <a href="proxy.php?url=https://opensauced.pizza/docs/contributing/introduction-to-contributing/" rel="nofollow noopener noreferrer">Contributing guide</a> for guidelines about how to proceed with your contribution.</p> <p><a rel="noopener noreferrer nofollow" href="proxy.php?url=https://camo.githubusercontent.com/79637b765f961af80fc788229d8d146273a869520eb63080903ad9d4cabaad3b/68747470733a2f2f692e6962622e636f2f434a66573138482f736869702e676966"><img src="proxy.php?url=https://camo.githubusercontent.com/79637b765f961af80fc788229d8d146273a869520eb63080903ad9d4cabaad3b/68747470733a2f2f692e6962622e636f2f434a66573138482f736869702e676966" width="200"></a></p> <div class="markdown-heading"> <h2 class="heading-element">🖥️ Development</h2> </div> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"> <pre>npm ci npm start</pre> </div> <div class="markdown-heading"> <h2 class="heading-element">🍕 Community</h2> </div> <p>Got Questions? Join the conversation in our <a href="proxy.php?url=https://github.com/orgs/open-sauced/discussions/1" rel="noopener noreferrer">Community</a>.<br> Find OpenSauced videos and release overviews on our <a href="proxy.php?url=https://www.youtube.com/channel/UCklWxKrTti61ZCROE1e5-MQ" rel="nofollow noopener noreferrer">YouTube Channel</a>.</p> <div class="markdown-heading"> <h2 class="heading-element">⚖️ LICENSE</h2> </div> <p>MIT © <a href="proxy.php?url=https://github.com/open-sauced/docsLICENSE" rel="noopener noreferrer">OpenSauced</a></p> </div> </div> <br> <div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/open-sauced/docs" rel="noopener noreferrer">View on GitHub</a></div> <br> </div> <br> <p>Yaml file link: <br> <a href="proxy.php?url=https://github.com/open-sauced/docs.opensauced.pizza/blob/main/.github/workflows/release.yml" rel="noopener noreferrer">@open-sauced/docs.opensauced.pizza/main/.github/workflows/release.yml</a></p> <h3> Additional Resources / Info </h3> <p>Here are all the open source actions we are using to power this release workflow:</p> <ul> <li> <a href="proxy.php?url=https://github.com/actions/checkout" rel="noopener noreferrer">actions/checkout@v2</a> - most performant git checkout</li> <li> <a href="proxy.php?url=https://github.com/actions/setup-node" rel="noopener noreferrer">actions/[email protected]</a> - we use it to set the <code>node</code> version to 16</li> <li> <a href="proxy.php?url=https://github.com/actions/upload-artifact" rel="noopener noreferrer">actions/upload-artifact@v2</a> - we use it to transport our artifacts in between jobs</li> <li> <a href="proxy.php?url=https://github.com/actions/download-artifact" rel="noopener noreferrer">actions/download-artifact@v2</a> - we use it to download our artifacts in between jobs</li> <li> <a href="proxy.php?url=https://github.com/docker/setup-buildx-action" rel="noopener noreferrer">docker/setup-buildx-action@v1</a> - we use it to set up the docker builder</li> <li> <a href="proxy.php?url=https://github.com/actions/cache" rel="noopener noreferrer">actions/cache@v2</a> - we use it to cache docker layers</li> <li> <a href="proxy.php?url=https://github.com/docker/metadata-action" rel="noopener noreferrer">docker/metadata-action@v3</a> - we use it to normalize most of our docker container values</li> <li> <a href="proxy.php?url=https://github.com/docker/build-push-action" rel="noopener noreferrer">docker/build-push-action@v2</a> - we use it to build the container</li> <li> <a href="proxy.php?url=https://github.com/bahmutov/npm-install" rel="noopener noreferrer">bahmutov/npm-install@v1</a> - lightning-fast <code>npm ci</code> with built-in cache</li> <li> <a href="proxy.php?url=https://github.com/open-sauced/semantic-release-conventional-config" rel="noopener noreferrer">open-sauced/semantic-release-conventional-config@v3</a> - semantic-release configuration, docker container and GitHub action</li> <li> <a href="proxy.php?url=https://github.com/peaceiris/actions-gh-pages" rel="noopener noreferrer">peaceiris/actions-gh-pages@v3</a> - deploys any folder(s) to <code>gh-pages</code>, can use it for multiple static endpoints</li> <li> <a href="proxy.php?url=https://github.com/GeekyEggo/delete-artifact" rel="noopener noreferrer">geekyeggo/delete-artifact@v1</a> - deletes produced artifacts</li> </ul> <p>Be sure to include the DEV usernames of your collaborators:<br> </p> <div class="ltag__user ltag__user__id__391207"> <a href="proxy.php?url=/mtfoley" class="ltag__user__link profile-image-link"> <div class="ltag__user__pic"> <img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F391207%2F3ea20bd5-0891-4025-bf72-51490099a21b.jpg" alt="mtfoley image"> </div> </a> <div class="ltag__user__content"> <h2> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">Matthew Foley</a>Follow </h2> <div class="ltag__user__summary"> <a class="ltag__user__link" href="proxy.php?url=/mtfoley">I write code for fun, and sometimes for work</a> </div> </div> </div> actionshackathon21 github node docker