{"id":23895387,"url":"https://github.com/kelomo2502/advance-githubactions-best-practices","last_synced_at":"2026-04-07T08:01:34.296Z","repository":{"id":268751847,"uuid":"905267971","full_name":"kelomo2502/Advance-GithubACtions-Best-Practices","owner":"kelomo2502","description":"This is a sophisticated aspects of GitHub Actions, learning how to craft maintainable workflows, optimize performance, and prioritize security automation processes.","archived":false,"fork":false,"pushed_at":"2025-04-25T07:15:45.000Z","size":158,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-25T07:42:15.672Z","etag":null,"topics":["aws-ec2","bash","docker","jest","nodejs","supertest","yaml"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kelomo2502.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-18T13:41:02.000Z","updated_at":"2025-04-25T07:15:48.000Z","dependencies_parsed_at":"2024-12-18T18:19:52.189Z","dependency_job_id":"e6ad0ef3-a981-48b1-8e8e-fa3255b64f35","html_url":"https://github.com/kelomo2502/Advance-GithubACtions-Best-Practices","commit_stats":null,"previous_names":["kelomo2502/advance-githubactions-best-practices"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/kelomo2502/Advance-GithubACtions-Best-Practices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelomo2502%2FAdvance-GithubACtions-Best-Practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelomo2502%2FAdvance-GithubACtions-Best-Practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelomo2502%2FAdvance-GithubACtions-Best-Practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelomo2502%2FAdvance-GithubACtions-Best-Practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kelomo2502","download_url":"https://codeload.github.com/kelomo2502/Advance-GithubACtions-Best-Practices/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelomo2502%2FAdvance-GithubACtions-Best-Practices/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31504897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-ec2","bash","docker","jest","nodejs","supertest","yaml"],"created_at":"2025-01-04T15:55:40.526Z","updated_at":"2026-04-07T08:01:34.281Z","avatar_url":"https://github.com/kelomo2502.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Advance-GithubACtions-Best-Practices This project leverages GitHub Actions for CI/CD automation. Below is an overview of each GitHub Actions workflow.\r\n\r\nBuild Pipeline The build.yaml workflow is triggered on push or pull request to the main branch. It does the following:\r\n\r\nCheckout the Code: Pulls the latest code from the repository.\r\n\r\nSet up Node.js: Configures Node.js version 20.8.1.\r\n\r\nInstall Dependencies: Installs all the necessary dependencies using npm install.\r\n\r\nBuild the Application: Builds the application using npm run build.\r\n\r\nname: Build\r\n\r\non:\r\n  push:\r\n    branches:\r\n      - main\r\n  pull_request:\r\n    branches:\r\n      - main\r\n\r\njobs:\r\n  build:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      - name: Checkout code\r\n        uses: actions/checkout@v3\r\n\r\n      - name: Set up Node.js\r\n        uses: actions/setup-node@v3\r\n        with:\r\n          node-version: '20.8.1'\r\n\r\n      - name: Install dependencies\r\n        run: npm install\r\n\r\n      - name: Build the application\r\n        run: npm run build\r\n\r\nDockerize Pipeline The dockerize.yaml workflow is triggered when the build pipeline completes. It builds the Docker image and pushes it to Docker Hub:\r\n\r\nLog in to Docker Hub: Authenticates using Docker credentials stored as GitHub secrets.\r\n\r\nBuild and Tag the Docker Image: Builds the Docker image using the Dockerfile, tags it with the latest version, and pushes it to Docker Hub.\r\n\r\nLog out from Docker Hub: Logs out of Docker Hub to maintain security.\r\n\r\nyaml Copy Edit\r\n\r\nname: Dockerize\r\n\r\non:\r\n  workflow_run:\r\n    workflows: [\"Build\"]\r\n    types:\r\n      - completed\r\n\r\njobs:\r\n  dockerize:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      - name: Checkout code\r\n        uses: actions/checkout@v3\r\n\r\n      - name: Log in to Docker Hub\r\n        uses: docker/login-action@v2\r\n        with:\r\n          username: ${{ secrets.DOCKER_USERNAME }}\r\n          password: ${{ secrets.DOCKER_PASSWORD }}\r\n\r\n      - name: Build and push Docker image\r\n        run: |\r\n          docker build -t my-test-node-app .\r\n          docker tag my-test-node-app:latest ${{ secrets.DOCKER_USERNAME }}/my-test-node-app:latest\r\n          docker push ${{ secrets.DOCKER_USERNAME }}/my-test-node-app:latest\r\n\r\n      - name: Log out from Docker Hub\r\n        run: docker logout\r\n\r\nTest Pipeline The test.yaml workflow runs the unit tests after the build pipeline completes. It does the following:\r\n\r\nSet up Node.js: Configures the required Node.js version.\r\n\r\nInstall Dependencies: Installs dependencies using npm install.\r\n\r\nRun Jest Tests: Runs the tests with npm test to ensure that the application works as expected.\r\n\r\nname: Run Tests\r\n\r\non:\r\n  workflow_run:\r\n    workflows: [\"Build\"]\r\n    types:\r\n      - completed\r\n\r\njobs:\r\n  test:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      - name: Checkout code\r\n        uses: actions/checkout@v3\r\n\r\n      - name: Set up Node.js\r\n        uses: actions/setup-node@v3\r\n        with:\r\n          node-version: '20.8.1'\r\n\r\n      - name: Install dependencies\r\n        run: npm install\r\n\r\n      - name: Run Jest tests\r\n        run: npm test\r\n\r\nDeploy Pipeline The deploy.yaml workflow is triggered after the Dockerize pipeline completes. It deploys the app to an EC2 instance:\r\n\r\nConfigure SSH: Sets up SSH using the private key stored in GitHub secrets.\r\n\r\nDeploy the Dockerized App: Pulls the latest image from Docker Hub and runs the app on EC2.\r\n\r\nClean up: Stops and removes any dangling Docker containers.\r\n\r\nyaml Copy Edit\r\n\r\nname: Deploy\r\n\r\non:\r\n  workflow_run:\r\n    workflows: [\"Dockerize\"]\r\n    types:\r\n      - completed\r\n\r\njobs:\r\n  deploy:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      - name: Checkout code\r\n        uses: actions/checkout@v3\r\n\r\n      - name: Configure SSH for EC2\r\n        run: |\r\n          echo \"${{ secrets.EC2_KEY }}\" \u003e ec2_key.pem\r\n          chmod 600 ec2_key.pem\r\n\r\n      - name: Deploy to EC2\r\n        run: |\r\n          ssh -o StrictHostKeyChecking=no -i ec2_key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_PUBLIC_IP }} \u003c\u003c 'EOF'\r\n          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}\r\n          docker pull ${{ secrets.DOCKER_USERNAME }}/my-test-node-app:latest\r\n          docker stop my-test-node-app || true\r\n          docker rm my-test-node-app || true\r\n          docker rmi $(docker images -f \"dangling=true\" -q) || true\r\n          docker run -d --name my-test-node-app -p 3000:3000 ${{ secrets.DOCKER_USERNAME }}/my-test-node-app:latest\r\n          docker system prune -af || true\r\n          EOF\r\n\r\n      - name: Cleanup local SSH key\r\n        run: rm ec2_key.pem\r\n\r\nRelease Pipeline The release.yaml workflow is triggered when a tag is pushed to the repository. It creates a GitHub release based on the tag:\r\n\r\nCheckout the Code: Retrieves the code associated with the tag.\r\n\r\nCreate a GitHub Release: Uses the actions/create-release action to generate a new release.\r\n\r\nyaml Copy Edit\r\n\r\nname: Create release\r\n\r\non:\r\n  push:\r\n    tags:\r\n      - '*'  # Trigger the workflow for all tag pushes\r\n\r\njobs:\r\n  build:\r\n    name: Create Release\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      - name: Checkout code\r\n        uses: actions/checkout@v2\r\n    \r\n      - name: Create Release\r\n        id: create_release\r\n        uses: actions/create-release@v1\r\n        env:\r\n          GITHUB_TOKEN: ${{ secrets.VERSION_TOKEN }}\r\n        with:\r\n          tag_name: ${{ github.ref }}\r\n          release_name: Release ${{ github.ref }}\r\n          body: |\r\n            This is an automated release based on tag ${{ github.ref }}\r\n          draft: false\r\n          prerelease: false\r\n\r\nApp Description This Node.js app is a simple Express server with two routes:\r\n\r\nGET /: Returns a welcome message.\r\n\r\nGET /status: Returns a status JSON object.\r\n\r\nServer Code (server.js)\r\n\r\nconst express = require('express');\r\nconst app = express();\r\n\r\napp.get('/', (req, res) =\u003e {\r\n  res.send('Welcome to the Node.js Server!');\r\n});\r\n\r\napp.get('/status', (req, res) =\u003e {\r\n  res.json({ status: 'OK' });\r\n});\r\n\r\nif (require.main === module) {\r\n  app.listen(3000, () =\u003e {\r\n    console.log('Server is running on port 3000');\r\n  });\r\n}\r\n\r\nmodule.exports = app;\r\n\r\nFROM node:18-alpine\r\n\r\nWORKDIR /usr/src/app\r\n\r\nCOPY package*.json ./\r\n\r\nRUN npm install\r\n\r\nCOPY . .\r\n\r\nEXPOSE 3000\r\n\r\nCMD [\"npm\", \"start\"]\r\n\r\nTesting Unit tests are written using Jest and Supertest to test the server's routes.\r\n\r\nconst request = require('supertest');\r\nconst app = require('../server');\r\nlet server;\r\n\r\nbeforeAll(() =\u003e {\r\n  server = app.listen(3000);\r\n});\r\n\r\nafterAll((done) =\u003e {\r\n  server.close(done);\r\n});\r\n\r\ndescribe('Node.js Server', () =\u003e {\r\n  it('should return a welcome message from the root route', async () =\u003e {\r\n    const response = await request(app).get('/');\r\n    expect(response.text).toBe('Welcome to the Node.js Server!');\r\n  });\r\n\r\n  it('should return a status JSON object from the /status route', async () =\u003e {\r\n    const response = await request(app).get('/status');\r\n    expect(response.body.status).toBe('OK');\r\n  });\r\n});\r\n\r\nDeployment The app is deployed to an EC2 instance using Docker. After the Docker image is built and pushed to Docker Hub, it is pulled on the EC2 instance and run in a Docker container.\r\n\r\nTo manually deploy the app on your EC2 instance:\r\n\r\ndocker run -d -p 3000:3000 \u003cyour-dockerhub-username\u003e/my-test-node-app:latest\r\n\r\nLicense This project is licensed under the MIT License.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelomo2502%2Fadvance-githubactions-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkelomo2502%2Fadvance-githubactions-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelomo2502%2Fadvance-githubactions-best-practices/lists"}