<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nabin Ale</title>
    <description>The latest articles on Forem by Nabin Ale (@nabim777).</description>
    <link>https://forem.com/nabim777</link>
    <image>
      <url>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%2F1173579%2F6477af53-c735-400c-a323-3d219d044035.jpeg</url>
      <title>Forem: Nabin Ale</title>
      <link>https://forem.com/nabim777</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nabim777"/>
    <language>en</language>
    <item>
      <title>Playwright and GitHub Actions - Run tests in CI</title>
      <dc:creator>Nabin Ale</dc:creator>
      <pubDate>Mon, 16 Mar 2026 08:49:26 +0000</pubDate>
      <link>https://forem.com/jankaritech/playwright-and-github-actions-run-tests-in-ci-47d2</link>
      <guid>https://forem.com/jankaritech/playwright-and-github-actions-run-tests-in-ci-47d2</guid>
      <description>&lt;p&gt;This blog post explains how to run Playwright UI tests in CI (Continuous Integration) using GitHub Actions.&lt;br&gt;
Before you start, you need to have a basic knowledge of &lt;strong&gt;GitHub Actions&lt;/strong&gt;, &lt;strong&gt;Playwright&lt;/strong&gt;, and the &lt;strong&gt;Playwright Trace Viewer&lt;/strong&gt; to better understand this blog. If you are not familiar with any of these topics, below are links to our blogs that explain each one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://blog.jankaritech.com/#/blog/Introduction%20to%20GitHub%20Actions%20-%20CI%20%26%20CD" rel="noopener noreferrer"&gt;Introduction to GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jankaritech.com/#/blog/E2E%20Testing%20using%20BDD%20with%20Playwright/Behavior%20Driven%20Development%20(BDD)%20using%20Playwright" rel="noopener noreferrer"&gt;Playwright&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jankaritech.com/#/blog/E2E%20Testing%20using%20BDD%20with%20Playwright/Debugging%20and%20Error%20Tracing%20in%20Playwright" rel="noopener noreferrer"&gt;Debugging and Error Tracing in Playwright&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By the end of this blog, you will be able to set up a CI workflow that automatically runs your Playwright UI tests whenever you push code to your repository. You will also learn how to get Playwright trace reports when tests fail, making it easier to debug and fix errors.&lt;/p&gt;
&lt;h2&gt;
  
  
  🤔 Why run tests on CI?
&lt;/h2&gt;

&lt;p&gt;Tests are run on CI to ensure the code works properly in a clean and isolated environment every time a change is made. Here are some reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Early bug detection:&lt;/strong&gt;&lt;br&gt;
CI runs tests automatically on every push or PR, so you find problems right when they're introduced, not days or weeks later when the context is gone and fixes are harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. No more "Works on my machine":&lt;/strong&gt;&lt;br&gt;
CI runs your tests in a clean environment every time. If tests pass there, it means your code works in a standard setup, not just on your own computer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Protect the main branch:&lt;/strong&gt;&lt;br&gt;
Tests on CI act like a gatekeeper. If something breaks, it doesn't get merged. This keeps the main (or master) branch deployable and stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Confidence to refactor and move fast:&lt;/strong&gt;&lt;br&gt;
When tests run automatically, you can refactor aggressively. If CI is green, you didn't break existing behavior. That confidence significantly speeds things up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Better collaboration:&lt;/strong&gt;&lt;br&gt;
CI gives everyone on the team the same test results. This helps avoid confusion and makes it clear whether the code is working or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Automated process:&lt;/strong&gt;&lt;br&gt;
CI systems enable developers to save time and effort on testing.&lt;/p&gt;
&lt;h2&gt;
  
  
  📘 About the Project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftujtq9gy8hjxwoj8qfng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftujtq9gy8hjxwoj8qfng.png" alt="Login page of the Project" width="754" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog, I have taken a simple application with a frontend built using Vue.js and a backend built using &lt;a href="https://www.npmjs.com/package/json-server" rel="noopener noreferrer"&gt;json-server&lt;/a&gt;(a fake REST API). The GitHub repository is available at: &lt;a href="https://github.com/nabim777/momo-restro-list.git" rel="noopener noreferrer"&gt;https://github.com/nabim777/momo-restro-list.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a basic application that includes login and logout functionality. E2E tests are written using Playwright to verify the login feature. You can find the test scenarios &lt;a href="https://github.com/nabim777/momo-restro-list/blob/master/tests/acceptance/features/login.feature" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ Running App Locally
&lt;/h2&gt;

&lt;p&gt;Before setting up CI, let's run the application and tests locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install dependencies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Start the frontend and backend servers&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run serve              &lt;span class="c"&gt;# Start frontend&lt;/span&gt;
npm run backend            &lt;span class="c"&gt;# Start backend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Running UI Tests Locally
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;/strong&gt; Make sure both the frontend and backend are running before running the tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To run the UI tests locally, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx playwright &lt;span class="nb"&gt;install &lt;/span&gt;chromium
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:e2e tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚙️ Setting Up CI in GitHub Actions
&lt;/h2&gt;

&lt;p&gt;After verifying the app locally, the next step is to set up CI using GitHub Actions. First, create a file named &lt;code&gt;ci.yml&lt;/code&gt; in your project using the following folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦momo-restro-list
┗ 📂.github
┃ ┣ 📂workflows
┃ ┃ ┗ 📜ci.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, add the following code to the &lt;code&gt;ci.yml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;e2e-UI-tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v6&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up node&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v6&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;24.x&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npm ci&lt;/span&gt;
          &lt;span class="s"&gt;npx playwright install chromium&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JS lint&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npm run lint || (echo "Linting failed! Please run 'npm run lint:fix' to fix the errors." &amp;amp;&amp;amp; exit 1)&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run the project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npm run serve &amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;npm run backend &amp;amp;&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Wait for services&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;sudo apt-get install wait-for-it -y&lt;/span&gt;
          &lt;span class="s"&gt;wait-for-it -h localhost -p 8080 -t 10&lt;/span&gt;
          &lt;span class="s"&gt;wait-for-it -h localhost -p 3000 -t 10&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run UI tests&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-ui&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test:e2e tests&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload trace results&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ failure() &amp;amp;&amp;amp; steps.test-ui.conclusion == 'failure' }}&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v6&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;trace-results/*.zip&lt;/span&gt;
            &lt;span class="s"&gt;retention-days: 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔍 What does this workflow do?
&lt;/h2&gt;

&lt;p&gt;This GitHub Actions file runs when you push to the &lt;code&gt;master&lt;/code&gt; branch or create a pull request to &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It has one job called &lt;code&gt;e2e-UI-tests&lt;/code&gt; with these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Checkout repo code&lt;/strong&gt; - Gets the project code from GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up node&lt;/strong&gt; - Installs Node.js version 24.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install dependencies&lt;/strong&gt; - Installs the project dependencies and Playwright browsers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS lint&lt;/strong&gt; - Runs the linter to check for code quality issues. If linting fails, it will print a custom error message and exit with a failure status.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the project&lt;/strong&gt; - Starts the Vue app and the backend using json-server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait for services&lt;/strong&gt; - Waits for the frontend (port 8080) and backend (port 3000) to be ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run UI tests&lt;/strong&gt; - Runs the UI tests using Playwright.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload trace results&lt;/strong&gt; - If the UI tests fail, it uploads the Playwright trace results as an artifact that can be downloaded from the GitHub Actions interface. The trace files will be retained for 30 days.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  📥 How to Download and View Trace Files?
&lt;/h2&gt;

&lt;p&gt;If your tests fail in CI, you can download the trace files to see what went wrong:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your GitHub repository&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Actions&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Select the failed workflow run&lt;/li&gt;
&lt;li&gt;Scroll down to the &lt;strong&gt;Artifacts&lt;/strong&gt; section at the bottom of the page&lt;/li&gt;
&lt;li&gt;Click on the artifact name to download the trace files (they will be in a &lt;code&gt;.zip&lt;/code&gt; file)&lt;/li&gt;
&lt;li&gt;Extract the downloaded &lt;code&gt;.zip&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Open the trace file using one of these methods:

&lt;ul&gt;
&lt;li&gt;Drag and drop the trace file into &lt;a href="https://trace.playwright.dev" rel="noopener noreferrer"&gt;trace.playwright.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Or run this command locally: &lt;code&gt;npx playwright show-trace path/to/trace.zip&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The trace viewer will show you step-by-step what happened during the test, including screenshots, network requests, and console logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  📝 Conclusion
&lt;/h2&gt;

&lt;p&gt;Using GitHub Actions to run your Playwright tests means your app is tested automatically in a clean environment every time you make changes. It helps find bugs early, makes teamwork easier, and keeps your project stable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CI tests turn "hope it works" into "we know it works."&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>playwright</category>
      <category>githubactions</category>
      <category>automation</category>
      <category>testing</category>
    </item>
    <item>
      <title>Helpful for keycloak script</title>
      <dc:creator>Nabin Ale</dc:creator>
      <pubDate>Fri, 23 Aug 2024 06:49:08 +0000</pubDate>
      <link>https://forem.com/nabim777/helpful-for-keycloak-script-1lpo</link>
      <guid>https://forem.com/nabim777/helpful-for-keycloak-script-1lpo</guid>
      <description>&lt;p&gt;Altogether I have found three method to set up keycloak can be used as the bash script. methods are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Using Admin CLI bash command
2. By importing the json file
3. Using API (recommended)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. Using Admin CLI command
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;/strong&gt;  following command is for docker if keycloak is locally run then you can run command inside &lt;code&gt;''&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;a. Login&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;keycloak-keycloak-1 /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cd opt/keycloak/bin &amp;amp;&amp;amp; bash kcadm.sh config credentials --server &amp;lt;keycloak-host&amp;gt; --realm master --user admin --password admin'&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b. Create realm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;keycloak-keycloak-1 /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cd opt/keycloak/bin &amp;amp;&amp;amp; bash kcadm.sh create realms -s realm=&amp;lt;realm-name&amp;gt; -s enabled=true -o'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;c. Create clients( here we get client-id )&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;keycloak-keycloak-1 /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd opt/keycloak/bin &amp;amp;&amp;amp; bash kcadm.sh create clients -r opendesk -s clientId=nextcloud -s enabled=true -s 'redirectUris=[&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;nextcloud-host&amp;gt;/apps/user_oidc/code&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]' -s rootUrl=&amp;lt;nextcloud-host&amp;gt; -s 'attributes.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;backchannel.logout.url&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;=&amp;lt;nextcloud-host&amp;gt;/apps/user_oidc/backchannel-logout/Keycloak' -s 'attributes.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;post.logout.redirect.uris&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;=&amp;lt;nextcloud-host&amp;gt;/*' -s 'webOrigins=[&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;nextcloud-host&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]' -s adminUrl=&amp;lt;nextcloud-host&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;d. Get secretId&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;keycloak-keycloak-1 /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cd opt/keycloak/bin &amp;amp;&amp;amp; bash kcadm.sh get clients/&amp;lt;Client-ID&amp;gt; -r &amp;lt;realm-name&amp;gt; --fields secret'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e. OIDC configure (this is for user_oidc on nextcloud)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; www-data nextcloud php ./occ user_oidc:provider Keycloak &lt;span class="nt"&gt;--clientid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"nextcloud"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--clientsecret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;secret-id&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;--discoveryuri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;keycloak-host&amp;gt;/realms/&amp;lt;realm-name&amp;gt;/.well-known/openid-configuration"&lt;/span&gt; &lt;span class="nt"&gt;--scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"openid email profile"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. By importing the json file
&lt;/h2&gt;

&lt;p&gt;It simply by importing the json file in a realm with the help of import admin bash cli command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash kc.sh &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--dir&lt;/span&gt; &amp;lt;path-to-json-file&amp;gt; &lt;span class="nt"&gt;--realm&lt;/span&gt; &amp;lt;realm-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Using API
&lt;/h2&gt;

&lt;p&gt;a. getting the acess token using api&lt;/p&gt;

&lt;p&gt;following curlcommand will store the acess_token in variable &lt;code&gt;MASTER_TOKEN&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MASTER_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &amp;lt;keycloak-host&amp;gt;/realms/master/protocol/openid-connect/token &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/x-www-form-urlencoded'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'client_id=admin-cli'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'username=admin'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'password=admin'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'grant_type=password'&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.access_token'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b. Creating the realm using API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&amp;lt;keycloak-host&amp;gt;/admin/realms"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ""&lt;/span&gt;&lt;span class="nv"&gt;$MASTER_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"realm":"opendesk","enabled":true}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;c. Creating the clients using API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://keycloak.local/admin/realms/opendesk/clients"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ""&lt;/span&gt;&lt;span class="nv"&gt;$MASTER_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "clientId": "nextcloud",
    "enabled": true, 
    "redirectUris" : ["&amp;lt;nextcloud-host&amp;gt;/apps/user_oidc/code"],
    "rootUrl": "&amp;lt;nextcloud-host&amp;gt;",
    "attributes": {
     "backUsing Admin CLI bash commandchannel.logout.url": "&amp;lt;nextcloud-host&amp;gt;/apps/user_oidc/backchannel-logout/Keycloak"
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;d. Get the secret id using API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&amp;lt;keycloak-host&amp;gt;/admin/realms/opendesk/clients"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ""&lt;/span&gt;&lt;span class="nv"&gt;$MASTER_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.[] | select(.clientId == "nextcloud") | .secret'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Factory Design Pattern</title>
      <dc:creator>Nabin Ale</dc:creator>
      <pubDate>Mon, 20 May 2024 01:23:39 +0000</pubDate>
      <link>https://forem.com/nabim777/factory-design-pattern-4n5j</link>
      <guid>https://forem.com/nabim777/factory-design-pattern-4n5j</guid>
      <description>&lt;p&gt;The Factory Design Pattern is a way to create objects without specifying the exact class of the object that will be created. It provides a method to create objects that can be overridden by subclasses to change the type of objects that will be created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding through Example
&lt;/h2&gt;

&lt;p&gt;Let's use the Factory Design Pattern with an example involving a waiter, a cook, and the client in a restaurant setting. Here’s how the pattern works in this context:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a. Waiter:&lt;/strong&gt; Acts as the Factory.&lt;br&gt;
&lt;strong&gt;b. Cook:&lt;/strong&gt; Represents the different types of objects that can be created.&lt;br&gt;
&lt;strong&gt;c. Client:&lt;/strong&gt; Requests a dish through the waiter.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scenario
&lt;/h2&gt;

&lt;p&gt;A client goes to a restaurant and asks the waiter for a specific dish (e.g., &lt;a href="https://junifoods.com/wp-content/uploads/2023/11/Easy-and-Simple-Chicken-Momo-Dumplings-Sajilo-Kukhura-ko-Momo-%E0%A4%B8%E0%A4%9C%E0%A4%BF%E0%A4%B2%E0%A5%8B-%E0%A4%95%E0%A5%81%E0%A4%96%E0%A5%81%E0%A4%B0%E0%A4%BE%E0%A4%95%E0%A5%8B-%E0%A4%AE%E0%A4%AE-1.jpg"&gt;Momo&lt;/a&gt; or &lt;a href="https://www.southernliving.com/thmb/j_6gABRIAMegN6RFHxOgbUqBxjA=/750x0/filters:no_upscale():max_bytes(150000):strip_icc():format(webp)/2652401_QFSSL_SupremePizza_00072-d910a935ba7d448e8c7545a963ed7101.jpg"&gt;Pizza&lt;/a&gt;). The waiter takes the order and instructs the cook to prepare the dish. The client doesn't know the details of how the dish is prepared; they just get the dish.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-by-Step Example in TypeScript
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Define the Dish Interface&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This interface defines a method prepare() that every dish must implement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Create Concrete Classes for Dishes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Momo&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Preparing Momo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Preparing Pizza&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These classes implement the Dish interface and provide their own version of the prepare method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Create the Waiter (Factory)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Waiter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;orderDish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dishType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dishType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Momo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Momo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Waiter class has a static method orderDish that takes a string parameter dishType and returns an instance of the corresponding dish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Client Requests a Dish&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dish1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Waiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orderDish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Momo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dish1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;dish1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Output: Preparing Momo&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dish2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Waiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orderDish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dish2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;dish2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Output: Preparing Pizza&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client uses the Waiter to order dishes by specifying the dish type. The Waiter (factory) handles the creation of the dish, and the client receives a dish ready to be prepared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Dish Interface:&lt;/strong&gt; This defines a common interface that all dishes must follow.&lt;br&gt;
&lt;strong&gt;- Concrete Classes (Momo, Pizza):&lt;/strong&gt; Implement the Dish interface and provide specific implementations for the prepare method.&lt;br&gt;
&lt;strong&gt;- Waiter (Factory):&lt;/strong&gt; Contains the orderDish method, which decides which dish to create based on the given type.&lt;br&gt;
&lt;strong&gt;- Client:&lt;/strong&gt; Requests dishes from the Waiter without needing to know the details of how the dishes are created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full given Example in TypeScript look like this&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dish Interface&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete Momo Class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Momo&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Preparing Momo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Concrete Pizza Class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Preparing Pizza&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Waiter (Factory) Class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Waiter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;orderDish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dishType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dishType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Momo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Momo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Client Code&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dish1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Waiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orderDish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Momo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dish1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;dish1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Output: Preparing Momo&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dish2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dish&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Waiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orderDish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dish2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;dish2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Output: Preparing Pizza&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To execute the code within a web browser &lt;a href="https://www.mycompiler.io/view/8TPVEzvUkcf"&gt;click here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why use the Factory Design Pattern?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;1. Decoupling:&lt;/strong&gt; It decouples the client code from the object creation process. It separates the part of the code that asks for an object from the part that makes the object. This way, the code that needs the object doesn't have to know exactly how the object is made&lt;br&gt;
&lt;strong&gt;2. Flexibility:&lt;/strong&gt; It allows the code to be more flexible and easier to extend. New classes can be added without changing the existing client code.&lt;br&gt;
&lt;strong&gt;3. Single Responsibility:&lt;/strong&gt; The Factory Design Pattern follows the Single Responsibility Principle by making sure that each class has only one job&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;In this example, the client interacts only with the Waiter (factory), asking for specific dishes. The Waiter then decides which type of dish to create and returns it to the client. This pattern decouples the client from the creation logic, making the system more modular and easier to maintain.&lt;/p&gt;

</description>
      <category>factorydesignpattern</category>
      <category>oop</category>
    </item>
    <item>
      <title>Introduction to GitHub Actions - CI &amp; CD</title>
      <dc:creator>Nabin Ale</dc:creator>
      <pubDate>Thu, 25 Apr 2024 05:06:24 +0000</pubDate>
      <link>https://forem.com/jankaritech/introduction-to-github-actions-ci-cd-41c9</link>
      <guid>https://forem.com/jankaritech/introduction-to-github-actions-ci-cd-41c9</guid>
      <description>&lt;p&gt;GitHub Actions is an automation and CI/CD (Continuous Integration/Continuous Delivery or Deployment) service provided by GitHub, allowing us to automate our software development processes or workflows, from building and testing code to deploying it to different environments. It's an effective tool that can enhance software quality and save our time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some features of GitHub Actions:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It allows you to automate various stages of SDLC (Software Development Life Cycle), such as building, testing, deploying, and releasing software.&lt;/li&gt;
&lt;li&gt;It simplifies CI/CD integration, facilitating seamless DevOps practices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Components of GitHub Actions:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Workflows&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Jobs&lt;/li&gt;
&lt;li&gt;Steps&lt;/li&gt;
&lt;li&gt;Actions&lt;/li&gt;
&lt;li&gt;Runners&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3r48l2mu7uc5yqzbcizd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3r48l2mu7uc5yqzbcizd.png" alt="Image description" width="763" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Workflows
&lt;/h3&gt;

&lt;p&gt;Workflows are automated procedures that you add to your repository. They will run when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule. They can be used to build, test, package, release, or deploy a project on GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Events
&lt;/h3&gt;

&lt;p&gt;Events are specific activities such as code push, pull request creation, issue creation, comments on pull requests or issues, etc., that trigger a workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Jobs
&lt;/h3&gt;

&lt;p&gt;Jobs are sets of steps that are executed in the same runner. A workflow with multiple jobs will run in parallel by default, but it can be configured so that jobs run sequentially.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Steps
&lt;/h3&gt;

&lt;p&gt;A step is an individual task that can run the commands in a job. These can be actions or commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Actions
&lt;/h3&gt;

&lt;p&gt;Actions are the standalone commands for the GitHub Actions platform that perform complex but frequently repeated tasks. Actions help to reduce repetitive code in workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Runner
&lt;/h3&gt;

&lt;p&gt;A runner is a GitHub Actions server where our workflows run. It listens for available jobs, runs multiple jobs at a time, and reports the progress, logs, and results back to GitHub. GitHub hosted runners are based on Ubuntu, Linux, Microsoft Windows, and Mac OS.&lt;/p&gt;

&lt;p&gt;Note:&lt;br&gt;
One event can trigger many workflows, a workflow can contain many jobs, and a job can contain many steps.&lt;/p&gt;
&lt;h2&gt;
  
  
  Process in GitHub Actions:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgelwyoe03zqlobqpewn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgelwyoe03zqlobqpewn8.png" alt="Image description" width="501" height="474"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started:
&lt;/h2&gt;

&lt;p&gt;Before we dive into an example, make sure you have a repository where you want to set up your CI/CD workflow. If you don't have one, create a new repository, for example, named &lt;code&gt;action-hero&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Step 1: Clone your repository into your system&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;your_github_repo_url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Go to path &lt;code&gt;action-hero&lt;/code&gt; and create a folder named &lt;code&gt;.github&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;action-hero
&lt;span class="nb"&gt;mkdir&lt;/span&gt; .github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Go to path &lt;code&gt;.github&lt;/code&gt; and create a folder named &lt;code&gt;workflows&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; .github
&lt;span class="nb"&gt;mkdir &lt;/span&gt;workflows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Inside the folder &lt;code&gt;workflows&lt;/code&gt;, create a file named &lt;code&gt;hello_world.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;workflows
&lt;span class="nb"&gt;touch &lt;/span&gt;hello_world.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our file structure should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦action-hero
┗ 📂.github
┃ ┣ 📂workflows
┃ ┃ ┗ 📜hello_world.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Add the following code snippet to your &lt;code&gt;hello_world.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello world workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Print a message&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello, GitHub Actions!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The workflow is triggered by a push event on the main branch.&lt;/li&gt;
&lt;li&gt;The job named "build" runs on the latest version of Ubuntu.&lt;/li&gt;
&lt;li&gt;The first step checks out the repository using the &lt;code&gt;actions/checkout&lt;/code&gt; action.&lt;/li&gt;
&lt;li&gt;The second step simply prints a message using the &lt;code&gt;echo&lt;/code&gt; command.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub Actions activity:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdtgb7oluv0vdpvcjodr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdtgb7oluv0vdpvcjodr.png" alt="Image description" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above is the output from our GitHub Actions workflow run. It shows that the workflow was successful and completed the &lt;code&gt;Hello world workflow&lt;/code&gt; job, which consisted of two steps: &lt;code&gt;Checkout repository&lt;/code&gt; and &lt;code&gt;Print a message&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The step &lt;code&gt;Print a message&lt;/code&gt; executed the command &lt;code&gt;echo "Hello, GitHub Actions!"&lt;/code&gt;, resulting in the output &lt;code&gt;Hello, GitHub Actions!&lt;/code&gt; being displayed in the workflow log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this blog, we've explored GitHub Actions, an automation and CI/CD service provided by GitHub. We've learned about its key components and how they work together to automate software development workflows.&lt;/p&gt;

&lt;p&gt;GitHub Actions enables us to automate tasks like building, testing, and deploying code, leading to improved software quality and time savings.&lt;/p&gt;

&lt;p&gt;With a practical example, we've seen how easy it is to set up a basic workflow.&lt;/p&gt;

&lt;p&gt;In summary, GitHub Actions is a powerful tool for speedy development processes, making it easier to deliver high-quality software efficiently.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>githubactions</category>
      <category>cicd</category>
      <category>devops</category>
    </item>
    <item>
      <title>Set SSH keys for Github in ubuntu or linux mint</title>
      <dc:creator>Nabin Ale</dc:creator>
      <pubDate>Sat, 14 Oct 2023 01:50:52 +0000</pubDate>
      <link>https://forem.com/nabim777/set-github-for-ssh-in-ubuntu-or-linux-mint-5ena</link>
      <guid>https://forem.com/nabim777/set-github-for-ssh-in-ubuntu-or-linux-mint-5ena</guid>
      <description>&lt;h2&gt;
  
  
  Github Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo apt install ppa-purge
sudo ppa-purge ppa:git-core/ppa
sudo apt purge git
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring the git
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global user.name "&amp;lt;your_github_username&amp;gt;"
git config --global user.email &amp;lt;your_email@example.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;/strong&gt;  To check the user.name and user.email set or not &lt;br&gt;
&lt;code&gt;git config -l&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Keys generation
&lt;/h2&gt;

&lt;p&gt;Step 1: Generate new ssh keys&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t ed25519 -C "your_email@example.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Add a new ssh keys&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat ~/.ssh/id_ed25519.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Output will be something like this&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
ssh-ed25519 &lt;br&gt;
NAAAC3Nza*********jPRyyNVIdgj&lt;br&gt;
&lt;a href="mailto:your_email@example.com"&gt;your_email@example.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Step 3: Copy output and paste in &lt;code&gt;setting &amp;gt; SSH and GPG keys &amp;gt; new SSH key&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mrlhokvusj1s5wfh54s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mrlhokvusj1s5wfh54s.jpg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>nalem7</category>
      <category>beginners</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
