-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.gitlab-ci.yml
More file actions
130 lines (122 loc) · 5.52 KB
/
Copy path.gitlab-ci.yml
File metadata and controls
130 lines (122 loc) · 5.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
---
# .gitlab-ci.yml — docker/lintorama
#
# Self-contained pipeline (no external template includes). Builds the lint-extras
# image and pushes semver / major / latest tags to this project's GitLab Container
# Registry ($CI_REGISTRY_IMAGE), then lints this repo with the freshly built image.
#
# RUNNER REQUIREMENT (Docker socket binding):
# This is a traditional Docker-executor runner — no dind, no shared daemon. The
# build job talks to the host Docker daemon through the bind-mounted socket, so
# the runner's config.toml must mount it:
# [runners.docker]
# volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
# Until that is in place the build job fails fast at the `docker info` check.
stages:
- build
- lint
- docs
variables:
# Published image version: baked into the OCI labels (BUILD_VER) and used as the
# primary registry tag. Bump this for each release.
BUILD_VER: "5.3.0"
# Docker Hub mirror target. Set DOCKERHUB_USER and DOCKERHUB_TOKEN as protected,
# masked CI/CD variables (DOCKERHUB_TOKEN is a Docker Hub access token, not the
# account password) so every release is pushed to the public registry too.
DOCKERHUB_IMAGE: "docker.io/zaventh/lintorama"
# Pinned docker CLI image version.
DOCKER_VERSION: "28.3"
# Use the bind-mounted host daemon over its unix socket; no dind, no TLS.
# (Overrides the tcp://docker:2375 DOCKER_HOST the runner injects by default.)
DOCKER_HOST: "unix:///var/run/docker.sock"
DOCKER_TLS_CERTDIR: ""
DOCKER_BUILDKIT: "1"
build:
stage: build
image: "docker:$DOCKER_VERSION"
interruptible: true
rules:
# Build + push from the default branch (master) on every push ...
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
# ... and when started manually via "Run pipeline".
- if: '$CI_PIPELINE_SOURCE == "web"'
before_script:
- 'docker info >/dev/null 2>&1 || { echo "host docker socket not reachable at $DOCKER_HOST — is the runner configured with volumes=[\"/var/run/docker.sock:/var/run/docker.sock\"]?"; ls -l /var/run/docker.sock 2>&1 || true; exit 1; }'
# CI_REGISTRY_USER=gitlab-ci-token, CI_REGISTRY_PASSWORD=$CI_JOB_TOKEN: job-token
# auth scoped to this project's registry, no long-lived credentials.
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
# Docker Hub login for the public mirror push.
- echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USER" --password-stdin docker.io
script:
# Derive the major tag from the semver, e.g. 5.3.0 -> 5 (README pins :5 for pulls).
- MAJOR="${BUILD_VER%%.*}"
# Build once with three tags. $CI_JOB_STARTED_AT is already ISO8601 (no `date`).
- |
docker build \
--build-arg BUILD_VER="$BUILD_VER" \
--build-arg BUILD_DATE="$CI_JOB_STARTED_AT" \
--build-arg BUILD_SHA="$CI_COMMIT_SHA" \
--tag "$CI_REGISTRY_IMAGE:$BUILD_VER" \
--tag "$CI_REGISTRY_IMAGE:$MAJOR" \
--tag "$CI_REGISTRY_IMAGE:latest" \
--tag "$DOCKERHUB_IMAGE:$BUILD_VER" \
--tag "$DOCKERHUB_IMAGE:$MAJOR" \
--tag "$DOCKERHUB_IMAGE:latest" \
.
- docker push "$CI_REGISTRY_IMAGE:$BUILD_VER"
- docker push "$CI_REGISTRY_IMAGE:$MAJOR"
- docker push "$CI_REGISTRY_IMAGE:latest"
- docker push "$DOCKERHUB_IMAGE:$BUILD_VER"
- docker push "$DOCKERHUB_IMAGE:$MAJOR"
- docker push "$DOCKERHUB_IMAGE:latest"
lint:
stage: lint
needs: ["build"]
# Run the just-pushed image AS the job image (GitLab pulls it with the job token).
# entrypoint: [""] overrides the image's ENTRYPOINT so we invoke the linter ourselves.
image:
name: "$CI_REGISTRY_IMAGE:$BUILD_VER"
entrypoint: [""]
variables:
GIT_STRATEGY: clone # lint-extras relies on `git ls-files`
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "web"'
script:
# The Dockerfile only whitelists /code; CI checks out to $CI_PROJECT_DIR.
- git config --global --add safe.directory "$CI_PROJECT_DIR"
- /usr/local/bin/lint-extras
# Sync this repo's README to the Docker Hub repository description on each release.
# NOTE: the Docker Hub description API needs a JWT minted from /v2/users/login/.
# DOCKERHUB_TOKEN must be an access token with Read/Write/Delete scope (or the
# account password) — a read-only token can log in and push images but cannot
# edit the description.
dockerhub-description:
stage: docs
image: alpine:3.24
needs: ["build"]
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "web"'
before_script:
- apk add --no-cache curl jq
script:
# Derive "zaventh/lintorama" from the docker.io/... mirror target.
- REPO="${DOCKERHUB_IMAGE#docker.io/}"
- |
JWT="$(curl -sf -H 'Content-Type: application/json' \
-d "{\"username\": \"$DOCKERHUB_USER\", \"password\": \"$DOCKERHUB_TOKEN\"}" \
https://hub.docker.com/v2/users/login/ | jq -r '.token')"
- '[ -n "$JWT" ] && [ "$JWT" != "null" ] || { echo "Docker Hub login failed"; exit 1; }'
# jq -Rs safely JSON-encodes the whole README (quotes, backticks, newlines).
- |
PAYLOAD="$(jq -Rs \
--arg short 'One Docker image, many linters, a single command.' \
'{description: $short, full_description: .}' < README.md)"
- |
curl -sf -X PATCH \
-H "Authorization: JWT $JWT" \
-H 'Content-Type: application/json' \
-d "$PAYLOAD" \
"https://hub.docker.com/v2/repositories/$REPO/" >/dev/null
- echo "Synced Docker Hub description for $REPO"