Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ci-lab03-jenkins] 更新文档和添加模板 #15

Merged
merged 2 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions ci/lab03-jenkins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
* https://www.jenkins.io/download/
* https://www.jenkins.io/blog/2011/06/16/jenkins-long-term-support-release/
* https://www.jenkins.io/blog/2012/03/13/why-does-jenkins-have-blue-balls/
* https://www.jenkins.io/blog/2014/07/08/workflow-plugin-tutorial-writing-a-step-impl/
* https://www.jenkins.io/blog/2017/01/17/Jenkins-is-upgrading-to-Java-8/

### 1.3 相关工具对比
Expand Down Expand Up @@ -290,7 +289,6 @@ pipeline {

1. 2014 年 5 月,groovy-cps 库诞生了 0.1 版本。
2. 2016 年 4 月,Jenkins 发布了 2.0 版本,对应的 groovy-cps-1.7。
3. 2016 年 4 月,Jenkins 发布了 2.0 版本。
4. 2016 年 8 月,Jenkins 的 pipeline-model-definition 插件发布 0.1 版本。
5. 2017 年 2 月,Jenkins 的 pipeline-model-definition 插件发布 1.0 GA 版本。
6. 2017 年 4 月,Blue Ocean 1.0
Expand Down Expand Up @@ -350,6 +348,7 @@ node {
* https://www.jenkins.io/blog/2017/02/15/declarative-notifications/
* https://www.jenkins.io/blog/2017/04/05/say-hello-blueocean-1-0/
* https://www.jenkins.io/blog/2017/04/10/jenkins-has-upgraded-to-java-8/
* https://www.jenkins.io/blog/2014/07/08/workflow-plugin-tutorial-writing-a-step-impl/


#### 3. Declarative Pipeline 特点和原理
Expand Down Expand Up @@ -493,5 +492,7 @@ def purgeBranchString(branch) {
* https://github.com/opsbox-dev/oes-pipeline-plugin

## 4. 实战练习

* https://github.com/seanly/cloudogu-jenkinsfiles

>两三句话的简介?

* https://github.com/seanly/cloudogu-jenkinsfiles
170 changes: 170 additions & 0 deletions ci/lab03-jenkins/templates/baseimage/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*

# 功能描述

构建基础镜像

# 参数配置

```yaml

coderepo:
auth: xxx
url: xxx

dockerpush:
auth: xxx
registry: xxx
namespace: xxx
image: xxx

build_method: docker-compose
```

# 插件依赖

* https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/
* https://plugins.jenkins.io/docker-workflow/
* https://github.com/opsbox-dev/oes-template-plugin


# 使用方法

*/

def branch = purgeBranchString(coderepo.branch)

pipeline {

agent any

options {
disableConcurrentBuilds()
skipDefaultCheckout true
}

stages {

stage("Checkout Code") {
steps {
script {
deleteDir()
def gitParams = [
$class : 'GitSCM',
branches : [[name: "${branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions : [[$class: 'CleanBeforeCheckout']],
submoduleCfg : [],
userRemoteConfigs : [[url: "${coderepo.url}"]]
]
if (coderepo.auth != null) {
gitParams.userRemoteConfigs = [[credentialsId: "${coderepo.auth}",
url : "${coderepo.url}"]]
}
checkout(gitParams)
}
}
} // end: Checkout Code

stage("Build Image by Docker Compose") {
when {
expression { build_method == "docker-compose" }
}
steps {
script {
// 检查关键文件是否存在
if (!fileExists('docker-compose.yml')) {
error( "--//ERR: 缺少docker-compose.yml文件")
}

def _docker_compose_j2 = """
|{% set version = "${branch}" %}
|version: '3'
|services:
|{%- for name, _ in services.items() %}
| {{ name }}:
| {% if version == "main" %}
| image: "${dockerpush.registry}/${dockerpush.namespace}/${dockerpush.image}:{{name}}"
| {% else %}
| image: "${dockerpush.registry}/${dockerpush.namespace}/${dockerpush.image}:{{name}}-{{ version }}"
| {% endif %}
|{%- endfor %}
""".stripMargin().stripIndent()
writeFile(file: 'docker-compose.j2', text: _docker_compose_j2)

def _dockerfile = '''
FROM rockylinux:8
RUN yum install -y python3 && pip3 install jinja2-cli[yaml]
'''.stripIndent()
writeFile(file: 'Dockerfile', text: _dockerfile)

def jinja2Image = docker.build("rockylinux8:jinja2")
jinja2Image.inside {
sh """
set -eux
jinja2 ./docker-compose.j2 ./docker-compose.yml > docker-compose.override.yml
"""
}

docker.withRegistry("https://${dockerpush.registry}", "${dockerpush.auth}") {
sh """
set -eux
docker-compose -f docker-compose.yml -f docker-compose.override.yml build
docker-compose -f docker-compose.yml -f docker-compose.override.yml push
"""
}
}
}
} // end: Build Image by Docker Compose

stage("Build Image by Docker") {
when {
expression { build_method == "docker" }
}
steps {
script {
if (!fileExists('Dockerfile')) {
error( "--//ERR: 缺少 Dockerfile 文件")
}
docker.withRegistry("https://${dockerpush.registry}", "${dockerpush.auth}") {
def _tag = branch
if (branch == "master") {
_tag = "latest"
}
def _image = docker.build("${dockerpush.registry}/${dockerpush.namespace}/${dockerpush.image}:${_tag}")
_image.push()
}
}
}
} // end: Build Image by Docker

}
}

// looks for string [ci skip] in commit message
boolean getCiSkip() {
sh(returnStdout: true, script: 'git show --pretty=%s%b -s',
label : 'check skip CI?'
).toLowerCase().contains('[ci skip]')
}

String getGitCommit() {
sh(
returnStdout: true, script: 'git rev-parse HEAD',
label : 'getting GIT commit'
).trim()
}

def purgeBranchString(branch) {
def gitBranch = branch
if (gitBranch?.startsWith("refs/heads/")) {
gitBranch = gitBranch.replace("refs/heads/", "")
if (gitBranch != "main") {
error("--//INFO: 不支持除 main 之外的分支")
}
}
if (gitBranch?.startsWith("refs/tags/")) {
gitBranch = gitBranch.replace("refs/tags/", "")
}
return gitBranch
}
146 changes: 146 additions & 0 deletions ci/lab03-jenkins/templates/general/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*

# 功能描述

构建基础镜像

# 参数配置

```yaml

coderepo:
auth: xxx
url: xxx
branch: mkt4d

registry:
url: xxx
auth: xxx

pipeline:
build:
script: |
# 配置环境变量
# 使用 dapper 编译代码
dapper -m bind

archive:
script: |
# 打包镜像
docker build -t $DOCKER_REG/xxx/xxx:version . -f Dockerfile
docker push $DOCKER_REG/xxx/xxx:version

deploy:
image: xxx/xxx
kubeconfig: xxx # credential id.
script: |
kubectl set image <app> <app>=$DOCKER_REG/xxx/xxx:version -n <group>
kubectl rollout status --timeout=300 <app> -n <group>

```

# 插件依赖

* https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/
* https://plugins.jenkins.io/docker-workflow/
* https://www.jenkins.io/doc/book/pipeline/docker/
* https://docs.cloudbees.com/docs/admin-resources/latest/plugins/docker-workflow
* https://github.com/opsbox-dev/oes-template-plugin


# 使用方法

演示样例代码:https://jihulab.com/oes-workspace/spring-demo
*/

def branch = purgeBranchString(coderepo.branch)

pipeline {

agent any

options {
disableConcurrentBuilds()
skipDefaultCheckout true
}

stages {

stage("Checkout Code") {
steps {
script {
deleteDir()
def gitParams = [
$class : 'GitSCM',
branches : [[name: "${branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions : [[$class: 'CleanBeforeCheckout']],
submoduleCfg : [],
userRemoteConfigs : [[url: "${coderepo.url}"]]
]
if (coderepo.auth != null) {
gitParams.userRemoteConfigs = [[credentialsId: "${coderepo.auth}",
url : "${coderepo.url}"]]
}
checkout(gitParams)
}
}
} // end: Checkout Code

stage("build") {
steps {
script {
docker.withRegistry("https://${registry.url}", "${registry.auth}") {
sh """
${pipeline.build.script}
""".stripIndent()
}
}
}
}

stage("archive") {
steps {
script {
docker.withRegistry("https://${registry.url}", "${registry.auth}") {
sh """
export DOCKER_REG=${registry.url}
${pipeline.build.script}
""".stripIndent()
}
}
}
}

stage("deploy") {
environment {
KUBECONFIG = credentials("${pipeline.deploy.kubeconfig}")
}
steps {
script {
docker.withRegistry("https://${registry.url}", "${registry.auth}") {
docker.image("${pipeline.deploy.image}").inside("-e KUBECONFIG=/root/.kube/config -v ${KUBECONFIG}:/root/.kube/config") {
sh """
${pipeline.deploy.script}
""".stripIndent()
}
}
}
}
} // end deploy stage.
}
}

def purgeBranchString(branch) {
def gitBranch = branch
if (gitBranch?.startsWith("refs/heads/")) {
gitBranch = gitBranch.replace("refs/heads/", "")
if (gitBranch != "main") {
error("--//INFO: 不支持除 main 之外的分支")
}
}
if (gitBranch?.startsWith("refs/tags/")) {
gitBranch = gitBranch.replace("refs/tags/", "")
}
return gitBranch
}