Skip to content

Commit e581e39

Browse files
Feature/update readme (#215)
* Update README
1 parent ee278e0 commit e581e39

File tree

14 files changed

+175
-82
lines changed

14 files changed

+175
-82
lines changed

README.md

Lines changed: 130 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,165 @@
1-
# Django continuous delivery
1+
# Talos - Django Continuous Delivery
22

33
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black)
44

55
> A [Django](https://docs.djangoproject.com) project template ready for continuous delivery.
66
7-
## 📝 Conventions
7+
## 🧩 Requirements
88

9-
In the following instructions:
9+
The Talos script can be run either using Docker or as a local shell command.
1010

11-
- replace `projects` with your actual projects directory
12-
- replace `My project name` with your chosen project name
11+
### 🐋 Docker
1312

14-
## Git
13+
In order to run Talos via Docker, a working [Docker installation](https://docs.docker.com/get-docker/) is the only requirement.
1514

16-
To get the existing project, change directory and clone the project repository.
15+
### 👨‍💻 Shell command
1716

17+
In order to run Talos as a shell command, first clone the repository in a local projects directory
1818
```console
19-
$ cd ~/projects/
20-
$ git clone https://github.com/20tab/django-continuous-delivery.git
19+
cd ~/projects
20+
git clone https://github.com/20tab/django-continuous-delivery.git talos-django
2121
```
22+
Then, install the following requirements
23+
| Requirements | Instructions |
24+
|--|--|
25+
|🌎 Terraform | [Install Guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) |
26+
|🐍 Python Dependencies | `pip install -r talos-django/requirements/common.txt` |
2227

23-
## 🧩 Requirements
28+
## 🔑 Credentials
29+
30+
### 🦊 GitLab
31+
If the GitLab integration is enabled, a Personal Access Token with _api_ permission is required.<br/>
32+
It can be generated in the GitLab User Settings panel.
2433

25-
A set of requirements must be installed before initializing the project.
34+
**Note:** the token can be generated in the Access Tokens section of the GitLab User Settings panel.<br/>
35+
⚠️ Beware that the token is shown only once after creation.
2636

37+
## 🚀️ Quickstart
38+
39+
Change to the projects directory, for example
2740
```console
28-
$ python3 -m pip install -r django-continuous-delivery/requirements/common.txt
41+
cd ~/projects
2942
```
3043

31-
## 🚀️ Quickstart
44+
### 🐋 Docker
3245

33-
Change directory and create a new project as in this example:
46+
```console
47+
docker run --interactive --tty --rm --volume $PWD:/data 20tab/talos-django:latest
48+
```
49+
50+
### 👨‍💻 Shell command
51+
52+
```console
53+
./talos-django/setup.py
54+
```
3455

56+
### Example
3557
```console
36-
$ python3 django-continuous-delivery/setup.py
37-
Project name: My project name
58+
Project name: My Project Name
3859
Project slug [my-project-name]:
3960
Service slug [backend]:
4061
Project dirname (backend, myprojectname) [backend]: myprojectname
4162
Development environment complete URL [https://dev.my-project-name.com/]:
4263
Staging environment complete URL [https://stage.my-project-name.com/]:
4364
Production environment complete URL [https://www.my-project-name.com/]:
4465
Media storage (local, s3-digitalocean, none) [s3-digitalocean]:
66+
Do you want to configure Redis? [y/N]: y
67+
Do you want to configure Gitlab? [Y/n]: y
68+
Gitlab group slug [my-project-name]:
69+
Make sure the Gitlab "my-project-name" group exists before proceeding. Continue? [y/N]: y
70+
Gitlab private token (with API scope enabled):
71+
Sentry DSN (leave blank if unused) []:
4572
Initializing the backend service:
4673
...cookiecutting the service
4774
...generating the .env file
4875
...formatting the cookiecut python code
4976
...compiling the requirements files
77+
- common.txt
78+
- test.txt
79+
- local.txt
80+
- remote.txt
81+
- base.txt
5082
...creating the '/static' directory
51-
Do you want to configure Gitlab? [Y/n]: Y
52-
Gitlab group slug [my-project-name]:
53-
Make sure the Gitlab "my-project-name" group exists before proceeding. Continue? [y/N]: y
54-
Gitlab private token (with API scope enabled):
55-
Sentry DSN (leave blank if unused) []: https://sentry.io/mydsn
56-
...creating the Gitlab repository and associated resources
57-
Project successfully initialized.
58-
$ cd myprojectname
83+
...creating the GitLab repository and associated resources
5984
```
85+
## 🗒️ Arguments
86+
87+
The following arguments can be appended to the Docker and shell commands
88+
89+
#### User id
90+
`--uid=$UID`
91+
92+
#### Group id
93+
`--gid=1000`
94+
95+
#### Output directory
96+
`--output-dir="~/projects"`
97+
98+
#### Project name
99+
`--project-name="My project name"`
100+
101+
#### Project slug
102+
`--project-slug="my-project-name"`
103+
104+
#### Project dirname
105+
`--project-dirname="myprojectname"`
106+
107+
### 🎖️ Service
108+
109+
#### Service slug
110+
`--service-slug=backend`
111+
112+
#### Service port
113+
`--internal-service-port=8000`
114+
115+
#### Project Domain
116+
If you don't want DigitalOcean DNS configuration the following args are required
117+
118+
`--project-url-dev=https://dev.project-domain.com`<br/>
119+
`--project-url-stage=https://stage.project-domain.com`<br/>
120+
`--project-url-prod=https://www.project-domain.com`
121+
122+
#### Media storage
123+
124+
Value | Description | Argument
125+
------------- | ------------- | -------------
126+
local | Docker Volume are used for store media | `--media-storage=local`
127+
s3-digitalocean | `--media-storage=s3-digitalocean`
128+
none | Project have no media | `--media-storage=none`
129+
130+
#### Redis
131+
For enable redis integration the following arguments are needed:
132+
133+
`--use-redis`
134+
135+
Disabled args
136+
`--no-redis`
137+
138+
### 🦊 GitLab
139+
> **⚠️ Important: Make sure the GitLab group exists before create.**
140+
> https://gitlab.com/gitlab-org/gitlab/-/issues/244345
141+
142+
For enable gitlab integration the following arguments are needed:
143+
144+
`--use-gitlab`<br/>
145+
`--gitlab-private-token={{gitlab-private-token}}`<br/>
146+
`--gitlab-group-slug={{gitlab-group-slug}}`
147+
148+
Disabled args
149+
`--no-gitlab`
150+
151+
Add user to repository using comma separeted arguments
152+
153+
`--gitlab-group-owners=user1, [email protected]`<br/>
154+
`--gitlab-group-maintainers=user1, [email protected]`<br/>
155+
`--gitlab-group-developers=user1, [email protected]`
156+
157+
#### 🪖 Sentry
158+
For enable sentry integration the following arguments are needed:
159+
160+
`--sentry-dsn={{frontend-sentry-dsn}}`
161+
162+
#### 🔇 Silent
163+
Is command for use default if no args are provided
164+
165+
`--silent`

bootstrap/collector.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,25 +171,25 @@ def clean_use_redis(use_redis):
171171

172172

173173
def clean_use_gitlab(use_gitlab):
174-
"""Tell whether Gitlab should be used."""
174+
"""Tell whether GitLab should be used."""
175175
if use_gitlab is None:
176-
return click.confirm(warning("Do you want to configure Gitlab?"), default=True)
176+
return click.confirm(warning("Do you want to configure GitLab?"), default=True)
177177
return use_gitlab
178178

179179

180180
def clean_gitlab_group_data(project_slug, gitlab_group_slug, gitlab_private_token):
181-
"""Return Gitlab group data."""
181+
"""Return GitLab group data."""
182182
gitlab_group_slug = slugify(
183-
gitlab_group_slug or click.prompt("Gitlab group slug", default=project_slug)
183+
gitlab_group_slug or click.prompt("GitLab group slug", default=project_slug)
184184
)
185185
click.confirm(
186186
warning(
187-
f'Make sure the Gitlab "{gitlab_group_slug}" group exists '
187+
f'Make sure the GitLab "{gitlab_group_slug}" group exists '
188188
"before proceeding. Continue?"
189189
),
190190
abort=True,
191191
)
192192
gitlab_private_token = gitlab_private_token or click.prompt(
193-
"Gitlab private token (with API scope enabled)", hide_input=True
193+
"GitLab private token (with API scope enabled)", hide_input=True
194194
)
195195
return gitlab_group_slug, gitlab_private_token

bootstrap/runner.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def init_service(
114114
"project_url_prod": project_url_prod,
115115
"project_url_stage": project_url_stage,
116116
"service_slug": service_slug,
117-
"use_redis": use_redis,
117+
"use_redis": f"{use_redis}",
118118
},
119119
output_dir=output_dir,
120120
no_input=True,
@@ -171,8 +171,8 @@ def init_gitlab(
171171
terraform_dir,
172172
logs_dir,
173173
):
174-
"""Initialize the Gitlab repository and associated resources."""
175-
click.echo(info("...creating the Gitlab repository and associated resources"))
174+
"""Initialize the GitLab repository and associated resources."""
175+
click.echo(info("...creating the GitLab repository and associated resources"))
176176
terraform_dir = Path(terraform_dir) / service_slug
177177
os.makedirs(terraform_dir, exist_ok=True)
178178
env = dict(
@@ -228,7 +228,7 @@ def init_gitlab(
228228
apply_stderr_path.write_text(apply_process.stderr)
229229
click.echo(
230230
error(
231-
"Error applying Terraform Gitlab configuration "
231+
"Error applying Terraform GitLab configuration "
232232
f"(check {apply_stderr_path} and {apply_log_path})"
233233
)
234234
)

cookiecutter.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
"project_url_stage": null,
1010
"project_url_prod": null,
1111
"media_storage": ["local", "s3-digitalocean", "none"],
12-
"use_redis": false,
12+
"use_redis": "False",
1313
"_extensions": ["cookiecutter.extensions.SlugifyExtension"]
1414
}

terraform/main.tf

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ terraform {
1111
required_providers {
1212
gitlab = {
1313
source = "gitlabhq/gitlab"
14-
version = "3.7.0"
14+
version = "3.12.0"
1515
}
1616
}
1717
}
@@ -68,6 +68,7 @@ resource "null_resource" "init_repo" {
6868
"git checkout -b main",
6969
"git push -u origin main -o ci.skip",
7070
"git remote set-url origin %s",
71+
"git checkout develop",
7172
]),
7273
replace(
7374
gitlab_project.main.http_url_to_repo,
@@ -113,12 +114,6 @@ resource "gitlab_project_badge" "coverage" {
113114
image_url = "https://gitlab.com/%%{project_path}/badges/%%{default_branch}/coverage.svg"
114115
}
115116

116-
resource "gitlab_project_badge" "pipeline" {
117-
project = gitlab_project.main.id
118-
link_url = "https://gitlab.com/%%{project_path}/pipelines"
119-
image_url = "https://gitlab.com/%%{project_path}/badges/%%{default_branch}/pipeline.svg"
120-
}
121-
122117
/* Group Variables */
123118

124119
resource "gitlab_group_variable" "vars" {

terraform/variables.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
variable "gitlab_group_slug" {
2-
description = "The slug of the Gitlab group."
2+
description = "The slug of the GitLab group."
33
type = string
44
}
55

66
variable "gitlab_group_variables" {
7-
description = "A map of Gitlab group variables to create."
7+
description = "A map of GitLab group variables to create."
88
type = map(map(any))
99
default = {}
1010
}
1111

1212
variable "gitlab_project_variables" {
13-
description = "A map of Gitlab project variables to create."
13+
description = "A map of GitLab project variables to create."
1414
type = map(map(any))
1515
default = {}
1616
}
1717

1818
variable "gitlab_token" {
19-
description = "The Gitlab token."
19+
description = "The GitLab token."
2020
type = string
2121
sensitive = true
2222
}

{{cookiecutter.project_dirname}}/.gitlab-ci.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ sentry_release:
2424
- docker:20-dind
2525
rules:
2626
- &pipeline-push-rule
27-
if: $CI_PIPELINE_SOURCE != "push"
27+
if: $CI_PIPELINE_SOURCE == "trigger"
2828
when: never
2929
- if: $SENTRY_DSN && ($CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAG)
3030
script:
@@ -49,7 +49,7 @@ test:
4949
- docker:20-dind
5050
needs: []
5151
rules:
52-
- if: $CI_PIPELINE_SOURCE == "push"
52+
- if: $CI_PIPELINE_SOURCE != "trigger" && $CI_PIPELINE_SOURCE != "merge_request_event"
5353
variables:
5454
{{ cookiecutter.service_slug|upper }}_CONTAINER_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_JOB_NAME}-${CI_JOB_ID}_{{ cookiecutter.service_slug }}"
5555
{{ cookiecutter.service_slug|upper }}_BUILD_TARGET: "test"
@@ -267,6 +267,8 @@ build_production:
267267
- docker:20-dind
268268
variables:
269269
TF_ROOT: ${CI_PROJECT_DIR}/terraform
270+
TERRAFORM_CMD: "gitlab-terraform"
271+
TERRAFORM_IMAGE: "registry.gitlab.com/gitlab-org/terraform-images/stable:latest"
270272
before_script:
271273
- export TF_VAR_service_container_image=${CI_REGISTRY_IMAGE}:${VERSION_REF}
272274
script:
@@ -276,7 +278,9 @@ build_production:
276278
-v ${PWD}:${PWD}
277279
-w ${PWD}
278280
-e CI_JOB_TOKEN
281+
-e TERRAFORM_CMD
279282
-e TF_ADDRESS=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/{{ cookiecutter.project_slug }}_${ENVIRONMENT_SLUG}
283+
-e TF_IN_AUTOMATION=1
280284
-e TF_ROOT
281285
-e TF_VAR_cache_url="${CACHE_URL}"
282286
-e TF_VAR_digitalocean_token="${DIGITALOCEAN_TOKEN}"
@@ -301,7 +305,7 @@ build_production:
301305
-e TF_VAR_service_replicas
302306
-e TF_VAR_web_concurrency="${WEB_CONCURRENCY}"
303307
-e TF_VAR_stack_slug="${STACK_SLUG}"
304-
registry.gitlab.com/gitlab-org/terraform-images/stable:latest ./scripts/deploy.sh
308+
${TERRAFORM_IMAGE}:latest ./scripts/deploy.sh
305309
artifacts:
306310
name: plan
307311
paths:

{{cookiecutter.project_dirname}}/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pip: pip_update ## Compile requirements
7777

7878
.PHONY: pip_update
7979
pip_update: ## Update requirements and dependencies
80-
python3 -m pip install -q -U pip~=22.0.0 pip-tools~=6.5.0 setuptools~=60.9.0 wheel~=0.37.0
80+
python3 -m pip install -q -U pip~=22.0.0 pip-tools~=6.5.0 setuptools~=60.10.0 wheel~=0.37.0
8181

8282
.PHONY: precommit
8383
precommit: ## Fix code formatting, linting and sorting imports

{{cookiecutter.project_dirname}}/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ A [Django](https://docs.djangoproject.com) project using [uvicorn](https://www.u
2020
- [Testing](#testing)
2121
- [Static files](#static-files)
2222
- [Continuous Integration](#continuous-integration)
23-
- [Gitlab CI](#gitlab-ci)
23+
- [GitLab CI](#gitlab-ci)
2424

2525
## Conventions
2626

@@ -132,6 +132,6 @@ $ make collectstatic
132132

133133
Depending on the CI tool, you might need to configure Django environment variables.
134134

135-
### Gitlab CI
135+
### GitLab CI
136136

137137
The configuration file `.gitlab-ci.yml` should work as is, needing no further customization.

{{cookiecutter.project_dirname}}/requirements/remote.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{% if "s3" in cookiecutter.media_storage %}django-storages[boto3]~=1.12.0
44
{% endif %}gunicorn~=20.1.0
55
gunicorn~=20.1.0
6-
{% if cookiecutter.use_redis %}redis~=4.1.0
6+
{% if cookiecutter.use_redis == "True" %}redis~=4.1.0
77
{% endif %}sentry-sdk~=1.5.0
88
uvicorn[standard]~=0.17.0
99
wait-for-it~=2.2.0

0 commit comments

Comments
 (0)