Clarify some details
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
.vagrant
|
||||
@@ -1,12 +1,12 @@
|
||||
# Exercise 1
|
||||
|
||||
In this exercise, you will practice installing and configuring Jenkins on your machine.
|
||||
In this exercise, you will practice installing and configuring Jenkins on your machine. Feel free to experiment with a different Jenkins distribution than the proposed WAR file.
|
||||
|
||||
## Installing Jenkins
|
||||
|
||||
1. Download the [latest stable Jenkins WAR file](http://mirrors.jenkins.io/war-stable/latest/jenkins.war). To download from the command line, use `wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war`.
|
||||
2. Open a terminal and navigate to the directory containing the WAR file.
|
||||
3. Run the command `java -jar jenkins.war` to start Jenkins on port 8080. Provide the `--httpPort` option if you experience a port conflict e.g. `java -jar jenkins.war --httpPort=9999`. After a couple of seconds you should see the message "Jenkins is fully up and running" in the log output.
|
||||
3. Run the command `java -jar jenkins.war` to start Jenkins on port 8080. Provide the `--httpPort` option if you experience a port conflict e.g. `java -jar jenkins.war --httpPort=9999`. For more information on starting and stopping Jenkins, see the [user guide](https://wiki.jenkins.io/display/JENKINS/Starting+and+Accessing+Jenkins). After a couple of seconds you should see the message "Jenkins is fully up and running" in the log output.
|
||||
4. Open a browser of your choice and navigate to `localhost:<port>`. The default is `localhost:8080`.
|
||||
5. In the screen named "Unlock Jenkins", enter the password from the console output. Press the "Continue" button.
|
||||
6. In the screen named "Customize Jenkins", select the option "Install suggested plugins".
|
||||
|
||||
@@ -5,10 +5,10 @@ In this exercise, you will create a new freestyle job and configure it to build
|
||||
## Defining, Configuring and Organizing a Job
|
||||
|
||||
1. From the dashboard, click the "New Item" button.
|
||||
2. Enter the item name "my-freestyle-job" and select "Freestyle project". Press the "OK" button.
|
||||
2. Enter the item name `my-freestyle-job` and select "Freestyle project". Press the "OK" button.
|
||||
3. In the job configuration, define the option to only keep the last 2 builds. Provide the description "A simple freestyle job". Upon building the project, a String parameter named `MESSAGE` should be provided. Press the "Save" button.
|
||||
4. Trigger a new build by pressing the "Build with Parameters" button. Enter a value for the `MESSAGE` parameter. The build should finish successfully. Locate the provided parameter value in the build information.
|
||||
5. Run the build two more times. What do you see?
|
||||
6. Create a new view named "test". Add the job to the view.
|
||||
7. Create a new folder named "freestyle" as part of the view. Move the job into the folder.
|
||||
6. Create a new view named `test`. Add the job to the view.
|
||||
7. Create a new folder named `freestyle` as part of the view. Move the job into the folder.
|
||||
8. Locate the build information in `$JENKINS_HOME`. Inspect the directory structure.
|
||||
@@ -8,7 +8,7 @@ Configure the Git SCM and point the proper URL. The default is the `master` bran
|
||||
|
||||

|
||||
|
||||
Create the Gradle build step.
|
||||
Create the Gradle build step. Ensure to select the "Use Gradle Wrapper" option.
|
||||
|
||||

|
||||
|
||||
@@ -68,4 +68,4 @@ Build step 'Invoke Gradle script' changed build result to SUCCESS
|
||||
Finished: SUCCESS
|
||||
```
|
||||
|
||||
As a side note: The GitHub plugin is [currently broken](https://issues.jenkins-ci.org/browse/JENKINS-11337) if you wanted to build multiple branches with a single job. You will have to model it as a multi-branch pipeline job.
|
||||
**As a side note:** The GitHub plugin is [currently broken](https://issues.jenkins-ci.org/browse/JENKINS-11337) if you wanted to build multiple branches with a single job. You will have to model it as a multi-branch pipeline job.
|
||||
@@ -8,7 +8,7 @@ In this exercise, you will configure the existing job to execute tests. Furtherm
|
||||
2. Execute the build twice to generate a graph. Have a look at the executed tests in the test results.
|
||||
3. Include all test results (unit and integration tests) in the reporting.
|
||||
4. Have a look at how the test result trend changes.
|
||||
5. Install the JaCoCo plugin.
|
||||
5. Install the [JaCoCo plugin](https://plugins.jenkins.io/jacoco).
|
||||
6. Reconfigure the Gradle build step to also generate JaCoCo reports: `clean build jacocoTestReport jacocoIntegrationTestReport`.
|
||||
7. Add a post-build action for publish the JaCoCo reports. Use the following path to look for results: `build/jacoco/**.exec`.
|
||||
8. Execute the build twice to generate a graph. Have a look at the code coverage results.
|
||||
@@ -16,7 +16,7 @@ The trend changes accordingly.
|
||||
|
||||

|
||||
|
||||
Install the JaCoCo plugin.
|
||||
Install the JaCoCo plugin from the Plugin Manager page.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ You will enhance the existing job to generate a JAR file and store it on Jenkins
|
||||
2. Execute the build. The build should list the artifact `gradle-initializr-1.0.0.jar`.
|
||||
3. Have a look at the recorded fingerprints of this build.
|
||||
4. Render the MD5 hash of the artifact and the usage of the artifact.
|
||||
5. Install the Copy Artifacts plugin.
|
||||
5. Install the [Copy Artifacts plugin](https://plugins.jenkins.io/copyartifact).
|
||||
6. Create a downstream job named `consumer`.
|
||||
7. Configure the downstream job to use the artifact produced by the upstream job.
|
||||
8. Run the the build for the job `gradle-initializr`.
|
||||
|
||||
@@ -12,7 +12,7 @@ Have a look at the details of the fingerprinting.
|
||||
|
||||

|
||||
|
||||
Install the Copy Artifacts plugin.
|
||||
Install the Copy Artifacts plugin from the Plugin Manager page.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -2,16 +2,25 @@
|
||||
|
||||
You will start a VM using Vagrant as practice environment to set up a distributed build with 2 agents.
|
||||
|
||||
## Starting up the VMs
|
||||
|
||||
1. To start up the VMs, navigate to this directory. It should contain a `Vagrantfile`.
|
||||
2. Run the command `vagrant up`. Bringing up the VMs might take some minutes. The two VMs will be available with the IP address `192.168.99.201` and `192.168.99.202`. The username/password credentials for those VMs are `jenkins:jenkins`.
|
||||
|
||||
## Configuring and Executing Jobs in a Distributed Build
|
||||
|
||||
1. Go to "Manage Jenkins" > "Manage Nodes". You should see a single `master` node.
|
||||
2. Configure the `master` node by setting the # of executor value to 0. That will take care of never using the `master` for job workload.
|
||||
3. Have other physical or virtual machines ready that can act as agent nodes. Log into the machine as `root` user and create a new user named `jenkins` with the commands `useradd -d /var/lib/jenkins jenkins` and `passwd jenkins`. From the `master` node, copy the contents of the `id_rsa.key` file to the clipboard. Paste the contents of the clipboard to the file `/var/lib/jenkins/.ssh/authorized_keys`.
|
||||
4. Add new nodes by clicking "New Nodes". Enter an appropriate name and select the option "Permanent Agent". Use the remote directory `/home/jenkins/jenkins_slave` and set the # of executors to 2. Enter the host and provide credentials by selecting "SSH Username with private key". To keep things easy select "Non verifying Verification Strategy".
|
||||
3. Add new nodes by clicking "New Nodes". Enter an appropriate name and select the option "Permanent Agent". Use the remote directory `/home/jenkins/jenkins_slave` and set the # of executors to 2. Enter the IP address `192.168.99.201` as host and provide credentials by selecting "Username with password". You will likely have to create a new credential. To keep things easy select "Non verifying Verification Strategy".
|
||||
4. Trigger a build. You should see that the build is only executed on the agent and not the `master` node.
|
||||
5. Add at least one more agent.
|
||||
5. Add one more agent with the IP address `192.168.99.202`.
|
||||
6. Trigger a build. You should see that the build can be executed on any of the agents.
|
||||
7. Configure one of the agents to only build jobs with a specific label e.g. `java`. Change the "Usage" field to "Only build jobs with label expressions matching this node".
|
||||
8. Configure the `gradle-initializr` job and assign the label `java`.
|
||||
9. Trigger a build of the `gradle-initializr` job. It is only executed by the dedicated agent.
|
||||
10. Trigger other jobs that do not have the label `java` assigned to them. They are waiting for an agent that can execute the build.
|
||||
10. Trigger other jobs that do not have the label `java` assigned to them. They are waiting for an agent that can execute the build.
|
||||
|
||||
## Shutting down the VMs
|
||||
|
||||
1. After you are done with the exercise, navigate to the directory containing the `Vagrantfile`.
|
||||
2. Tear down the VM by executing `vagrant destroy -f`.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 941 KiB After Width: | Height: | Size: 956 KiB |
@@ -1,14 +1,14 @@
|
||||
# Exercise 11
|
||||
|
||||
In this exercise, you will set up a new multi-branch pipeline job and point it to an existing repository on GitHub. You will visualize the pipeline with the standard view and the Blue Ocean plugin.
|
||||
In this exercise, you will set up a new multi-branch pipeline job and point it to an existing repository on GitHub. You will visualize the pipeline with the standard view and the Blue Ocean plugin. The job uses [SonarCloud](https://sonarcloud.io/) to capture static code analysis metrics and deploys the application to [Heroku](https://www.heroku.com/). You will need to create accounts for both services to follow along. Both services offer free tiers.
|
||||
|
||||
## Creating a Pipeline Job
|
||||
|
||||
1. Have a look at the [repository](https://github.com/bmuschko/todo-spring-boot) `bmuschko/todo-spring-boot` on GitHub. The repository already contains the build definition in the form of a `Jenkinsfile`. Identify each of the steps.
|
||||
2. In Jenkins, set up the credentials `SONARCLOUD_TOKEN` and `HEROKU_API_KEY` if they don't exist yet.
|
||||
1. Have a look at the [repository](https://github.com/bmuschko/todo-spring-boot) `bmuschko/todo-spring-boot` on GitHub. The repository already contains the build definition in the form of a `Jenkinsfile`. Identify each of the steps. Fork and clone the repository so you can later on create and push new branches.
|
||||
2. In Jenkins, set up the credentials `SONARCLOUD_TOKEN` and `HEROKU_API_KEY` if they don't exist yet. The SonarCloud token can be retrieved under [My Account > Security](https://sonarcloud.io/account/security/). The Heroku API can be generated under [Account Settings > API Key](https://dashboard.heroku.com/account).
|
||||
3. Create a new multi-branch pipeline job for the repository.
|
||||
4. The initial build is triggered automatically. Have a look at the pipeline in the standard view and its console output.
|
||||
5. Install the Blue Ocean plugin.
|
||||
5. Install the [Blue Ocean plugin](https://plugins.jenkins.io/blueocean).
|
||||
6. Open the Blue Ocean pipeline visualization for the job. Manually trigger the deployment step. Open a browser with the deployed application on Heroku.
|
||||
7. Create a new branch named `bugfix` and push it to the remote repository. The code should be based off of `master`.
|
||||
8. Select "Scan Multibranch Pipeline Now". The job should build the new branch.
|
||||
@@ -5,13 +5,13 @@ In this exercise, you'll create a declarative pipeline for a Go-based project. T
|
||||
## Writing a Basic Jenkinsfile
|
||||
|
||||
1. Create a new GitHub repository named `go-on-jenkins`.
|
||||
2. Create a new `Jenkinsfile` in the root directory of the repository as well as a simple `main.go` file. The main function just prints "Hello World!". Initialize the project via Go Modules.
|
||||
2. Create a new `Jenkinsfile` in the root directory of the repository as well as a simple `main.go` file. The main function just prints "Hello World!". The repository https://github.com/bmuschko/go-helloworld-template shows an example.
|
||||
3. Commit the files and push them to the remote repository.
|
||||
4. Set up a new pipeline job for this repository in Jenkins.
|
||||
5. Install the [Jenkins Go plugin](https://plugins.jenkins.io/golang).
|
||||
6. Configure the latest Go runtime as global tool.
|
||||
6. Configure the latest Go runtime as global tool. Use a name that reflects the Go version. Remember the name for the next step.
|
||||
7. Enhance the `Jenkinsfile` based on the following requirements. The Jenkinsfile should use the declarative syntax.
|
||||
* The job can run on all agents.
|
||||
* The job sets the environment variable `GO111MODULES=on`.
|
||||
* The job uses the Go runtime from the global tool definition.
|
||||
* The job uses the Go runtime from the global tool definition (see previous step).
|
||||
* The job specifies one build stage named "Build". The build stage executes the shell command `go build`.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Exercise 13
|
||||
|
||||
We'll want to enhance the pipeline by additional stages and implement a release workflow. The project is going to use an external tool called [GoReleaser](https://goreleaser.com/) to publish cross-compiled artifacts to [GitHub Releases](https://help.github.com/en/github/administering-a-repository/creating-releases). The binaries should only be released if the commit has been tagged.
|
||||
We'll want to enhance the existing Go pipeline by additional stages and implement a release workflow. The project is going to use an external tool called [GoReleaser](https://goreleaser.com/) to publish cross-compiled artifacts to [GitHub Releases](https://help.github.com/en/github/administering-a-repository/creating-releases). The binaries should only be released if the commit has been tagged. You will need to create an account on [CodeCov](https://codecov.io/) and set up a [GitHub token](https://github.com/settings/tokens) to follow along.
|
||||
|
||||
## Enhancing a Pipeline With Advanced Features
|
||||
|
||||
@@ -8,13 +8,11 @@ We'll want to enhance the pipeline by additional stages and implement a release
|
||||
* Add a build step that runs the shell command `go test ./...`.
|
||||
* Generate code coverage metrics by adding the option `-coverprofile=coverage.txt` to the build step.
|
||||
* Publish the code coverage metrics to CodeCov by sending a curl command `curl -s https://codecov.io/bash | bash -s -`.
|
||||
* Log into [CodeCov](https://codecov.io/), determine the CodeCov token for the repository (aka Repository Upload Token) and set it up as credential in Jenkins.
|
||||
* Retrieve the credential and set the value as environment variable named `CODECOV_TOKEN`.
|
||||
2. Add a stage named `Code Analysis` that uses [golangci-lint](https://github.com/golangci/golangci-lint) to detect issues with the code.
|
||||
* Add a build step for installing the `golangci-lint` with the shell command `curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.17.1`
|
||||
* Add a build step for installing the `golangci-lint` with the shell command `curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.18.0`
|
||||
* Add a build step that runs `golangci-lint` with the shell command `golangci-lint run`.
|
||||
3. Add a stage named `Release` that uses [GoReleaser](https://github.com/goreleaser/goreleaser).
|
||||
* Only build this step if the commit has been tagged.
|
||||
* Set up a credential in Jenkins named `github_token` and set your GitHub token.
|
||||
* Set up a credential in Jenkins named `github_token` and set your [GitHub token](https://github.com/settings/tokens). Create a new token if you didn't set up one yet.
|
||||
* Retrieve the credential and set the value as environment variable named `GITHUB_TOKEN`.
|
||||
* Add a build step that runs the shell command `curl -sL https://git.io/goreleaser | bash`.
|
||||
@@ -1,16 +1,9 @@
|
||||
# Solution
|
||||
|
||||
Create the credentials for the CodeCov token.
|
||||
|
||||

|
||||
|
||||
You can implement the "Test" stage as follows.
|
||||
|
||||
```groovy
|
||||
stage('Test') {
|
||||
environment {
|
||||
CODECOV_TOKEN = credentials('CODECOV_TOKEN')
|
||||
}
|
||||
steps {
|
||||
sh 'go test ./... -coverprofile=coverage.txt'
|
||||
sh "curl -s https://codecov.io/bash | bash -s -"
|
||||
@@ -23,7 +16,7 @@ You can implement the "Code Analysis" stage as follows.
|
||||
```groovy
|
||||
stage('Code Analysis') {
|
||||
steps {
|
||||
sh 'curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.17.1'
|
||||
sh 'curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.18.0'
|
||||
sh 'golangci-lint run'
|
||||
}
|
||||
}
|
||||
@@ -47,4 +40,48 @@ stage('Release') {
|
||||
sh 'curl -sL https://git.io/goreleaser | bash'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The final `Jenkinsfile` looks similar to the solution below.
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
tools {
|
||||
go 'go-1.12'
|
||||
}
|
||||
environment {
|
||||
GO111MODULE = 'on'
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'go build'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'go test ./... -coverprofile=coverage.txt'
|
||||
sh "curl -s https://codecov.io/bash | bash -s -"
|
||||
}
|
||||
}
|
||||
stage('Code Analysis') {
|
||||
steps {
|
||||
sh 'curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.18.0'
|
||||
sh 'golangci-lint run'
|
||||
}
|
||||
}
|
||||
stage('Release') {
|
||||
when {
|
||||
buildingTag()
|
||||
}
|
||||
environment {
|
||||
GITHUB_TOKEN = credentials('GITHUB_TOKEN')
|
||||
}
|
||||
steps {
|
||||
sh 'curl -sL https://git.io/goreleaser | bash'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -13,7 +13,7 @@ The directory structure of shared library repository should have the following s
|
||||
Define the pipeline as global variable in the file `standard.groovy`.
|
||||
|
||||
```groovy
|
||||
def call(String goToolName = 'go-1.12', String golangCiVersion = 'v1.12.5') {
|
||||
def call(String goToolName = 'go-1.12', String golangCiVersion = 'v1.18.0') {
|
||||
pipeline {
|
||||
agent any
|
||||
tools {
|
||||
@@ -29,9 +29,6 @@ def call(String goToolName = 'go-1.12', String golangCiVersion = 'v1.12.5') {
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
environment {
|
||||
CODECOV_TOKEN = credentials('CODECOV_TOKEN')
|
||||
}
|
||||
steps {
|
||||
sh 'go test ./... -coverprofile=coverage.txt'
|
||||
sh "curl -s https://codecov.io/bash | bash -s -"
|
||||
|
||||
Reference in New Issue
Block a user