Skip to content

Gitlab CI example pipeline #221

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

Merged
merged 62 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
cd8216e
Gitlab CI experiment
febus982 Dec 26, 2024
8bee950
Add git in build phase
febus982 Dec 30, 2024
7cb8983
Create multi-arch build template
febus982 Dec 31, 2024
72d9221
Include templates file
febus982 Dec 31, 2024
09ab310
Remove --load
febus982 Dec 31, 2024
fb1f7a7
Use registry cache and push image to registry
febus982 Dec 31, 2024
6fef6a0
Try to fix buildx command
febus982 Dec 31, 2024
529374f
Try to fix buildx command 2
febus982 Dec 31, 2024
22182d9
Remove # from echoed string
febus982 Dec 31, 2024
dd63022
Remove = from options
febus982 Dec 31, 2024
6d46ca5
Add = to all options
febus982 Dec 31, 2024
0a2bb66
Improve login security
febus982 Dec 31, 2024
b30b53b
Build and push in separate commands
febus982 Dec 31, 2024
914e93e
Remove whitespace -.-' and unify build+push commands
febus982 Dec 31, 2024
076104d
Use prefix instead of suffix
febus982 Dec 31, 2024
e12acb8
Comment release
febus982 Dec 31, 2024
57db965
Add typing job
febus982 Dec 31, 2024
1af4e5c
Remove release
febus982 Dec 31, 2024
3230818
Add note about native ARM64 build
febus982 Dec 31, 2024
6c3c5d3
Add lint, format and tests
febus982 Dec 31, 2024
a483a24
Use test with console coverage report
febus982 Dec 31, 2024
7cfb205
Remove QEMU and default to amd64 architecture
febus982 Dec 31, 2024
de7d3e3
Add http app native arch image
febus982 Dec 31, 2024
9d2ba95
Reverse tag prefixes
febus982 Dec 31, 2024
4fbb720
Split prefix and suffix, create multiarch manifest
febus982 Dec 31, 2024
0275a20
Reminder to group the build pipeline
febus982 Jan 1, 2025
f3558f2
1st attempt at artifact promotion
febus982 Jan 1, 2025
52dfa55
Extend the correct template -.-
febus982 Jan 1, 2025
8cf46bd
Fix indentation
febus982 Jan 1, 2025
13ffd18
Remove comment
febus982 Jan 1, 2025
d123089
Unhappy with : ?
febus982 Jan 1, 2025
df2a370
Disable unix-timestamp format
febus982 Jan 1, 2025
771753f
Remove -
febus982 Jan 1, 2025
dccdfb6
Remove backslashes
febus982 Jan 1, 2025
de9798f
Update docker image version
febus982 Jan 1, 2025
74f2c2e
Use variable for docker version
febus982 Jan 1, 2025
08edaf9
Add quotes
febus982 Jan 1, 2025
d4ca073
Remove TODO
febus982 Jan 1, 2025
1baada2
Prepare timestamp and add debug printout
febus982 Jan 1, 2025
f9a6fee
Temporarily disable test stage
febus982 Jan 1, 2025
4819e39
Transform date in unix timestamp
febus982 Jan 1, 2025
6859da5
Login into registry
febus982 Jan 1, 2025
a9480e4
Fix date format
febus982 Jan 1, 2025
8890f26
Missing space
febus982 Jan 1, 2025
bf5a00f
Use variable for login
febus982 Jan 1, 2025
462e601
Rearrange variables
febus982 Jan 1, 2025
14477c4
Fix multiarch step extends
febus982 Jan 1, 2025
1310c54
Fix docker login
febus982 Jan 1, 2025
cccd903
Make target and platform optional
febus982 Jan 1, 2025
dbafef4
Template for docker login
febus982 Jan 1, 2025
a0d4c4c
Fix cache
febus982 Jan 1, 2025
fb7f4d7
Add debug line
febus982 Jan 1, 2025
6ada742
Remvoe other multiline \
febus982 Jan 1, 2025
e91b6d1
Aggregate manifests using buildx
febus982 Jan 1, 2025
20b627c
Fix manifest aggregation
febus982 Jan 1, 2025
395ac9d
Remove unnecessary quotes
febus982 Jan 1, 2025
dcd1e82
Use DOCKER_IMAGE_NAME in promote step
febus982 Jan 1, 2025
29c7b82
Fix registry in promote step
febus982 Jan 1, 2025
23327a7
Create image using job datetime so it can be executed again
febus982 Jan 1, 2025
6e52de9
Re-enable tests
febus982 Jan 1, 2025
59199a1
Use dev target for tests
febus982 Jan 1, 2025
1b907bb
Mention github pipeline in the README.md
febus982 Jan 1, 2025
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
2 changes: 2 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include:
- local: .gitlab_ci/base.yml
96 changes: 96 additions & 0 deletions .gitlab_ci/_templates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
variables:
DOCKER_IMAGE_TAG: $CI_COMMIT_SHA
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME
DOCKER_IMAGE_FULL_TAG: $CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG
DOCKER_VERSION: 27.4

.docker-gitlab-login: &docker-gitlab-login
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY

# Build Docker image for test
# TODO: Sign image using Cosign
.build-and-push-gitlab:
image: docker:$DOCKER_VERSION
services:
- docker:$DOCKER_VERSION-dind
variables:
DOCKER_BUILDKIT: 1
DOCKER_PLATFORM: ""
DOCKER_TARGET: ""
DOCKER_CACHE_FULL_TAG: $CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME:cache
before_script:
- apk add --no-cache bash git
script:
- docker buildx create --use
- docker buildx inspect --bootstrap
- *docker-gitlab-login
- echo "Building $DOCKER_IMAGE_FULL_TAG - Cache from $DOCKER_CACHE_FULL_TAG"
- if [[ -n "$DOCKER_TARGET" ]]; then export TARGET_ARG="--target $DOCKER_TARGET"; fi;
- if [[ -n "$DOCKER_PLATFORM" ]]; then export PLATFORM_ARG="--platform $DOCKER_PLATFORM"; fi;
- if [[ -n "$DOCKER_PLATFORM" ]]; then export PLATFORM_SUFFIX="-$(echo $DOCKER_PLATFORM | sed 's/\///')"; fi;
# remove \ from platform variable
- export SUFFIX=$(echo $DOCKER_PLATFORM | sed 's/\///')
- docker buildx build --push
$TARGET_ARG
--tag $DOCKER_IMAGE_FULL_TAG$PLATFORM_SUFFIX
$PLATFORM_ARG
--cache-from type=registry,ref=$DOCKER_CACHE_FULL_TAG
--cache-to type=registry,ref=$DOCKER_CACHE_FULL_TAG
.

# Architectures are hardcoded for multiarch, need to make this better
.multiarch-manifest-gitlab:
image: docker:$DOCKER_VERSION
services:
- docker:$DOCKER_VERSION-dind
script:
- *docker-gitlab-login
- echo "Building $DOCKER_IMAGE_FULL_TAG multiarch manifest"
- docker buildx imagetools create
--tag $DOCKER_IMAGE_FULL_TAG
$DOCKER_IMAGE_FULL_TAG-linuxamd64
$DOCKER_IMAGE_FULL_TAG-linuxarm64

.promote-image:
image: docker:$DOCKER_VERSION
variables:
PROMOTED_ENVIRONMENT: "dev"
DOCKER_BUILDKIT: 1
services:
- docker:$DOCKER_VERSION-dind
script:
- *docker-gitlab-login
# Remove the UTC offset, not supported by `date` in docker image (busybox)
- export CLEAN_DATETIME=$(echo "$CI_JOB_STARTED_AT" | sed 's/+00:00//' | sed 's/Z//')
# Transform in unix timestamp
- export UNIX_TIMESTAMP=$(date -d "$CLEAN_DATETIME" -D "%Y-%m-%dT%H:%M:%S" +%s)
- echo "Unix timestamp - $UNIX_TIMESTAMP"
- echo "Tagging $CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME:$PROMOTED_ENVIRONMENT-$UNIX_TIMESTAMP from $DOCKER_IMAGE_FULL_TAG"
- docker buildx imagetools create
--annotation index:org.opencontainers.image.version=$CI_COMMIT_SHORT_SHA
--annotation index:org.opencontainers.image.revision=$CI_COMMIT_SHA
--annotation index:org.opencontainers.image.source=$CI_PROJECT_URL
--annotation index:org.opencontainers.image.created=$CI_JOB_STARTED_AT
--tag $CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME:$PROMOTED_ENVIRONMENT-$UNIX_TIMESTAMP
$DOCKER_IMAGE_FULL_TAG

.python-typing:
image: $DOCKER_IMAGE_FULL_TAG
script:
- make typing

.python-lint:
image: $DOCKER_IMAGE_FULL_TAG
script:
- make lint

.python-format:
image: $DOCKER_IMAGE_FULL_TAG
script:
- make format

.python-tests:
image: $DOCKER_IMAGE_FULL_TAG
script:
- make test

17 changes: 17 additions & 0 deletions .gitlab_ci/base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variables:
# Use docker.io for Docker Hub if empty
REGISTRY: registry.gitlab.com
# IMAGE_NAME is defined as <account>/<repo> in GitLab CI/CD
IMAGE_NAME: $CI_REGISTRY_IMAGE
TEST_TAG: $REGISTRY/$CI_PROJECT_PATH:test

stages:
- build
- test
- deploy

include:
- local: /.gitlab_ci/_templates.yml
- local: /.gitlab_ci/build.yml
- local: /.gitlab_ci/test.yml
- local: /.gitlab_ci/deploy.yml
58 changes: 58 additions & 0 deletions .gitlab_ci/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Build Docker image for test
build-test:
stage: build
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-test
DOCKER_TARGET: dev
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .build-and-push-gitlab

# TODO: Make the multi-arch build in a single job (perhaps with a nested workflow)
build-http-app-amd64:
stage: build
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-http
DOCKER_PLATFORM: "linux/amd64"
DOCKER_TARGET: http_app
tags:
- saas-linux-small-amd64
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .build-and-push-gitlab

build-http-app-arm64:
stage: build
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-http
DOCKER_PLATFORM: "linux/arm64"
DOCKER_TARGET: http_app
tags:
- saas-linux-small-arm64
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .build-and-push-gitlab

aggregate-http-manifests:
stage: build
needs:
- build-http-app-amd64
- build-http-app-arm64
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-http
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .multiarch-manifest-gitlab

11 changes: 11 additions & 0 deletions .gitlab_ci/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
promote-dev:
stage: deploy
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-http
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .promote-image
when: manual
44 changes: 44 additions & 0 deletions .gitlab_ci/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Test Docker image
typing:
stage: test
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-test
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .python-typing

lint:
stage: test
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-test
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .python-lint

format:
stage: test
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-test
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .python-format

tests:
stage: test
variables:
DOCKER_IMAGE_NAME: $CI_PROJECT_NAME-test
rules:
# We run the pipeline only on merge requests or the `main` branch
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .python-tests
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This template provides out of the box some commonly used functionalities:
* Repository pattern for databases using [SQLAlchemy](https://www.sqlalchemy.org/) and [SQLAlchemy bind manager](https://febus982.github.io/sqlalchemy-bind-manager/stable/)
* Database migrations using [Alembic](https://alembic.sqlalchemy.org/en/latest/) (configured supporting both sync and async SQLAlchemy engines)
* Authentication and Identity Provider using [ORY Zero Trust architecture](https://www.ory.sh/docs/kratos/guides/zero-trust-iap-proxy-identity-access-proxy)
* Example CI/CD deployment pipeline for GitLab (The focus for this repository is still GitHub but, in case you want to use GitLab 🤷)
* [TODO] Producer and consumer to emit and consume events using [CloudEvents](https://cloudevents.io/) format on [Confluent Kafka](https://docs.confluent.io/kafka-clients/python/current/overview.html)

## Documentation
Expand Down
Loading