-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
913fab9
commit b0dfde8
Showing
64 changed files
with
7,249 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/) | ||
Oops, something went wrong.