├── .gitignore
├── test
└── index.js
├── Dockerfile
├── index.html
├── release.config.js
├── kubernetes
├── drone-secrets.yaml
├── drone-pvc.yaml
└── drone.yaml
├── ci-demo.yaml
├── README.md
└── .drone.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 | node_modules
4 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | console.log('Unit test passed');
2 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginx:1.15-alpine
2 |
3 | COPY index.html /usr/share/nginx/html/
4 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World
4 |
5 |
6 | Hello World
7 |
8 |
9 |
--------------------------------------------------------------------------------
/release.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | '@semantic-release/commit-analyzer',
4 | '@semantic-release/release-notes-generator',
5 | '@semantic-release/github'
6 | ]
7 | };
8 |
--------------------------------------------------------------------------------
/kubernetes/drone-secrets.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Secret
4 | type: Opaque
5 | data:
6 | DOCKER_PASSWORD: encoded_password
7 | metadata:
8 | name: drone-secrets
9 | namespace: default
10 |
--------------------------------------------------------------------------------
/ci-demo.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: extensions/v1beta1
3 | kind: Deployment
4 | metadata:
5 | name: ci-demo-deployment
6 | namespace: default
7 | labels:
8 | app: ci-demo
9 | spec:
10 | replicas: 1
11 | template:
12 | spec:
13 | containers:
14 | - image: allovince/drone-ci-demo
15 | name: ci-demo
16 | restartPolicy: Always
17 |
--------------------------------------------------------------------------------
/kubernetes/drone-pvc.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: PersistentVolume
4 | metadata:
5 | name: drone-pv
6 | namespace: default
7 | labels:
8 | alicloud-pvname: drone-pv
9 | spec:
10 | capacity:
11 | storage: 2Gi
12 | accessModes:
13 | - ReadWriteMany
14 | persistentVolumeReclaimPolicy: Retain
15 | nfs:
16 | path: /
17 | server: "your_nas_service"
18 |
19 | ---
20 | kind: PersistentVolumeClaim
21 | apiVersion: v1
22 | metadata:
23 | name: drone-pvc
24 | namespace: default
25 | spec:
26 | accessModes:
27 | - ReadWriteMany
28 | resources:
29 | requests:
30 | storage: 2Gi
31 | selector:
32 | matchLabels:
33 | alicloud-pvname: drone-pv
34 |
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## A Demo to show workflow of Drone CI + GitFlow + Semantic Release + Kubernetes
2 |
3 | [](https://cloud.drone.io/AlloVince/drone-ci-demo)
4 |
5 | Step by step, to show how to build a powerful team development workflow with CI
6 |
7 | - [Github repo](https://github.com/AlloVince/drone-ci-demo)
8 | - [Drone CI of this repo](https://cloud.drone.io/AlloVince/drone-ci-demo)
9 | - [Docker Registry of this repo](https://cloud.docker.com/repository/docker/allovince/drone-ci-demo)
10 |
11 | ## Step 0: Hello world
12 |
13 | 1. Use drone cloud or setup a private drone by k8s
14 |
15 | Kubernetes config files under [./kubernetes](./kubernetes)
16 |
17 | 2. prepare `.drone.yml`
18 |
19 | ```yml
20 | kind: pipeline
21 | name: deploy
22 |
23 | steps:
24 | - name: hello-world
25 | image: docker
26 | commands:
27 | - echo "hello world"
28 | ```
29 |
30 | ## Step 1: For single person, manually release
31 |
32 | 1. Add a secret in Drone, key is `DOCKER_PASSWORD`, value is your docker registry password
33 |
34 | 2. prepare `.drone.yml`
35 |
36 | ```yml
37 | kind: pipeline
38 | name: deploy
39 |
40 | steps:
41 | - name: unit-test
42 | image: node:10
43 | commands:
44 | - node test/index.js
45 | when:
46 | branch: master
47 | event: push
48 | - name: build-image
49 | image: plugins/docker
50 | settings:
51 | repo: allovince/drone-ci-demo
52 | username: allovince
53 | password:
54 | from_secret: DOCKER_PASSWORD
55 | auto_tag: true
56 | when:
57 | event: tag
58 | ```
59 |
60 | 3. push to master branch will trigger unit test
61 |
62 | 4. manually release on github will trigger building docker image
63 |
64 | ## Step 2: For team develop, support GitFlow
65 |
66 | Change `.drone.yml` as [this](https://github.com/AlloVince/drone-ci-demo/blob/gitflow/.drone.yml)
67 |
68 | ## Step 3: For team develop, support GitFlow, with semantic-release
69 |
70 | Change `.drone.yml` as [this](https://github.com/AlloVince/drone-ci-demo/blob/semantic-release/.drone.yml)
71 |
72 |
--------------------------------------------------------------------------------
/.drone.yml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: pipeline
3 | name: deploy
4 |
5 | steps:
6 | - name: pre-check
7 | image: docker
8 | environment:
9 | DOCKER_PASSWORD:
10 | from_secret: DOCKER_PASSWORD
11 | MY_TELEGRAM_TOKEN:
12 | from_secret: MY_TELEGRAM_TOKEN
13 | MY_TELEGRAM_ID:
14 | from_secret: MY_TELEGRAM_ID
15 | GITHUB_TOKEN:
16 | from_secret: GITHUB_TOKEN
17 | commands:
18 | - echo $${DOCKER_PASSWORD}
19 | - echo $${MY_TELEGRAM_TOKEN}
20 | - echo $${MY_TELEGRAM_ID}
21 | - echo $${GITHUB_TOKEN}
22 |
23 | - name: unit-test
24 | image: node:10
25 | commands:
26 | - node test/index.js
27 | when:
28 | branch:
29 | include:
30 | - feature/*
31 | - master
32 | - dev
33 | event:
34 | include:
35 | - push
36 | - pull_request
37 |
38 | - name: build-branch-image
39 | image: plugins/docker
40 | settings:
41 | repo: allovince/drone-ci-demo
42 | username: allovince
43 | password:
44 | from_secret: DOCKER_PASSWORD
45 | tag:
46 | - ${DRONE_BRANCH##feature/}
47 | when:
48 | branch: feature/*
49 | event: push
50 |
51 | - name: build-test-image
52 | image: plugins/docker
53 | settings:
54 | repo: allovince/drone-ci-demo
55 | username: allovince
56 | password:
57 | from_secret: DOCKER_PASSWORD
58 | tag:
59 | - test
60 | when:
61 | branch: dev
62 | event: push
63 |
64 | - name: build-staging-image
65 | image: plugins/docker
66 | settings:
67 | repo: allovince/drone-ci-demo
68 | username: allovince
69 | password:
70 | from_secret: DOCKER_PASSWORD
71 | tag:
72 | - latest
73 | when:
74 | branch: master
75 | event: pull_request
76 |
77 | - name: semantic-release
78 | image: gtramontina/semantic-release:15.13.3
79 | environment:
80 | GITHUB_TOKEN:
81 | from_secret: GITHUB_TOKEN
82 | entrypoint:
83 | - semantic-release
84 | when:
85 | branch: master
86 | event: push
87 |
88 | - name: build-production-image
89 | image: plugins/docker
90 | settings:
91 | repo: allovince/drone-ci-demo
92 | username: allovince
93 | password:
94 | from_secret: DOCKER_PASSWORD
95 | tag:
96 | - ${DRONE_TAG}
97 | when:
98 | event: tag
99 |
100 | - name: k8s-deploy
101 | image: quay.io/honestbee/drone-kubernetes
102 | settings:
103 | kubernetes_server:
104 | from_secret: KUBERNETES_SERVER
105 | kubernetes_cert:
106 | from_secret: KUBERNETES_CERT
107 | kubernetes_token:
108 | from_secret: KUBERNETES_TOKEN
109 | namespace: default
110 | deployment: ci-demo-deployment
111 | repo: allovince/drone-ci-demo
112 | container: ci-demo
113 | tag:
114 | - ${DRONE_TAG}
115 | # remove commands in real production env
116 | commands:
117 | - echo "kubectl -n default set image deployment/ci-demo-deployment ci-demo=allovince/drone-ci-demo:${DRONE_TAG}"
118 | when:
119 | event: tag
120 |
--------------------------------------------------------------------------------
/kubernetes/drone.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: rbac.authorization.k8s.io/v1beta1
3 | kind: ClusterRoleBinding
4 | metadata:
5 | name: drone-rbac
6 | subjects:
7 | - kind: ServiceAccount
8 | name: default
9 | namespace: default
10 | roleRef:
11 | kind: ClusterRole
12 | name: cluster-admin
13 | apiGroup: rbac.authorization.k8s.io
14 |
15 | ---
16 | apiVersion: apps/v1
17 | kind: Deployment
18 | metadata:
19 | name: drone-secrets
20 | namespace: default
21 | labels:
22 | app: drone-secrets
23 | spec:
24 | replicas: 1
25 | selector:
26 | matchLabels:
27 | app: drone-secrets
28 | template:
29 | metadata:
30 | labels:
31 | app: drone-secrets
32 | spec:
33 | containers:
34 | - name: drone-secrets
35 | image: drone/kubernetes-secrets
36 | imagePullPolicy: Always
37 | env:
38 | - name: SECRET_KEY
39 | value: your_secret_key
40 | ports:
41 | - name: http
42 | containerPort: 3000
43 | restartPolicy: Always
44 |
45 | ---
46 | kind: Service
47 | apiVersion: v1
48 | metadata:
49 | name: drone-secrets-service
50 | namespace: default
51 | spec:
52 | selector:
53 | app: drone-secrets
54 | ports:
55 | - protocol: TCP
56 | port: 80
57 | targetPort: 3000
58 | name: http
59 |
60 | ---
61 | apiVersion: apps/v1
62 | kind: Deployment
63 | metadata:
64 | name: drone-server
65 | namespace: default
66 | labels:
67 | app: drone-server
68 | spec:
69 | replicas: 1
70 | selector:
71 | matchLabels:
72 | app: drone-server
73 | template:
74 | metadata:
75 | labels:
76 | app: drone-server
77 | spec:
78 | containers:
79 | - name: drone-server
80 | image: drone/drone:1.0.0
81 | imagePullPolicy: Always
82 | env:
83 | - name: DRONE_KUBERNETES_ENABLED
84 | value: "true"
85 | - name: DRONE_KUBERNETES_NAMESPACE
86 | value: default
87 | - name: DRONE_GITHUB_SERVER
88 | value: https://github.com
89 | - name: DRONE_GITHUB_CLIENT_ID
90 | value: your_github_client_id
91 | - name: DRONE_GITHUB_CLIENT_SECRET
92 | value: your_github_client_secret
93 | - name: DRONE_SERVER_HOST
94 | value: your_domain
95 | - name: DRONE_SERVER_PROTO
96 | value: https
97 | - name: DRONE_DATABASE_DRIVER
98 | value: sqlite3
99 | - name: DRONE_DATABASE_DATASOURCE
100 | value: "/drone/drone.sqlite"
101 | - name: DRONE_USER_CREATE
102 | value: username:AlloVince,admin:true
103 | - name: DRONE_SECRET_SECRET
104 | value: your_secret_key
105 | - name: DRONE_SECRET_ENDPOINT
106 | value: http://drone-secrets-service
107 | ports:
108 | - name: http
109 | containerPort: 80
110 | - name: https
111 | containerPort: 443
112 | volumeMounts:
113 | - name: drone-pvc
114 | mountPath: "/drone"
115 | volumes:
116 | - name: drone-pvc
117 | persistentVolumeClaim:
118 | claimName: drone-pvc
119 | restartPolicy: Always
120 |
121 | ---
122 | kind: Service
123 | apiVersion: v1
124 | metadata:
125 | name: drone-server-service
126 | namespace: default
127 | spec:
128 | selector:
129 | app: drone-server
130 | ports:
131 | - protocol: TCP
132 | port: 80
133 | name: http
134 |
135 |
136 | ---
137 | apiVersion: extensions/v1beta1
138 | kind: Ingress
139 | metadata:
140 | name: drone-ingress
141 | namespace: default
142 | annotations:
143 | kubernetes.io/ingress.class: traefik
144 | traefik.ingress.kubernetes.io/frontend-entry-points: http,https
145 | spec:
146 | rules:
147 | - host: your_domain
148 | http:
149 | paths:
150 | - path: /
151 | backend:
152 | serviceName: drone-server-service
153 | servicePort: 80
154 |
155 |
--------------------------------------------------------------------------------