Skip to content

Commit

Permalink
started github actions
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveSayantan committed Jan 14, 2025
1 parent 913fab9 commit b0dfde8
Show file tree
Hide file tree
Showing 64 changed files with 7,249 additions and 22 deletions.
28 changes: 28 additions & 0 deletions .github/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## GitHub Actions
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows us to automate your build, test, and deployment pipeline. We can create workflows that build and test every pull request to our repository, or deploy merged pull requests to production.

GitHub Actions goes beyond just DevOps and lets us run workflows when other events happen in our repository. For example, we can run a workflow to automatically add the appropriate labels whenever someone creates a new issue in our repository.
#### Resources
- [Docs](https://docs.github.com/en/actions/about-github-actions/understanding-github-actions)
- [Mickey Goussel YT](https://youtube.com/playlist?list=PLiO7XHcmTsleVSRaY7doSfZryYWMkMOxB&si=kT7crVPw3xdNlznG)

#### Overview
- **Workflow** - A workflow is a configurable automated process made up of one or more jobs. Workflows are defined in `.yml` files in the `.github/workflows` directory of your repository.

- **Jobs** - A job is a set of steps that execute on the same _runner_. Runner is a server that has the GitHub Actions runner application installed. Jobs can run sequentially or in parallel.

- **Steps** - A step is an individual task that can run commands or actions e.g. `actions/checkout@v2`. Each step in a job executes on the same runner, allowing for direct file sharing.

> Summary: The workflow is a set of jobs and each job is a set of steps. Each step can be an action or a shell command.
- **Event** - An event is a specific activity that triggers a workflow. For example, activity that occurs on GitHub, such as opening a pull request or pushing a commit.

- **Action** - An action is a reusable unit of code. You can use an action defined in the same repository as the workflow, a public repository, or in a published Docker container image. See these examples [here](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsuses)


For detailed syntax, checkout [workflow-syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#about-yaml-syntax-for-workflows)





19 changes: 19 additions & 0 deletions .github/workflows/basic-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: CI # name of the workflow

on: workflow_dispatch # to trigger the workflow manually (with a button), we use this event. This event will only trigger a workflow run if the workflow file exists on the default branch.

jobs: # This workflow contains a single job called "build"

build: # name of the job

runs-on: ubuntu-latest # runs-on is the type of machine to run the job on - runner

steps: # steps are the individual tasks that make up a job

# selecting an action to run as part of a step in a job
- uses: actions/checkout@v4 # 'actions' is a public repo containing useful GitHub actions, 'checkout' is the action that checks-out repository so the workflow can access it, 'v4' indicates the 4th major release of it.

- name: Wohoooo # the name of the step, if not specified, he step name will default to the text specified in the run command

# Runs command-line programs. Each run keyword represents a new process and shell in the runner environment. When you provide multi-line commands, each line runs in the same shell.
run: echo Hello, world!
10 changes: 6 additions & 4 deletions ansible/passwordless-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ Suppose, we have two servers, namely *host1* and *host2* . We should be able to

In *host1*,
- run `ssh-keygen` .
- Keep pressing **enter** to accept all the default options.
- Keep pressing **enter** to accept all the default options.
- Now, a bunch of files are created at `/home/user/.ssh` (default location).

```bash
ls /home/ubuntu/.ssh
>> authorized_keys id_rsa id_rsa.pub known_hosts
```

- *id_isa* is private key which is used to login to machine. Never share this with anyone.
- *id_isa.pub* is public key which is used for communication with others.
- *id_rsa* is private key which is used to login to machine. Never share this with anyone.
- *id_rsa.pub* is public key which is used for communication with others.

In *host2*,

Expand All @@ -32,4 +32,6 @@ In *host2*,
ssh-ed23uoirut...
```

Now, in *host1*, we can simply run `ssh <host2_IP>` to connect to *host2* . To disconnect, use **logout** command.
Now, in *host1*, we can simply run `ssh <host2_IP>` to connect to *host2* . To disconnect, use **logout** command.

A documentation on how to use SSH public key authentication on Linux, click [here](https://www.linode.com/docs/guides/use-public-key-authentication-with-ssh/?tabs=ed25519-recommended%2Cssh-add%2Cusing-ssh-copy-id-recommended)
Binary file added assets/adding_shared-lib.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/bridge2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/github-webhook.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/jenkins-assign_roles.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/jenkins-manage_roles.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/jenkins-scm-pipeline.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
130 changes: 130 additions & 0 deletions cicd-basics/add-linux-node.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
## Steps to add a Linux node (Slave) to Jenkins
- Create an ec2 instance.

- Jenkins connects to the slave via ssh. So, we need to generate a key-pair using `ssh-keygen` in the master.
- Also, we need to add the generated **public-key** to the slave node in **authorized_keys** file.

- Install Java in the slave. Check out the Jenkins installation docs for the commands.

- Now, in the master,
- Go to `Manage Jenkins > Nodes`. Click on **New Node** button.

- Provide a name and select the **Permanent Agent** radio button, click **Create**.

- Provide an optional **Description**.

- Leave the **Number of executors** as 1 (default).

- Provide the **Remote root directory** as `/home/ubuntu/jenkins-test` . As the name suggests, Jenkins uses this directory as its root in the slave node. If the provided directory is not present in the agent, it will be created.
- Inside this, folders like `jobs/`, `workspace/` etc. will be present.

- Provide a name in **Labels**. It will be used by the master to identify this slave.

- Keep **Usage** to **Use this node as much as possible** (default).

- In the **Launch method**, select **Launch agents via SSH**

- Provide the public IP of the slave in **Host**.

- Click on `Add` button under **Credentials**, and select **Jenkins**.

- In the modal, select **SSH Username with private key** from the dropdown of **Kind** .

- Leave the **Scope** to its default value. Provide a name in the **ID** and an optional description in **Description**.

- In the **Username**, add the username of the slave instance (e.g. ubuntu). Leave the **Treat username as secret** checkbox as empty.

- Click on the **Enter directly** radio button and paste the **private-key** generated initially. Add **Passphrase** (if any).

- Click on **Add**.

- Now, select the added key from **Credentials** dropdown. Also, select **Non verifying Verification Strategy** from the dropdown of **Host Key Verification Strategy**.

Check if the connection is working properly.

## Example: Declarative Pipeline
```groovy
pipeline {
agent {label 'agent-demo'} // this has to be the same as provided in 'Labels' box above
stages { // each stage will be executed in the agent
stage('first') {
steps {
sh 'echo "Hello World" > test.txt' // this file will be created at `workspace/{JOBNAME}/` folder which is inside the specified Remote root directory.
}
}
}
}
```

## Example: Declarative Pipeline with credentials
```groovy
pipeline {
agent {label 'agent-demo'}
stages {
stage('show how to use credentials') {
steps {
withCredentials([usernamePassword(credentialsId: 'fake-docker-passwd', passwordVariable: 'PASSWD', usernameVariable: 'USERNAME')]) { // this is generated by Pipeline Syntax Snippet Generator. Here we store the password and username in PASSWD and USERNAME variables for future usage.
sh 'echo username is $USERNAME, password is $PASSWD' // always use single quotes or triple-single quote here to prevent Groovy interpolate the secrets.
// using triple-single quotes
sh '''
echo username is $USERNAME
echo password is $PASSWD
'''
}
}
}
}
}
```
## Example: Declarative Pipeline - Cloning from GitHub
```groovy
pipeline {
agent {label 'agent-demo'}
stages {
stage('show how to clone from GitHub') {
steps {
// the following line will clone the repo from GitHub to `workspace/{JOBNAME}/` folder
//(For private repo, we need to set the credentials first)
git branch: 'master', credentialsId: 'test-github', url: 'https://github.com/SteveSayantan/Web_BootCamp.git' // this is generated by Pipeline Syntax Snippet Generator
sh 'echo cloning successful'
// or, if the repo is public, we can also do it simply as:
sh 'git clone https://github.com/xyz'
}
}
}
}
```

## How to Trigger Pipeline using GitHub Webhook

In Jenkins configuration of the corresponding pipeline, make sure the **Definition** of the pipeline says **Pipeline script from SCM** i.e. it fetches Jenkinsfile from a remote repo. Also, check the **GitHub hook trigger for GITScm polling** box under **Build Triggers**.

In GitHub,
- Go to **Webhooks** under the **Settings** tab of the corresponding repository.
- Click on **Add webhook**
- In **Payload URL**, write `http://<IP_of_jenkins_master>:8080/github-webhook/`. GitHub will hit this endpoint to trigger the pipeline.
- Disable the **SSL verification** if working with http.
- Choose the type of event which would run this webhook, as per requirement.
- Click on **Add webhook** .
- Check the **Recent Deliveries** section in the webhook configuration to verify if the connection was successful.
- Example:
![example_webhook](../assets/github-webhook.JPG)
29 changes: 26 additions & 3 deletions cicd-basics/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,29 @@
- Reports: Stats about test coverage, code quality checks etc.
- Deployment

CI/CD helps automate all these steps. Otherwise, performing all these steps for every change in the code will take very long and thereby delaying the delivery.
CI/CD helps automate all these steps. Otherwise, performing all these steps manually for every change in the code will take very long and thereby delaying the delivery.

- Jenkins Pipeline: Suppose, some changes are pushed to our Github. We shall set up Jenkins such that for any PR/commit on the repo it will run a set of actions automatically with the help of multiple tools. Hence Jenkins is called an orchestrator.
### Differences between Continuous Integration, Continuous Delivery and Continuous Deployment

1. **Continuous Integration (CI)**:
- **Purpose**: CI focuses on **automating the integration** of code changes from multiple developers into a single project. The goal is to frequently integrate code (several times a day) and **run automated tests** to detect issues early.
- **Example**: Imagine a team of developers working on a JavaScript application. Each developer pushes their code changes to a shared repository on GitHub. With CI configured (using tools like Jenkins or GitLab CI), every code push triggers a **build** and a set of **unit tests**. If any test fails, the team is notified immediately to fix it, ensuring that the main branch remains stable and bug-free.

1. **Continuous Delivery (CD)**:
- **Purpose**: Continuous Delivery automates the process of preparing code for release but requires a **manual approval step** before production deployment. This stage ensures that the codebase is always in a deployable state, even if the actual deployment is not automated.
- **Example**: In the same JavaScript application, the CI pipeline automatically runs integration tests and builds the application. In a CD setup, this pipeline also deploys the tested application to a **staging environment**. Once tested and approved by the QA team, a manager can trigger a **manual deployment to production**. This approach provides a higher level of control over what goes into production.

1. **Continuous Deployment (CD)**:
- **Purpose**: Continuous Deployment takes Continuous Delivery a step further by **automating the entire process**, including deployment to production. Each successful change that passes all tests is deployed automatically without manual intervention, enabling rapid delivery of updates.
- **Example**: For a high-frequency application like a social media platform, the development team may practice continuous deployment. Each change pushed to the repository, once it passes all tests (unit, integration, and end-to-end tests), is **automatically deployed to production**. This allows users to see new features, improvements, or fixes almost immediately after they’re completed by developers.

##### **Key Differences**:
- **Continuous Integration**: Focuses on code integration and testing automation.
- **Continuous Delivery**: Adds automation up to the staging environment, with a manual step for production.
- **Continuous Deployment**: Automates everything, including deployment to production, without manual steps.

### Jenkins Pipeline
Suppose, some changes are pushed to our Github. We shall set up Jenkins such that for any PR/commit on the repo it will run a set of actions automatically with the help of multiple tools. Hence Jenkins is called an orchestrator.

- e.g. for a Java application, Jenkin can be configured to run Maven for building, Junit for testing, ALM for reporting etc. whenever there is a PR/commit on our repo.

Expand All @@ -27,7 +47,7 @@ CI/CD helps automate all these steps. Otherwise, performing all these steps for

- Disadvantages of Jenkins

- While working with Jenkins, generally, we do not put all the load in a single machine. Instead, we create a master node, and connect several ec2 instances to it. Now using the master node, we configure those as worker nodes and schedule them to execute the pipelines.
- While working with Jenkins, generally, we do not put all the load in a single machine (as it may cause dependency conflicts and not practical). Instead, we create a master node, and connect several ec2 instances to it. Now using the master node, we configure those as worker nodes and schedule them to execute the pipelines/builds.

- But this setup is not scalable as the setup becomes very costly as well as less maintainable.

Expand All @@ -37,4 +57,7 @@ CI/CD helps automate all these steps. Otherwise, performing all these steps for

For every PR, GitHub Actions will spin up a docker container in a remote server for us and everything is executed in it. When there is no change in the code, the container will be deleted and server will be used for some other project in another repo. As a result, there will be no wastage of resources.

### References
- [TrainWithShubham](https://youtu.be/XaSdKR2fOU4?si=awS9KPt3gys0P8TM)

- [Abhishek Veeramalla](https://youtube.com/playlist?list=PLdpzxOOAlwvLUH6ww022l7OZGakJYP9WY&si=KUAtAdWDxiEX-Ewf)
107 changes: 107 additions & 0 deletions cicd-basics/first-jenkins-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## Jenkins Pipeline
There are multiple ways to create a pipeline in Jenkins e.g., **Freestyle project**, **Pipeline**, **Multi-configuration project** etc.

Jenkins freestyle projects are the traditional method of configuring jobs in Jenkins, where most configurations are done through the GUI (without the need to write any code)by setting parameters, build triggers, and post-build actions. While Jenkins freestyle projects are simple and quick to set up, they come with certain limitations, sucn as:

- Job configurations in freestyle projects are stored in Jenkins itself, making it hard to track changes or collaborate on job configurations.

- We need to duplicate configurations across multiple jobs for similar workflows, which is error-prone and time-consuming, i.e. lack of reusability.

- Freestyle jobs struggle to handle complex workflows, especially those with multiple stages or conditional steps.

To overcome these issues, Pipeline approach is used. It is a declarative in nature and uses Groovy scripting. A `Jenkinsfile` contains the configuration of Jenkins Pipeline. We shall focus on the Declarative syntax of writing a Jenkinsfile.

### Default Storage Locations

Every time we create a new job (i.e. a pipeline or freestyle project etc.) in Jenkins, a new folder is created at `/var/lib/jenkins/jobs/`.

- Whenever a job is executed, a new build is created. Each job stores its related build-data in the directory `/var/lib/jenkins/jobs/{JOBNAME}`

Each job folder contains:

- The job configuration file is `/var/lib/jenkins/jobs/{JOBNAME}/config.xml`

- The job builds are stored in `/var/lib/jenkins/jobs/{JOBNAME}/builds/`

However, the files related to our project (e.g. source code pulled from SCM) is stored at `/var/lib/jenkins/workspace/{JOBNAME}/` by default.

### Declarative Pipeline fundamentals
This is the basic structure of a Jenkinsfile:
```groovy
pipeline { //block defines all the work done throughout your entire Pipeline.
//The agent directive, which is required, instructs Jenkins to allocate an executor and workspace for the Pipeline.
agent any // Execute this Pipeline or any of its stages, on any available agent. Since no external agent is specified, jenkins uses its built-in agent or the same machine where the Jenkins controller is running to execute the jobs
stages {
stage('Build') { // Defines the "Build" stage
steps {
//Perform some steps related to the "Build" stage.
}
}
stage('Test') {
steps {
//
}
}
stage('Deploy') {
steps {
//
}
}
}
}
```
We can also refer to the pipeline-syntax generator at `http://<current_IP_of_ec2>:8080/pipeline-syntax` and the directive-generator at `http://<current_IP_of_ec2>:8080/directive-generator`

### Building the first Pipeline
- Using pipeline script, check out the steps [here](https://www.jenkins.io/doc/book/pipeline/getting-started/#through-the-classic-ui)

- Using Pipeline Script from SCM,
![Pipeline Script from SCM](../assets/jenkins-scm-pipeline.JPG)

- The jenkins file in the [git repo](https://github.com/iam-veeramalla/Jenkins-Zero-To-Hero) looks like:

```groovy
pipeline {
agent {
docker { image 'node:16-alpine' }
}
stages {
stage('Test') {
steps {
sh 'node --version'
}
}
}
}
```
Explanation
- first, Jenkins gets the Jenkinsfile from the repo by cloning it.
- Builds a container based on the given image to run the script
- removes the container
## Plugin
- To get a nice view of the pipeline, install **Pipeline: Stage View** plugin.
## Adding Credentials
To add credentials (e.g. private-SSHkey, GitHub API token, DockerHub secret token etc.):
- Go to **Manage Jenkins** > **Credentials**
- Click on **(global)** Domain
- Click on **Add Credentials**
- select the appropriate alternative from the dropdown of **Kind** .
- Leave the **Scope** to its default value. Provide a name in the **ID** and an optional description in **Description**.
- In the **Username**, add the username. Leave the **Treat username as secret** checkbox as empty.
- In the **Password**, add the password.
- Click on **Create** .
## Referenes
- [Pipeline](https://www.jenkins.io/doc/book/pipeline/)
Loading

0 comments on commit b0dfde8

Please sign in to comment.