{"id":24625,"date":"2014-09-07T22:52:05","date_gmt":"2014-09-08T03:52:05","guid":{"rendered":"https:\/\/wordpress-1325650-4848760.cloudwaysapps.com\/?p=24625"},"modified":"2025-05-15T11:26:29","modified_gmt":"2025-05-15T15:26:29","slug":"github-actions-tutorial","status":"publish","type":"post","link":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial","title":{"rendered":"GitHub Actions Tutorial: Automating Your Deployment Workflow"},"content":{"rendered":"\n<p>Automation With Github Actions automation has completely transformed how I handle deployments. Back in the old days (which wasn&#8217;t actually that long ago), we relied on clunky webhooks on github and custom scripts to get our code from repository to production. While those methods worked, but they were absolutely painful to maintain.<\/p>\n\n\n\n<p>In this Github Actions tutorial, I&#8217;m going to show you EXACTLY how to create powerful, flexible deployment workflows that will save you countless hours of manual work. Trust me, once you start automating your deployments, you&#8217;ll never want to go back to the old ways.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Are GitHub Actions?<\/h2>\n\n\n\n<p>GitHub Actions is a CI\/CD (Continuous Integration\/Continuous Deployment) platform built directly into GitHub. It lets you automate your build, test, and deployment pipeline without needing to set up any external systems.<\/p>\n\n\n\n<p>Unlike the old webhook approach that required maintaining separate build scripts and servers, GitHub Actions handles everything within the GitHub ecosystem. This means faster setup, better integration, and less headache.<\/p>\n\n\n\n<p>The best part? Every GitHub repository comes with free build minutes each month &#8211; 2,000 minutes for public repositories and 3,000 minutes for private repositories on the free plan. That&#8217;s seriously generous, especially for smaller projects.<\/p>\n\n\n\n<p><em>Tip \ud83d\udca1: level up your productivity with our <a href=\"https:\/\/codesamplez.com\/productivity\/git-commands\" target=\"_blank\" rel=\"noreferrer noopener\">git commands cheat sheet<\/a>!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why You Need GitHub Actions<\/h2>\n\n\n\n<p>Before diving into the how-to, let&#8217;s talk about why you absolutely need to be using GitHub Actions:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Save tremendous time<\/strong> by automating repetitive deployment tasks<\/li>\n\n\n\n<li><strong>Reduce human errors<\/strong> that inevitably happen during manual deployments<\/li>\n\n\n\n<li><strong>Maintain consistent environments<\/strong> across development, staging, and production<\/li>\n\n\n\n<li><strong>Get instant feedback<\/strong> when something breaks<\/li>\n\n\n\n<li><strong>Create robust testing workflows<\/strong> that run automatically<\/li>\n\n\n\n<li><strong>Scale easily<\/strong> as your project grows<\/li>\n<\/ol>\n\n\n\n<p>Honestly, the benefits are so substantial that I can&#8217;t imagine working without automated workflows anymore.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started with GitHub Actions<\/h2>\n\n\n\n<p>Setting up your first GitHub Action workflow is incredibly straightforward. Let&#8217;s break it down step by step:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Create Your Workflow File<\/h3>\n\n\n\n<p>GitHub Actions workflows are defined in YAML files stored in the <code>.github\/workflows<\/code> directory of your repository. Let&#8217;s create a simple deployment workflow:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In your repository, create the directory <code>.github\/workflows<\/code> if it doesn&#8217;t already exist<\/li>\n\n\n\n<li>Create a new file called <code>deploy.yml<\/code> in that directory<\/li>\n<\/ol>\n\n\n\n<p>Here&#8217;s a basic workflow to get you started:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">name: Deploy Application\n\non:\n  push:\n    branches: &#91; main ]\n  workflow_dispatch:  <span class=\"hljs-comment\"># Allows manual triggering<\/span>\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v3\n      \n      - name: Setup Node.js\n        uses: actions\/setup-node@v3\n        with:\n          node-version: <span class=\"hljs-string\">'16'<\/span>\n      \n      - name: Install dependencies\n        run: npm install\n      \n      - name: Build application\n        run: npm run build\n      \n      - name: Deploy to server\n        uses: easingthemes\/ssh-deploy@v4<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.8<\/span>\n        with:\n          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}\n          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}\n          REMOTE_USER: ${{ secrets.REMOTE_USER }}\n          SOURCE: <span class=\"hljs-string\">\"dist\/\"<\/span>\n          TARGET: <span class=\"hljs-string\">\"\/var\/www\/html\/\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This workflow will trigger whenever someone pushes to the main branch, checkout the code, set up Node.js, install dependencies, build the application, and then deploy it to your server using SSH.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Set Up Secrets<\/h3>\n\n\n\n<p>For the deployment step, we need to securely store our SSH credentials. GitHub provides a secure way to store sensitive information using Secrets:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to your repository settings<\/li>\n\n\n\n<li>Click on &#8220;Secrets and variables&#8221; and then &#8220;Actions&#8221;<\/li>\n\n\n\n<li>Click &#8220;New repository secret&#8221;<\/li>\n\n\n\n<li>Add secrets for <code>SSH_PRIVATE_KEY<\/code>, <code>REMOTE_HOST<\/code>, and <code>REMOTE_USER<\/code><\/li>\n<\/ol>\n\n\n\n<p>These secrets are encrypted and only exposed to the GitHub Actions workflow during run time. They&#8217;ll never be visible in logs or to people who don&#8217;t have admin access to your repository.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Push Your Changes<\/h3>\n\n\n\n<p>Commit your workflow file and push it to your repository. This will automatically trigger the workflow if you&#8217;re pushing to the main branch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Workflow Syntax<\/h2>\n\n\n\n<p>Let&#8217;s break down the key components of a GitHub Actions workflow:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Triggers<\/h3>\n\n\n\n<p>The <code>on<\/code> section defines when your workflow should run:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">on:\n  push:\n    branches: &#91; main, develop ]\n  pull_request:\n    branches: &#91; main ]\n  schedule:\n    - cron: <span class=\"hljs-string\">'0 0 * * *'<\/span>  <span class=\"hljs-comment\"># Run daily at midnight<\/span>\n  workflow_dispatch:     <span class=\"hljs-comment\"># Manual trigger<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You can trigger workflows on pushes, pull requests, on a schedule using cron syntax, or manually using the <code>workflow_dispatch<\/code> event.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Jobs<\/h3>\n\n\n\n<p>Workflows are made up of one or more jobs that can run in parallel or sequentially:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">jobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      <span class=\"hljs-comment\"># Test steps here<\/span>\n  \n  build:\n    needs: test  <span class=\"hljs-comment\"># This job will only run after 'test' completes<\/span>\n    runs-on: windows-latest\n    steps:\n      <span class=\"hljs-comment\"># Build steps here<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>needs<\/code> keyword creates dependencies between jobs, ensuring they run in the right order.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Runners<\/h3>\n\n\n\n<p>The <code>runs-on<\/code> property specifies the type of machine to run the job on. GitHub provides runners for Linux, Windows, and macOS:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ubuntu-latest<\/code> (Linux)<\/li>\n\n\n\n<li><code>windows-latest<\/code> (Windows)<\/li>\n\n\n\n<li><code>macos-latest<\/code> (macOS)<\/li>\n<\/ul>\n\n\n\n<p>You can also set up self-hosted runners if you need specialized environments.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Steps<\/h3>\n\n\n\n<p>Each job consists of a sequence of steps:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">steps:\n  - name: Checkout code\n    uses: actions\/checkout@v3\n  \n  - name: Run a command\n    run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Hello, World!\"<\/span>\n  \n  - name: Run a script\n    run: |\n      <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"This is a multi-line script\"<\/span>\n      .\/my-script.sh\n      <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Script completed\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Steps can either use pre-built actions (with the <code>uses<\/code> keyword) or run commands directly (with the <code>run<\/code> keyword).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced GitHub Actions Features<\/h2>\n\n\n\n<p>Once you&#8217;re comfortable with the basics, you can leverage these advanced features:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Environment Variables<\/h3>\n\n\n\n<p>You can define environment variables at the workflow, job, or step level:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">env:\n  GLOBAL_VAR: <span class=\"hljs-string\">\"Available to all jobs\"<\/span>\n\n<span class=\"hljs-attr\">jobs<\/span>:\n  build:\n    env:\n      JOB_VAR: <span class=\"hljs-string\">\"Available to all steps in this job\"<\/span>\n    <span class=\"hljs-attr\">steps<\/span>:\n      - name: Step <span class=\"hljs-keyword\">with<\/span> env vars\n        <span class=\"hljs-attr\">env<\/span>:\n          STEP_VAR: <span class=\"hljs-string\">\"Available only in this step\"<\/span>\n        <span class=\"hljs-attr\">run<\/span>: echo <span class=\"hljs-string\">\"$GLOBAL_VAR $JOB_VAR $STEP_VAR\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Matrix Builds<\/h3>\n\n\n\n<p>Matrix builds let you test across multiple configurations simultaneously:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">jobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node-version: &#91;<span class=\"hljs-number\">12.<\/span>x, <span class=\"hljs-number\">14.<\/span>x, <span class=\"hljs-number\">16.<\/span>x]\n        os: &#91;ubuntu-latest, windows-latest]\n    steps:\n      - uses: actions\/checkout@v3\n      - name: <span class=\"hljs-keyword\">Use<\/span> <span class=\"hljs-title\">Node<\/span>.<span class=\"hljs-title\">js<\/span> ${{ <span class=\"hljs-title\">matrix<\/span>.<span class=\"hljs-title\">node<\/span>-<span class=\"hljs-title\">version<\/span> }}\n        <span class=\"hljs-title\">uses<\/span>: <span class=\"hljs-title\">actions<\/span>\/<span class=\"hljs-title\">setup<\/span>-<span class=\"hljs-title\">node<\/span>@<span class=\"hljs-title\">v3<\/span>\n        <span class=\"hljs-title\">with<\/span>:\n          <span class=\"hljs-title\">node<\/span>-<span class=\"hljs-title\">version<\/span>: ${{ <span class=\"hljs-title\">matrix<\/span>.<span class=\"hljs-title\">node<\/span>-<span class=\"hljs-title\">version<\/span> }}\n      - <span class=\"hljs-title\">run<\/span>: <span class=\"hljs-title\">npm<\/span> <span class=\"hljs-title\">test<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This would run your tests against Node.js 12, 14, and 16 on both Ubuntu and Windows &#8211; a total of 6 different combinations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Caching Dependencies<\/h3>\n\n\n\n<p>To speed up your workflows, cache dependencies between runs:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">steps:\n  - uses: actions\/checkout@v3\n  \n  - name: Cache npm dependencies\n    uses: actions\/cache@v3\n    with:\n      path: ~\/.npm\n      key: npm-${{ hashFiles(<span class=\"hljs-string\">'package-lock.json'<\/span>) }}\n      restore-keys: npm-\n  \n  - name: Install dependencies\n    run: npm install<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This can dramatically reduce build times for subsequent runs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Implementing Multi-Environment Deployments<\/h2>\n\n\n\n<p>One of the most powerful features of GitHub Actions is the ability to deploy to different environments based on branch or event.<\/p>\n\n\n\n<p>Here&#8217;s how to set up a workflow for deploying to both staging and production:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">name: Deploy Pipeline\n\n<span class=\"hljs-attr\">on<\/span>:\n  push:\n    branches: &#91;develop, main]\n\n<span class=\"hljs-attr\">jobs<\/span>:\n  deploy:\n    runs-on: ubuntu-latest\n    <span class=\"hljs-attr\">steps<\/span>:\n      - uses: actions\/checkout@v3\n      \n      - name: Setup application\n        <span class=\"hljs-attr\">run<\/span>: |\n          npm install\n          npm run build\n      \n      - name: Deploy to Staging\n        <span class=\"hljs-attr\">if<\/span>: github.ref == <span class=\"hljs-string\">'refs\/heads\/develop'<\/span>\n        <span class=\"hljs-attr\">uses<\/span>: easingthemes\/ssh-deploy@v4<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.8<\/span>\n        <span class=\"hljs-attr\">with<\/span>:\n          SSH_PRIVATE_KEY: ${{ secrets.STAGING_SSH_KEY }}\n          <span class=\"hljs-attr\">REMOTE_HOST<\/span>: ${{ secrets.STAGING_HOST }}\n          <span class=\"hljs-attr\">REMOTE_USER<\/span>: ${{ secrets.STAGING_USER }}\n          <span class=\"hljs-attr\">SOURCE<\/span>: <span class=\"hljs-string\">\"dist\/\"<\/span>\n          <span class=\"hljs-attr\">TARGET<\/span>: <span class=\"hljs-string\">\"\/var\/www\/staging\/\"<\/span>\n      \n      - name: Deploy to Production\n        <span class=\"hljs-attr\">if<\/span>: github.ref == <span class=\"hljs-string\">'refs\/heads\/main'<\/span>\n        <span class=\"hljs-attr\">uses<\/span>: easingthemes\/ssh-deploy@v4<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.8<\/span>\n        <span class=\"hljs-attr\">with<\/span>:\n          SSH_PRIVATE_KEY: ${{ secrets.PRODUCTION_SSH_KEY }}\n          <span class=\"hljs-attr\">REMOTE_HOST<\/span>: ${{ secrets.PRODUCTION_HOST }}\n          <span class=\"hljs-attr\">REMOTE_USER<\/span>: ${{ secrets.PRODUCTION_USER }}\n          <span class=\"hljs-attr\">SOURCE<\/span>: <span class=\"hljs-string\">\"dist\/\"<\/span>\n          <span class=\"hljs-attr\">TARGET<\/span>: <span class=\"hljs-string\">\"\/var\/www\/production\/\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this workflow, pushing to the <code>develop<\/code> branch deploys to staging, while pushing to <code>main<\/code> deploys to production. The <code>if<\/code> conditions ensure each deployment step only runs for the appropriate branch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing Before Deployment<\/h2>\n\n\n\n<p>A robust CI\/CD pipeline should include testing to prevent deploying broken code. Here&#8217;s how to add testing to your workflow:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">jobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v3\n      \n      - name: Set up Node.js\n        uses: actions\/setup-node@v3\n        with:\n          node-version: <span class=\"hljs-string\">'16'<\/span>\n      \n      - name: Install dependencies\n        run: npm install\n      \n      - name: Run tests\n        run: npm test\n  \n  deploy:\n    needs: test  <span class=\"hljs-comment\"># Only deploy if tests pass<\/span>\n    runs-on: ubuntu-latest\n    steps:\n      <span class=\"hljs-comment\"># Deployment steps here<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>By adding the <code>needs: test<\/code> line, the deployment job will only run if the test job completes successfully.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting Common Issues<\/h2>\n\n\n\n<p>Even with automation, things sometimes go wrong. Here are some common issues and how to fix them:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Failed Deployments<\/h3>\n\n\n\n<p>If your deployment fails, first check the workflow logs for error messages. Common problems include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Permission issues<\/strong>: Ensure your SSH user has the necessary permissions<\/li>\n\n\n\n<li><strong>Connection problems<\/strong>: Verify host address and network configurations<\/li>\n\n\n\n<li><strong>Space limitations<\/strong>: Check if your server has enough disk space<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Debugging Workflows<\/h3>\n\n\n\n<p>For complex debugging, you can set up SSH access to the runner:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">steps:\n  - name: Setup tmate session\n    if: ${{ failure() }}\n    uses: mxschmitt\/action-tmate@v3<\/code><\/span><\/pre>\n\n\n<p>This creates an SSH session to the runner if a previous step fails, allowing you to investigate interactively.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices for GitHub Actions<\/h2>\n\n\n\n<p>To make the most out of GitHub Actions, follow these best practices:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Keep workflows focused<\/strong>: Create separate workflows for different purposes (testing, deployment, etc.)<\/li>\n\n\n\n<li><strong>Use official actions<\/strong>: Prefer well-maintained actions from verified creators<\/li>\n\n\n\n<li><strong>Set timeout limits<\/strong>: Add <code>timeout-minutes<\/code> to prevent stuck jobs from running forever<\/li>\n\n\n\n<li><strong>Add status badges<\/strong>: Include workflow status badges in your README<\/li>\n\n\n\n<li><strong>Use concurrency limits<\/strong>: Prevent parallel runs of the same workflow with <code>concurrency<\/code> settings<\/li>\n\n\n\n<li><strong>Add manual approval<\/strong> for sensitive environments using <code>environment<\/code> configurations<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>GitHub Actions has completely revolutionized how we approach deployment automation. With its tight integration into GitHub, extensive marketplace of pre-built actions, and powerful workflow capabilities, it&#8217;s now easier than ever to create robust CI\/CD pipelines.<\/p>\n\n\n\n<p>I&#8217;ve personally migrated all my projects from the old webhook-based approach to GitHub Actions, and the difference is night and day. Deployments are now consistent, reliable, and completely hands-off.<\/p>\n\n\n\n<p>If you&#8217;re still using manual deployments or older automation tools, I strongly encourage you to give GitHub Actions a try. The time savings alone make it worth the initial setup investment, not to mention the peace of mind that comes from knowing your deployments are handled automatically.<\/p>\n\n\n\n<p>Have you implemented GitHub Actions in your workflow? Let me know about your experiences in the comments below!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Additional Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/sdras\/awesome-actions\" target=\"_blank\" rel=\"noreferrer noopener\">Awesome Actions<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/actions\" target=\"_blank\" rel=\"noreferrer noopener\">Official Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/marketplace?type=actions\" target=\"_blank\" rel=\"noreferrer noopener\">Actions Marketplace<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.github.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub Learning Lab<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Automation has transformed how developers handle deployments. GitHub Actions provides a powerful CI\/CD platform built directly into GitHub, eliminating the need for external systems. In this tutorial, I&#8217;ll show you exactly how to create automated workflows that will save you countless hours and reduce deployment errors.<\/p>\n","protected":false},"author":1,"featured_media":58659,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[32],"tags":[3290,26,27],"class_list":{"0":"post-24625","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-devops","8":"tag-deployment","9":"tag-git","10":"tag-github","11":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.4 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>GitHub Actions Tutorial: Automating Your Deployment Workflow - CodeSamplez.com<\/title>\n<meta name=\"description\" content=\"In this comprehensive tutorial, learn how to set up automated deployment workflows with GitHub Actions, streamlining your development process.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/codesamplez.com\/devops\/github-actions-tutorial\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GitHub Actions Tutorial: Automating Your Deployment Workflow\" \/>\n<meta property=\"og:description\" content=\"In this comprehensive tutorial, learn how to set up automated deployment workflows with GitHub Actions, streamlining your development process.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/codesamplez.com\/devops\/github-actions-tutorial\" \/>\n<meta property=\"og:site_name\" content=\"CodeSamplez.com\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/codesamplez\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/ranacseruet\" \/>\n<meta property=\"article:published_time\" content=\"2014-09-08T03:52:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-15T15:26:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1536\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Rana Ahsan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ranacseruet\" \/>\n<meta name=\"twitter:site\" content=\"@codesamplez\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rana Ahsan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial\"},\"author\":{\"name\":\"Rana Ahsan\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#\\\/schema\\\/person\\\/a82c3c07205f4bb73d6b3b0906bc328b\"},\"headline\":\"GitHub Actions Tutorial: Automating Your Deployment Workflow\",\"datePublished\":\"2014-09-08T03:52:05+00:00\",\"dateModified\":\"2025-05-15T15:26:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial\"},\"wordCount\":1170,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/codesamplez.com\\\/wp-content\\\/uploads\\\/2014\\\/09\\\/github-actions-tutorial.webp\",\"keywords\":[\"deployment\",\"git\",\"github\"],\"articleSection\":[\"DevOps\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial\",\"url\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial\",\"name\":\"GitHub Actions Tutorial: Automating Your Deployment Workflow - CodeSamplez.com\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/codesamplez.com\\\/wp-content\\\/uploads\\\/2014\\\/09\\\/github-actions-tutorial.webp\",\"datePublished\":\"2014-09-08T03:52:05+00:00\",\"dateModified\":\"2025-05-15T15:26:29+00:00\",\"description\":\"In this comprehensive tutorial, learn how to set up automated deployment workflows with GitHub Actions, streamlining your development process.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#primaryimage\",\"url\":\"https:\\\/\\\/codesamplez.com\\\/wp-content\\\/uploads\\\/2014\\\/09\\\/github-actions-tutorial.webp\",\"contentUrl\":\"https:\\\/\\\/codesamplez.com\\\/wp-content\\\/uploads\\\/2014\\\/09\\\/github-actions-tutorial.webp\",\"width\":1536,\"height\":1024,\"caption\":\"Github Actions Tutorial\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/devops\\\/github-actions-tutorial#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/codesamplez.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"GitHub Actions Tutorial: Automating Your Deployment Workflow\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#website\",\"url\":\"https:\\\/\\\/codesamplez.com\\\/\",\"name\":\"CODESAMPLEZ.COM\",\"description\":\"Programming And Development Resources\",\"publisher\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/codesamplez.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#organization\",\"name\":\"codesamplez.com\",\"url\":\"https:\\\/\\\/codesamplez.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/codesamplez.com\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/cropped-favicon.webp\",\"contentUrl\":\"https:\\\/\\\/codesamplez.com\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/cropped-favicon.webp\",\"width\":512,\"height\":512,\"caption\":\"codesamplez.com\"},\"image\":{\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/codesamplez\",\"https:\\\/\\\/x.com\\\/codesamplez\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/codesamplez.com\\\/#\\\/schema\\\/person\\\/a82c3c07205f4bb73d6b3b0906bc328b\",\"name\":\"Rana Ahsan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c7a4f88bcf4a55cd1483386318ebecf27359154275a0b355b0ea186676f9f7f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c7a4f88bcf4a55cd1483386318ebecf27359154275a0b355b0ea186676f9f7f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c7a4f88bcf4a55cd1483386318ebecf27359154275a0b355b0ea186676f9f7f?s=96&d=mm&r=g\",\"caption\":\"Rana Ahsan\"},\"description\":\"Rana Ahsan is a seasoned software engineer and technology leader specialized in distributed systems and software architecture. With a Master\u2019s in Software Engineering from Concordia University, his experience spans leading scalable architecture at Coursera and TopHat, contributing to open-source projects. This blog, CodeSamplez.com, showcases his passion for sharing practical insights on programming and distributed systems concepts and help educate others. Github | X | LinkedIn\",\"sameAs\":[\"https:\\\/\\\/github.com\\\/ranacseruet\",\"https:\\\/\\\/www.facebook.com\\\/ranacseruet\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/ranacseruet\\\/\",\"https:\\\/\\\/x.com\\\/ranacseruet\"],\"url\":\"https:\\\/\\\/codesamplez.com\\\/author\\\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"GitHub Actions Tutorial: Automating Your Deployment Workflow - CodeSamplez.com","description":"In this comprehensive tutorial, learn how to set up automated deployment workflows with GitHub Actions, streamlining your development process.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial","og_locale":"en_US","og_type":"article","og_title":"GitHub Actions Tutorial: Automating Your Deployment Workflow","og_description":"In this comprehensive tutorial, learn how to set up automated deployment workflows with GitHub Actions, streamlining your development process.","og_url":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial","og_site_name":"CodeSamplez.com","article_publisher":"https:\/\/www.facebook.com\/codesamplez","article_author":"https:\/\/www.facebook.com\/ranacseruet","article_published_time":"2014-09-08T03:52:05+00:00","article_modified_time":"2025-05-15T15:26:29+00:00","og_image":[{"width":1536,"height":1024,"url":"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp","type":"image\/webp"}],"author":"Rana Ahsan","twitter_card":"summary_large_image","twitter_creator":"@ranacseruet","twitter_site":"@codesamplez","twitter_misc":{"Written by":"Rana Ahsan","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#article","isPartOf":{"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial"},"author":{"name":"Rana Ahsan","@id":"https:\/\/codesamplez.com\/#\/schema\/person\/a82c3c07205f4bb73d6b3b0906bc328b"},"headline":"GitHub Actions Tutorial: Automating Your Deployment Workflow","datePublished":"2014-09-08T03:52:05+00:00","dateModified":"2025-05-15T15:26:29+00:00","mainEntityOfPage":{"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial"},"wordCount":1170,"commentCount":0,"publisher":{"@id":"https:\/\/codesamplez.com\/#organization"},"image":{"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#primaryimage"},"thumbnailUrl":"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp","keywords":["deployment","git","github"],"articleSection":["DevOps"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/codesamplez.com\/devops\/github-actions-tutorial#respond"]}]},{"@type":"WebPage","@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial","url":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial","name":"GitHub Actions Tutorial: Automating Your Deployment Workflow - CodeSamplez.com","isPartOf":{"@id":"https:\/\/codesamplez.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#primaryimage"},"image":{"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#primaryimage"},"thumbnailUrl":"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp","datePublished":"2014-09-08T03:52:05+00:00","dateModified":"2025-05-15T15:26:29+00:00","description":"In this comprehensive tutorial, learn how to set up automated deployment workflows with GitHub Actions, streamlining your development process.","breadcrumb":{"@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/codesamplez.com\/devops\/github-actions-tutorial"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#primaryimage","url":"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp","contentUrl":"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp","width":1536,"height":1024,"caption":"Github Actions Tutorial"},{"@type":"BreadcrumbList","@id":"https:\/\/codesamplez.com\/devops\/github-actions-tutorial#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/codesamplez.com\/"},{"@type":"ListItem","position":2,"name":"GitHub Actions Tutorial: Automating Your Deployment Workflow"}]},{"@type":"WebSite","@id":"https:\/\/codesamplez.com\/#website","url":"https:\/\/codesamplez.com\/","name":"CODESAMPLEZ.COM","description":"Programming And Development Resources","publisher":{"@id":"https:\/\/codesamplez.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/codesamplez.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/codesamplez.com\/#organization","name":"codesamplez.com","url":"https:\/\/codesamplez.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codesamplez.com\/#\/schema\/logo\/image\/","url":"https:\/\/codesamplez.com\/wp-content\/uploads\/2024\/10\/cropped-favicon.webp","contentUrl":"https:\/\/codesamplez.com\/wp-content\/uploads\/2024\/10\/cropped-favicon.webp","width":512,"height":512,"caption":"codesamplez.com"},"image":{"@id":"https:\/\/codesamplez.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/codesamplez","https:\/\/x.com\/codesamplez"]},{"@type":"Person","@id":"https:\/\/codesamplez.com\/#\/schema\/person\/a82c3c07205f4bb73d6b3b0906bc328b","name":"Rana Ahsan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5c7a4f88bcf4a55cd1483386318ebecf27359154275a0b355b0ea186676f9f7f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5c7a4f88bcf4a55cd1483386318ebecf27359154275a0b355b0ea186676f9f7f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5c7a4f88bcf4a55cd1483386318ebecf27359154275a0b355b0ea186676f9f7f?s=96&d=mm&r=g","caption":"Rana Ahsan"},"description":"Rana Ahsan is a seasoned software engineer and technology leader specialized in distributed systems and software architecture. With a Master\u2019s in Software Engineering from Concordia University, his experience spans leading scalable architecture at Coursera and TopHat, contributing to open-source projects. This blog, CodeSamplez.com, showcases his passion for sharing practical insights on programming and distributed systems concepts and help educate others. Github | X | LinkedIn","sameAs":["https:\/\/github.com\/ranacseruet","https:\/\/www.facebook.com\/ranacseruet","https:\/\/www.linkedin.com\/in\/ranacseruet\/","https:\/\/x.com\/ranacseruet"],"url":"https:\/\/codesamplez.com\/author\/admin"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/codesamplez.com\/wp-content\/uploads\/2014\/09\/github-actions-tutorial.webp","jetpack_shortlink":"https:\/\/wp.me\/p1hHlI-6pb","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":58380,"url":"https:\/\/codesamplez.com\/devops\/aws-sam-beginners-guide","url_meta":{"origin":24625,"position":0},"title":"AWS SAM: Build And Deploy Lambda Effortlessly","author":"Rana Ahsan","date":"April 21, 2025","format":false,"excerpt":"Kick\u2011start your serverless journey with this hands\u2011on AWS\u00a0SAM Tutorial. Learn why SAM matters, scaffold your first Lambda in minutes, test locally with Docker, and automate deployments using GitHub\u00a0Actions. Packed with code samples, real\u2011world tips, and troubleshooting hacks from a veteran dev, this guide turns beginners into confident builders.","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/codesamplez.com\/category\/devops"},"img":{"alt_text":"AWS SAM Tutorial For Beginners","src":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/04\/aws-sam.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/04\/aws-sam.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/04\/aws-sam.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/04\/aws-sam.webp?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/04\/aws-sam.webp?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/04\/aws-sam.webp?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":58136,"url":"https:\/\/codesamplez.com\/devops\/deploy-static-website-aws-s3-cloudfront","url_meta":{"origin":24625,"position":1},"title":"Host Static Website With AWS S3 And CloudFront &#8211; Step By Step","author":"Rana Ahsan","date":"March 7, 2025","format":false,"excerpt":"Hosting your front-end with AWS S3 and CloudFront changes everything. I\u2019m talking near-zero downtime, unstoppable performance, and total simplicity. Let me share my personal journey\u2014triumphs, embarrassing mistakes, and practical tips\u2014to ensure your website soars at lightning speed, while staying rock-solid, no matter what. Ready? Let\u2019s go get unstoppable right now!","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/codesamplez.com\/category\/devops"},"img":{"alt_text":"static website deployment s3 cloudfront","src":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/03\/static-website-deployment-s3-cloudfront.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/03\/static-website-deployment-s3-cloudfront.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/03\/static-website-deployment-s3-cloudfront.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/03\/static-website-deployment-s3-cloudfront.webp?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/03\/static-website-deployment-s3-cloudfront.webp?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2025\/03\/static-website-deployment-s3-cloudfront.webp?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":59809,"url":"https:\/\/codesamplez.com\/devops\/visual-regression-testing-github-actions","url_meta":{"origin":24625,"position":2},"title":"SnapDrift: Free Auto Visual Regression Testing On GitHub Actions","author":"Rana Ahsan","date":"March 19, 2026","format":false,"excerpt":"SnapDrift is a free, open-source visual regression testing tool built for GitHub Actions. It captures full-page screenshots on every push, compares them pixel-by-pixel against your baseline, and reports drift directly in your pull requests. No SaaS dashboards, no per-screenshot pricing \u2014 just two Actions and a JSON config.","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/codesamplez.com\/category\/devops"},"img":{"alt_text":"visual diff github","src":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2026\/03\/snapdrift-logo-banner.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2026\/03\/snapdrift-logo-banner.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2026\/03\/snapdrift-logo-banner.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2026\/03\/snapdrift-logo-banner.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2026\/03\/snapdrift-logo-banner.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":24647,"url":"https:\/\/codesamplez.com\/devops\/build-php-web-application-makefile","url_meta":{"origin":24625,"position":3},"title":"Building and Deploying PHP Web Applications with Makefiles","author":"Rana Ahsan","date":"August 17, 2014","format":false,"excerpt":"Discover how to enhance your PHP web development process using Makefiles. This guide walks you through automating repetitive tasks, organizing workflows, and improving project efficiency. Learn to streamline builds, manage dependencies, and simplify deployment, making your development process more robust and maintainable with Makefiles. Perfect for developers seeking productivity boosts!","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/codesamplez.com\/category\/devops"},"img":{"alt_text":"PHP Makefile","src":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2014\/08\/php-makefile.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2014\/08\/php-makefile.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2014\/08\/php-makefile.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2014\/08\/php-makefile.webp?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2014\/08\/php-makefile.webp?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2014\/08\/php-makefile.webp?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":22380,"url":"https:\/\/codesamplez.com\/devops\/aws-learning-roadmap","url_meta":{"origin":24625,"position":4},"title":"AWS Learning Roadmap: Ultimate Guide","author":"Rana Ahsan","date":"February 27, 2025","format":false,"excerpt":"Ready to master AWS? This AWS Learning Roadmap guides DevOps Engineers through essentials like EC2, IAM, and CloudWatch. From launching your first instance to automating deployments, I\u2019ll break it down with practical tips\u2014your friendly path to cloud expertise starts here!","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/codesamplez.com\/category\/devops"},"img":{"alt_text":"AWS Learning RoadMap","src":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2012\/12\/AWS-Learning-RoadMap.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2012\/12\/AWS-Learning-RoadMap.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2012\/12\/AWS-Learning-RoadMap.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2012\/12\/AWS-Learning-RoadMap.webp?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2012\/12\/AWS-Learning-RoadMap.webp?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2012\/12\/AWS-Learning-RoadMap.webp?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":57545,"url":"https:\/\/codesamplez.com\/devops\/aws-codedeploy-for-beginners","url_meta":{"origin":24625,"position":5},"title":"AWS CodeDeploy: Simplifying Application Deployments","author":"Rana Ahsan","date":"December 5, 2024","format":false,"excerpt":"AWS CodeDeploy is a managed service that simplifies application deployment across various platforms like EC2, on-premises servers, and AWS Lambda. It automates updates, ensures consistent processes to reduce errors, and allows easy rollbacks. The guide provides a step-by-step tutorial on using CodeDeploy, troubleshooting tips, and highlights its benefits for efficient\u2026","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/codesamplez.com\/category\/devops"},"img":{"alt_text":"AWS CodeDeploy","src":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2024\/12\/AWS-CodeDeploy.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2024\/12\/AWS-CodeDeploy.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2024\/12\/AWS-CodeDeploy.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/codesamplez.com\/wp-content\/uploads\/2024\/12\/AWS-CodeDeploy.webp?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/posts\/24625","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/comments?post=24625"}],"version-history":[{"count":3,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/posts\/24625\/revisions"}],"predecessor-version":[{"id":58660,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/posts\/24625\/revisions\/58660"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/media\/58659"}],"wp:attachment":[{"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/media?parent=24625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/categories?post=24625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codesamplez.com\/wp-json\/wp\/v2\/tags?post=24625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}