├── .gitignore
├── .travis.yml
├── DevOpsHQ_new_project.png
├── LICENSE
├── README.md
├── README_EN.md
├── _config.yml
├── exampleproject
├── Main.py
├── __init__.py
└── __main__.py
├── setup.cfg
├── setup.py
└── tests
├── __init__.py
├── conftest.py
└── test_Main.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 | local_settings.py
56 |
57 | # Flask stuff:
58 | instance/
59 | .webassets-cache
60 |
61 | # Scrapy stuff:
62 | .scrapy
63 |
64 | # Sphinx documentation
65 | docs/_build/
66 |
67 | # PyBuilder
68 | target/
69 |
70 | # Jupyter Notebook
71 | .ipynb_checkpoints
72 |
73 | # pyenv
74 | .python-version
75 |
76 | # celery beat schedule file
77 | celerybeat-schedule
78 |
79 | # SageMath parsed files
80 | *.sage.py
81 |
82 | # dotenv
83 | .env
84 |
85 | # virtualenv
86 | .venv
87 | venv/
88 | ENV/
89 |
90 | # Spyder project settings
91 | .spyderproject
92 | .spyproject
93 |
94 | # Rope project settings
95 | .ropeproject
96 |
97 | # mkdocs documentation
98 | /site
99 |
100 | # mypy
101 | .mypy_cache/
102 |
103 | # JetBrains
104 | .idea/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python: '3.6'
3 | branches:
4 | only: # можно перечислить ветки из которых должен быть автоматический запуск сборки на каждый push кода в репозиторий
5 | - master
6 | - develop
7 | install: # раздел предварительной настройки окружения до сборки
8 | - pip install pytest coverage codacy-coverage # эти библиотеки используются для запуска юнит-тестов сбора статистики покрытия кода юнит-тестами для сервиса Codacy
9 | script: # основной шаг сборки, состоящий из последовательного запуска скриптов
10 | - printenv # для отладки очень помогает вывод переменных окружения в логах Travis CI, потом этот шаг можно удалить
11 | - ls -la # также для отладки, потом этот шаг можно удалить
12 | - coverage run -m py.test tests # собираем покрытие кода тестами
13 | - coverage xml # формируем отчёт для Codacy
14 | - if [[ ! $CODACY_PROJECT_TOKEN ]]; then echo "Variable CODACY_PROJECT_TOKEN not set. Step is skipped."; exit 0; else python-codacy-coverage -r coverage.xml; fi # аплоадим отчёт в Codacy
15 | deploy: # раздел деплоя в котором можно указать действия, которые нужно произвести с успешно собранным артефактом
16 | provider: pypi # например, Travis CI поддерживает автоматическую загрузку в PyPI через указание провайдера "pypi"
17 | user: devopshq # логин проекта в PyPI
18 | password: # зашифрованный пароль для PyPI через утилиту travis-encrypt подставьте в переменную secure ниже:
19 | secure: "e5lg5iPHSMCIpjEGeA0XuJPHaqzwQjLJefIyjQpRNSgf7h9kYwKYI1BH3b8T48QUw6r099QYSgsTJF1pDNWw7rdpTfiXP7pjvr1esmSSr7fyKVeRYNjc/st0n+Blu99At8HEwLXtoLRw2zD92VvTeZA01qRakT0M1bXccT+6pP3FolG5q2HCvzhzImc+Q2FXPSYGgZIYUo28GoYdeVztq+cFwWd27Onx8ROVU0FrVbGQxYS84reiLuI5aCjlv26SJ+5UQREh/RkYnWbogDPSkN+ee+Cl6r+C3WAtf67ac/l++T1ejsv5G+hSyJlWDUrl+2YbTe0ul2b5szo0YY2uW+w+xEJqynGQp6mH0OBm3MCGvEaV8DEnbM94b6PXz1LHi8opWZAGIVSyst+W3w7jwIMU9kUi1leu8jgAcNPUHIC3UhJ7fJrJC4lElOAAn+cdtT5sb6eC4kIOVL3RjCtodeFLAHVWQxeIXnnR07paZPTN8Y4OpYhIY3fcisl5tLnzFnVZ3lf7W9KnAD8mzqxJsPLYEyqAcLxugpEntgL4gRmt/3R4eZz8XRxFvgh3O4m8u38eIwIWyd1FvY9ZfdrkUxfqWdESjz3tU6M4ZDlEVKdsfXtAr2QIxCA/OefprsuQCBtnyc14p1xfe0IiPXTnh5NaeuypZrKw2YaG/nct+tw="
20 | distributions: sdist bdist_wheel # виды артефактов, которые нужно загрузить в PyPY, sdist загружает .tar.gz, bdist_wheel - загружает wheel-файл
21 | on:
22 | all_branches: true
23 | skip_cleanup: true
24 | after_script: # команды которые нужно выполнить после успешного окончания сборки и деплоя
25 | - echo "Deploy to PyPI finished."
26 | env:
27 | global: # здесь можно разместить общие переменные и секреты доступные для всех шагов сборки. Yапример, секрет для Codacy, зашифрованный через утилиту travis-encrypt подставьте в переменную secure ниже:
28 | - secure: "ZGjMqDQ7BE2Y/Aago40EpeRJWGM4SRt4PWmfFsRiDKJpkcXOpD+VXTDPHeCNVPrTg1O0PMVzfoEJAi1ST1ZnlJDmufelk9WjtZJFx5grUVAldcODrBQS7yuE5Ck9COExagHvQOmhu4G0EMnxxL1fv5UEc3ef+4513ve1YaKNctE8CjnTV1XCdaazKuDGBB49wuax7DynN/5D0hQYHw5rsxhwHY4YB4IXkjB74rTcp6tYF6FtFrhWioQ+K1aJOcfeqcwPjPGpY7VySmkh/iTxwAtkTrltVN3j9D2F5X276XEW5kFWm9B0x3ytztNkmJk0BSWH2za5QbhrOmRtIml52XnQVWWwDLUV7WgOpGiMEhdcvdlXA5i82uahSUL1svBfR4AQ8uI+e7NdTVkVHY5GvTq+Gd7u8Bp0QPenwMEif62mIZVVTk7IMq99JLLYAEE39K64rTZAivCaEqrfbX1ObMjyaMCeGP1Nu9evsEOM8DOsh8hMDU01gxSLUZFS0q+CKnRBsXEKhxtlNo6Wur260b23rJMrDeii2Q94OUmMbqus9qjZ8hwv5QEgDZgluZyOJsM1wLBqyn41FSBv3j7AiqA0o4RcROlg/paePBhX5NA1DpC1SOVs/E6P9Sio6vwvgQz28+oQ5tsw2jNxjM6cmzEpZFKj9Fe56IYA7pPi3tI="
29 |
--------------------------------------------------------------------------------
/DevOpsHQ_new_project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devopshq/ExampleProject/de6db39c1695d1e8e8eaec5eff019c3c69430912/DevOpsHQ_new_project.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Open DevOps Community
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ExampleProject
2 | ==============
3 | This is simple example of project in DevOpsHQ Community with basic functionality.
4 | See english instruction here: https://github.com/devopshq/ExampleProject/blob/master/README_EN.md
5 |
6 | [](https://travis-ci.org/devopshq/ExampleProject) [](https://www.codacy.com/app/tim55667757/ExampleProject/dashboard) [](https://www.codacy.com/app/tim55667757/ExampleProject/dashboard) [](https://pypi.python.org/pypi/dohq-example-project) [](https://github.com/devopshq/ExampleProject/blob/master/LICENSE)
7 |
8 | ***Содержание:***
9 | - [Введение](#Introduction)
10 | - [Подготовка репозитория](#Preparing-repo)
11 | - [Подготовка документации](#Preparing-doc)
12 | - [Оценка качества кода](#Codacy)
13 | - [Подготовка автоматической сборки в Travis CI](#Travis-CI)
14 | - [Разработка сборочного скрипта setup.py](#Setup)
15 | - [Настройка конфигурации в .travis.yml](#Configuration)
16 | - [Подготовка и настройка репозитория в PyPI](#PyPI)
17 | - [Публикация новости о релизе в Telegram-канале DevOpsHQ](#News)
18 | - [Проверка тестового проекта](#Testing)
19 |
20 |
21 | # Введение
22 |
23 | **ExampleProject** — это пример простого проекта в собществе DevOpsHQ с базовой функциональностью. Документация содержит в себе примеры и рекомендации для самостоятельной организации сборки любого нового проекта в сообществе DevOpsHQ. Сам проект — имеет типовую структуру и сборку в Travis CI. Фактически, достаточно скопировать этот проект и заменить некоторые настройки, руководствуясь комментариями ниже.
24 |
25 | Подготовка любого нового проекта состоит из шагов, представленных на схеме ниже:
26 |
27 | 
28 |
29 |
30 | # Подготовка репозитория
31 |
32 | 1. Обсудить и согласовать с [Timur Gilmullin](https://github.com/Tim55667757), [Aleksey Burov](https://github.com/orgs/devopshq/people/allburov) или [Alexander Pazdnikov](https://github.com/apazdnikov) выкладку нового проекта в https://github.com/devopshq. После этого будет создан и настроен репозиторий и типовые группы доступа, выданы права owner на проект.
33 |
34 | 2. В настройках проекта (Settings) в разделе Options разрешается подключать только фичу (в разделе Features) Issue. Wikis и Projects в проектах на GitHub в сообществе DevOpsHQ мы не ведём.
35 |
36 | 3. Там же в настройках проекта в разделе Branches выбираем дефолтовую ветку master.
37 |
38 | 4. На вкладке проекта Issues в разделе Labels создаём только две метки: **Error** и **Task**, остальные удаляем. Milestones создавайте на своё усмотрение, например, если у вас планируется крупная фича к разработке, состоящая из множества зависимых тасков.
39 |
40 | 5. Юнит-тесты формата pytest должны располагаться в каталоге **./tests** в корне проекта.
41 |
42 | 6. При инициализации репозитория следует использовать только **MIT-лицензию** под именем **LICENSE** следующего содержания (обновив год):
43 |
44 | ```
45 | MIT License
46 |
47 | Copyright (c) 2017 Open DevOps Community
48 |
49 | Permission is hereby granted, free of charge, to any person obtaining a copy
50 | of this software and associated documentation files (the "Software"), to deal
51 | in the Software without restriction, including without limitation the rights
52 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
53 | copies of the Software, and to permit persons to whom the Software is
54 | furnished to do so, subject to the following conditions:
55 |
56 | The above copyright notice and this permission notice shall be included in all
57 | copies or substantial portions of the Software.
58 |
59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
65 | SOFTWARE.
66 | ```
67 |
68 |
69 | ## Подготовка документации
70 |
71 | 1. Документация к проекту на английском языке должна вестись в файле **README.md** формата **markdown**, который должен располагаться в корне репозитория в каждой ветке. Версионирование и изменения в документацию вносятся как в обычный код, вместе с отдельными комитами в соответствующую ветку. Документация на русском ведётся аналогично в файле **README_RUS.md**.
72 |
73 | 2. На вкладке Settings проекта в разделе Options подключаем [GitHub Pages сервис](https://pages.github.com/):
74 | * В качестве Source выбираем master branch. То есть, актуальная документация всегда будет браться для сайта на GitHub Pages из этой ветки.
75 | * В пункте Theme chooser нажимаете кнопку Change theme и выбираете любую понравившуюся тему для сайта с документацией. Обычно в DevOpsHQ мы используем "Hacker theme".
76 |
77 | После этого в ветке master в корне репозитория будет создан файл с настройками для GitHub Pages **_config.yml**.
78 |
79 | 3. Если документация объёмная (больше одной страницы или экрана текста), то рекомендуется добавить в неё содержание со ссылками.
80 |
81 | [Markdown](https://ru.wikipedia.org/wiki/Markdown) (маркдаун) — облегчённый язык разметки, созданный с целью написания максимально читаемого и удобного для правки текста, но пригодного для преобразования в языки для продвинутых публикаций (HTML, Rich Text и др.).
82 |
83 | Для работы с ним есть множество онлайн-инструментов, в том числе с инструкцией по правильной разметке текста, например:
84 | * [Dillinger](http://dillinger.io/) — в этом онлайн-редакторе можно на лету форматировать markdown-файлы и смотреть результат визуализации разметки.
85 |
86 | Также и GitHub поддерживает автоматическое отображение README.md файлов в формате markdown.
87 |
88 | В маркдаун-документацию можно добавлять индекс (оглавление) на внутренние якоря в документе. При этом ссылки в таком оглавлении будут кликабельными, как в обычном html-документе. Это полезно для больших markdown-документов.
89 |
90 | Для того, чтобы сделать оглавление:
91 |
92 | 1. Пишем в оглавлении ссылку вида:
93 |
94 | **\[HEADER\](#anchor_name)**
95 |
96 | 2. Рядом с нужным местом (заголовком) в документе добавляем обычный html-якорь:
97 |
98 | **\\ HEADER**
99 |
100 | Альтернативный вариант:
101 |
102 | 1. Пишем в оглавлении ссылку вида:
103 |
104 | **\[Long Header\](#long-header)**
105 |
106 | 2. В тексте заголовок должен быть такой же, как в квадратных скобках выше:
107 |
108 | **Long Header**
109 |
110 |
111 | ***Дополнительно:***
112 |
113 | Как реализовать подсветку синтаксиса: https://help.github.com/articles/creating-and-highlighting-code-blocks/
114 |
115 | Полный список алиасов для языков программирования: https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
116 |
117 |
118 |
119 | ## Оценка качества кода
120 |
121 | Качество кода автоматически отслеживается [сервисом Codacy](https://www.codacy.com/). Для его настройки:
122 |
123 | 1. Авторизуйтесь со своей GitHub-учёткой, или учёткой, созданной в самом сервисе: https://www.codacy.com/
124 |
125 | 2. Нажмите кнопку Add project.
126 |
127 | 3. Выберете проект из списка или добавьте URL на код в GitHub-е.
128 |
129 | 4. После обработки проекта он появится на дашборде.
130 |
131 | 5. Настройка автоматического подсчёта покрытия кода тестами (Coverage) будет реализована позже в разделе про Travis CI сборки.
132 |
133 | 5. Перейдите в настройки проекта (кнопка settings в меню слева) и скопируйте Codacy Badge для проекта в формате markdown. Это ссылка на оценку качества кода.
134 |
135 | 7. Вставьте ссылку на значок с оценкой качества кода в документацию README.md в самом начале, сразу после заголовка с названием проекта. Она должна иметь вид, похожий на этот:
136 |
137 | \[\](https://www.codacy.com/app/**tim55667757/FuzzyClassificator**/dashboard)
138 |
139 | Выделенное длинное число — это код значка для проекта в Codacy (можно узнать в настройках Settings - General - Codacy Badge), а выделенная часть ссылки — это ваш логин и имя проекта в Codacy.
140 |
141 | 8. После того, как любая сборка запушит первый раз данные по тестовому покрытию, можно также вставить ссылку на значок с оценкой покрытия кода тестами. Ссылка должна иметь вид, похожий на этот:
142 |
143 | \[\](https://www.codacy.com/app/**tim55667757/FuzzyClassificator**/dashboard)
144 |
145 | Выделенное длинное число — это код проекта в Codacy (его можно узнать в настройках Settings — General — Codacy Badge), а выделенная часть ссылки — это ваш логин и имя проекта в Codacy.
146 |
147 |
148 | # Подготовка автоматической сборки в Travis CI
149 |
150 | Подготовка сборки python-кода в [Travis CI](https://travis-ci.org/devopshq) состоит из нескольких основных шагов:
151 |
152 | * разработки сборочного скрипта **setup.py** (для стандартного сборщика python из библиотеки setuptools),
153 | * настройки конфигурации в **.travis.yml** (стандартный файл конфигурации для Travis CI),
154 | * настройки **репозитория в PyPI**.
155 |
156 | Для начала работы с Travis CI включите интеграцию в вашем GitHub проекте: для этого перейдите в Travis CI по ссылке https://travis-ci.org/profile/devopshq и включите интеграцию вашего нового проекта с GitHub. Для этой операции необходимы админские права в сообществе DevOpsHQ.
157 |
158 |
159 | ## Разработка сборочного скрипта setup.py
160 |
161 | Скрипт **setup.py** используется стандартным сборщиком python из библиотеки setuptools для обеспечения локальной сборки инструмента в пакет. Обычно, для локального билда и установки вашего инструмента в библиотеки локального python используют команду: python setup.py install. Этот же самый принцип использует Travis CI для обеспечения сборки и дальнейшей упаковки пакета, например, в .tar.gz или wheel-файл и загрузки в PyPI.
162 |
163 | Добавьте файлы **setup.py** и **setup.cfg** в корень своего репозитория. А также добавьте пустой файл **\_\_init\_\_.py** в каталог со скриптами, который вы хотите сделать пакетом и который после сборки можно будет импортировать в других проектах.
164 |
165 | В **setup.cfg** достаточно добавить две строчки, с указанием того, где искать документацию:
166 |
167 | [metadata]
168 | description-file = README.md
169 |
170 | Ниже представлен готовый **пример файла setup.py** с минимальным набором настроек для локальной сборки пакета. Внимательно читайте комментарии. Достаточно скопировать его к себе и он должен заработать с небольшими исправлениями:
171 |
172 | ```python
173 | #!/usr/bin/env python
174 | # -*- coding: utf-8 -*-
175 |
176 |
177 | from setuptools import setup
178 | import os
179 |
180 | __version__ = '1.0' # Здесь можно менять глобальный мажор.минор вашего инструмента. Итоговая версия после сборки будет выглядеть так: [major.minor].[build] для релизных сборок и [major.minor.dev]build для нерелизных.
181 | # В дальнейшем узнать версию вашего установленного инструмента внутри программы возможно используя метод, аналогичный этому:
182 | # https://github.com/devopshq/FuzzyClassificator/blob/master/FuzzyClassificator.py#L27
183 | # import pkg_resources # часть стандартной библиотеки setuptools
184 | # version = pkg_resources.get_distribution('YourProject').version
185 |
186 | devStatus = '4 - Beta' # Билд-статус по умолчанию, смотрите: https://pypi.python.org/pypi?%3Aaction=list_classifiers
187 |
188 | # Логика версионирования в зависимости от веток настраивается ниже:
189 | if 'TRAVIS_BUILD_NUMBER' in os.environ and 'TRAVIS_BRANCH' in os.environ:
190 | print("This is TRAVIS-CI build")
191 | print("TRAVIS_BUILD_NUMBER = {}".format(os.environ['TRAVIS_BUILD_NUMBER']))
192 | print("TRAVIS_BRANCH = {}".format(os.environ['TRAVIS_BRANCH']))
193 |
194 | __version__ += '.{}{}'.format(
195 | '' if 'release' in os.environ['TRAVIS_BRANCH'] or os.environ['TRAVIS_BRANCH'] == 'master' else 'dev',
196 | os.environ['TRAVIS_BUILD_NUMBER'],
197 | )
198 |
199 | devStatus = '5 - Production/Stable' if 'release' in os.environ['TRAVIS_BRANCH'] or os.environ['TRAVIS_BRANCH'] == 'master' else devStatus
200 |
201 | else:
202 | print("This is local build")
203 | __version__ += '.dev0' # set version as major.minor.localbuild if local build: python setup.py install
204 |
205 | print("YourProject build version = {}".format(__version__)) # Перед сборкой выведется сообщение о том, какая версия собирается
206 |
207 | # Это основной раздел настроек setuptools для сборки вашей программы
208 | setup(
209 | name='YourProject', # имя проекта под которым люди будут искать вашу программу в PyPI и инсталлить через "pip install YourProject"
210 |
211 | version=__version__,
212 |
213 | description='Short description of your project.', # короткое описание проекта - отображается рядом с пакетом в PyPI
214 |
215 | long_description='You can see detailed user manual here: https://devopshq.github.io/YourProject/', # подробная документация должна быть доступна в GitHub Pages по этой ссылке
216 |
217 | license='MIT', # только MIT лицензия для Open DevOps Community
218 |
219 | author='Open DevOps Community', # укажите имя основного автора, либо укажите Open DevOps Community
220 |
221 | author_email='tim55667757@gmail.com', # е-mail автора либо ссылка на Open DevOps Community
222 |
223 | url='https://devopshq.github.io/YourProject/', # сюда пишем ссылку на GitHub Pages или другой сайт с документацией
224 |
225 | download_url='https://github.com/devopshq/YourProject.git', # здесь указываем ссылку на проект в GitHub
226 |
227 | entry_points={'console_scripts': ['MainScript = MainScript:Main']}, # Точка входа указывает на основной метод, который нужно запустить при запуске программы из консоли. Например, если основной модуль называется MainScript, то в данном примере будет запущен метод Main() этого скрипта, если вы наберёте в консоли команду "MainScript".
228 |
229 | classifiers=[ # все допустимые классификаторы для PyPI подробно перечислены на страничке: https://pypi.python.org/pypi?%3Aaction=list_classifiers
230 | 'Development Status :: {}'.format(devStatus),
231 | 'Environment :: Console',
232 | 'Intended Audience :: Science/Research',
233 | 'Topic :: Scientific/Engineering :: Artificial Intelligence',
234 | 'License :: OSI Approved :: MIT License',
235 | 'Natural Language :: English',
236 | 'Programming Language :: Python :: 3.6',
237 | ],
238 |
239 | keywords=[ # перечислите все ключевые слова, которые ассоциируются с вашим инструментом, каждое слово отдельной записью
240 | 'keyword 1',
241 | 'keyword 2',
242 | ],
243 |
244 | packages=[ # необходимо перечислить ВСЕ каталоги с пакетами, если они присутствуют в вашем проекте, либо оставить '.', что будет указывать на то, что корень проекта сам является пакетом (в корне должен быть __init__.py)
245 | '.',
246 | ],
247 |
248 | setup_requires=[ # необходимо перечислить ВСЕ библиотеки, от которых зависит сборка вашего инструмента
249 | ],
250 |
251 | tests_require=[ # необходимо перечислить ВСЕ библиотеки, которые должны быть установлены для запуска тестов
252 | 'pytest',
253 | ],
254 |
255 | install_requires=[ # необходимо перечислить ВСЕ библиотеки, от которых зависит ваш инструмент (requirements), кроме стандартных библиотек, и они будут установлены автоматически при установке вашего инструмента
256 | ],
257 |
258 | package_data={ # необходимо перечислить ВСЕ файлы, которые должны войти в итоговый пакет, например:
259 | '': [
260 | './someothermodule/*.py', # если проект содержит другие модули, их и все входящие в них файлы тоже нужно перечислить
261 |
262 | './tests/*.py', # все юнит-тесты, если вы хотите, чтобы люди могли их запускать после установки вашей библиотеки
263 | 'MainScript.py', # основной скрипт вашего приложения и все остальные файлы должны быть указаны аналогично
264 |
265 | 'LICENSE', # файл лицензии нужно добавить в пакет
266 | 'README.md', # файл документации нужно добавить в пакет
267 | ],
268 | },
269 |
270 | zip_safe=True,
271 | )
272 | ```
273 |
274 | После разработки скрипта зарегистрируйте новый проект в PyPI (учётку devopshq могут использовать админы сообщества):
275 |
276 | python setup.py register -r pypi
277 |
278 | ***Дополнение:*** *похоже, что это уже не требуется, т.к. PyPI выдаёт на попытку зарегистрировать проект: Server response (410): Project pre-registration is no longer required or supported, so continue directly to uploading files.*
279 |
280 |
281 | ## Настройка конфигурации в .travis.yml
282 |
283 | Travis CI сервис ищет конфигурацию шагов сборки в стандартном файле **.travis.yml**. Описание его разделов подробно описано в родной документации: https://docs.travis-ci.com/user/customizing-the-build.
284 |
285 | 1. Добавьте файл **.travis.yml** в корень репозитория.
286 |
287 | 2. В конфигурационном файле используются учётные данные. Их потребуется зашифровать при помощи утилиты **[travis-encrypt](https://pypi.python.org/pypi/travis-encrypt)**. Установите её для вашего python:
288 |
289 |
290 | pip install travis-encrypt
291 |
292 | 3. Сгенерируйте секретку для деплойного ключа для загрузки артефакта сборки вашего проекта в PyPI командой ниже (потребуется учётка админов devopshq). Длинную строку секретки нужно будет подставить в файл **.travis.yml** в разделе deploy (смотри в примере ниже).
293 |
294 |
295 | travis-encrypt devopshq [имя репозитория проекта в GitHub, например, crosspm]
296 |
297 | 4. Добавьте интеграцию с сервисом Codacy:
298 | * Перейдите в настройки проекта в Codacy: Settings — Integrations, нажмите "Add integrations" и выберете "Project API".
299 | * В добавленной интеграции будет строка "Project API Token" с токеном проекта в Codacy.
300 |
301 | 5. Сгенерируйте секретку для авторизации в сервисе Codacy командой ниже. После ввода команды вы увидите длинную зашифрованную строку секретки. Эту строку нужно будет подставить в файл **.travis.yml** в разделе env (смотри в примере ниже).
302 |
303 |
304 | travis-encrypt --env --password CODACY_PROJECT_TOKEN=[длинное число с токеном проекта в Codacy] devopshq [имя репозитория проекта в GitHub, например, crosspm]
305 |
306 | Ниже представлен пример файла конфигурации **.travis.yml** с минимальным набором типичных шагов сборки в Travis CI для небольших и простых проектов. Достаточно скопировать его к себе, добавить юнит-тесты в ./tests, заменить ключи secure и он должен подойти, либо с минимальными доработками:
307 |
308 | ```YAML
309 | language: python
310 | python: '3.6'
311 | branches:
312 | only: # можно перечислить ветки из которых должен быть автоматический запуск сборки на каждый push кода в репозиторий
313 | - master
314 | - develop
315 | install: # раздел предварительной настройки окружения до сборки
316 | - pip install pytest coverage codacy-coverage # эти библиотеки используются для запуска юнит-тестов сбора статистики покрытия кода юнит-тестами для сервиса Codacy
317 | script: # основной шаг сборки, состоящий из последовательного запуска скриптов
318 | - printenv # для отладки очень помогает вывод переменных окружения в логах Travis CI, потом этот шаг можно удалить
319 | - ls -la # также для отладки, потом этот шаг можно удалить
320 | - coverage run -m py.test tests # собираем покрытие кода тестами
321 | - coverage xml # формируем отчёт для Codacy
322 | - if [[ ! $CODACY_PROJECT_TOKEN ]]; then echo "Variable CODACY_PROJECT_TOKEN not set. Step is skipped."; exit 0; else python-codacy-coverage -r coverage.xml; fi # аплоадим отчёт в Codacy
323 | deploy: # раздел деплоя в котором можно указать действия, которые нужно произвести с успешно собранным артефактом
324 | provider: pypi # например, Travis CI поддерживает автоматическую загрузку в PyPI через указание провайдера "pypi"
325 | user: devopshq # логин проекта в PyPI
326 | password: # зашифрованный пароль для PyPI через утилиту travis-encrypt
327 | secure: "скопируйте сюда длинную зашифрованную строку с паролем для PyPI, полученную через утилиту travis-encrypt"
328 | distributions: sdist bdist_wheel # виды артефактов, которые нужно загрузить в PyPY, sdist загружает .tar.gz, bdist_wheel - загружает wheel-файл
329 | on:
330 | all_branches: true
331 | skip_cleanup: true
332 | after_script: # команды которые нужно выполнить после успешного окончания сборки и деплоя
333 | - echo "Deploy to PyPI finished."
334 | env:
335 | global: # здесь можно разместить общие переменные и секреты доступные для всех шагов сборки, например, секрет для Codacy, зашифрованный через утилиту travis-encrypt
336 | - secure: "скопируйте сюда длинную зашифрованную строку с секретом для Codacy, полученную через утилиту travis-encrypt"
337 | ```
338 |
339 |
340 | ## Подготовка и настройка репозитория в PyPI
341 |
342 | После того, как в репозиторий был добавлен файл **.travis.yml** и включена интеграция с ним в Travis CI:
343 |
344 | 1. Логинимся в PyPI с учёткой devopshq (доступ к ней у админов DevOpsHQ): https://pypi.python.org
345 |
346 | 2. Справа в меню ищем ранее зарегистрированный проект, кликаем на его имя и на открывшейся странице кликаем на меню roles этого проекта.
347 |
348 | 3. Для Package Name вашего нового проекта небходимо добавить минимальную роль **Maintainer** для пользователя **devopshq**, чтобы Travis CI мог аплоадить артефакты в PyPI-репозиторий.
349 |
350 |
351 | # Публикация новости о релизе в Telegram-канале DevOpsHQ
352 |
353 | Канал сообщества: https://t.me/devopshq. Для публикации в него новости о новой фича или релизной сборке существует чат-бот @devops_mega_bot. Отправлять в канал новости могут админы сообщества DevOpsHQ:
354 |
355 | 1. Обратитесь к [Alexander Kovalev](https://github.com/alkovpro), чтобы он добавил боту опции для работы с новым инструментом.
356 |
357 | 2. После этого в любом чате Telegram станет доступна команда, которая выдаст последнюю версию собранного инструмента в PyPI:
358 |
359 |
360 | @devops_mega_bot [название вашего инструмента]
361 |
362 | 3. После этого можно в канале сообщества опубликовать запись о новой версии и добавить информацию в произвольном виде: что вошло в новую сборку, какие фичи добавлены, какие баги исправлены и т.п.
363 |
364 |
365 | # Проверка тестового проекта
366 |
367 | Чтобы убедиться, что данный тестовый проект **ExampleProject** работает, попробуйте установить его из PyPI:
368 |
369 | pip install dohq-example-project [--upgrade] [--pre]
370 |
371 | В случае успеха установки вы увидите что-то вроде:
372 |
373 | ```Shell
374 | pip install dohq-example-project --upgrade
375 |
376 | Collecting dohq-example-project
377 | Downloading dohq_example_project-1.0.11-py3-none-any.whl
378 | Installing collected packages: dohq-example-project
379 | Found existing installation: dohq-example-project 1.0.dev3
380 | Uninstalling dohq-example-project-1.0.dev3:
381 | Successfully uninstalled dohq-example-project-1.0.dev3
382 | Successfully installed dohq-example-project-1.0.11
383 | ```
384 |
385 | Запустите тестовый проект:
386 |
387 | exampleproject
388 |
389 | или
390 |
391 | [python_directory]/Scripts/exampleproject
392 |
393 | и вы должны увидеть что-то вроде:
394 |
395 | ```Shell
396 | This is Main module for ExampleProject that do nothing.
397 | Read more about DevOpsHQ Community here: https://github.com/devopshq/ExampleProject
398 | Version of ExampleProject is [ 1.0.11 ]
399 | ```
400 |
401 | Также можно проверить информацию в pip:
402 |
403 | pip show dohq-example-project
404 |
405 | после чего вы должны увидеть что-то вроде:
406 |
407 | ```Shell
408 | Name: dohq-example-project
409 | Version: 1.0.11
410 | Summary: About Example Project: https://github.com/devopshq/ExampleProject
411 | Home-page: https://devopshq.github.io/ExampleProject/
412 | Author: Open DevOps Community
413 | Author-email: tim55667757@gmail.com
414 | License: MIT
415 | Location: c:\anaconda3\lib\site-packages
416 | Requires:
417 | ```
418 |
419 | Аналогично вы можете проверить установку вашего проекта, сделанного на основе данного шаблона.
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | ExampleProject
2 | ==============
3 | This is simple example of project in DevOpsHQ Community with basic functionality.
4 | See full russian instruction here: https://github.com/devopshq/ExampleProject/blob/master/README.md
5 |
6 | [](https://travis-ci.org/devopshq/ExampleProject) [](https://www.codacy.com/app/tim55667757/ExampleProject/dashboard) [](https://www.codacy.com/app/tim55667757/ExampleProject/dashboard) [](https://pypi.python.org/pypi/dohq-example-project) [](https://github.com/devopshq/ExampleProject/blob/master/LICENSE)
7 |
8 |
9 | ***... Soon there will be a translation of the Russian instruction ...***
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/exampleproject/Main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | # This is Main module for ExampleProject that do nosting.
5 |
6 |
7 | def Main():
8 | """
9 | This is Main method that do nosting.
10 | """
11 | return "This is Main module for ExampleProject that do nothing.\nRead more about DevOpsHQ Community here: https://github.com/devopshq/ExampleProject"
12 |
13 |
14 | if __name__ == "__main__":
15 | print(Main())
16 |
17 | import pkg_resources # part of standart setuptools
18 | print("Version of ExampleProject is [ {} ]".format(pkg_resources.get_distribution('dohq-example-project').version))
19 |
--------------------------------------------------------------------------------
/exampleproject/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devopshq/ExampleProject/de6db39c1695d1e8e8eaec5eff019c3c69430912/exampleproject/__init__.py
--------------------------------------------------------------------------------
/exampleproject/__main__.py:
--------------------------------------------------------------------------------
1 | from exampleproject.Main import Main
2 |
3 | if __name__ == "__main__":
4 | print(Main())
5 |
6 | import pkg_resources # part of standart setuptools
7 | print("Version of ExampleProject is [ {} ]".format(pkg_resources.get_distribution('dohq-example-project').version))
8 |
9 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description-file = README.md
3 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | from setuptools import setup
6 | import os
7 |
8 | __version__ = '1.0' # Здесь можно менять глобальный мажор.минор вашего инструмента. Итоговая версия после сборки будет выглядеть так: [major.minor].[build] для релизных сборок и [major.minor.dev]build для нерелизных.
9 | # В дальнейшем узнать версию вашего установленного инструмента внутри программы возможно используя метод, аналогичный этому:
10 | # https://github.com/devopshq/FuzzyClassificator/blob/master/FuzzyClassificator.py#L27
11 | # import pkg_resources # часть стандартной библиотеки setuptools
12 | # version = pkg_resources.get_distribution('YourProject').version
13 |
14 | devStatus = '4 - Beta' # Билд-статус по умолчанию, смотрите: https://pypi.python.org/pypi?%3Aaction=list_classifiers
15 |
16 | # Логика версионирования в зависимости от веток настраивается ниже:
17 | if 'TRAVIS_BUILD_NUMBER' in os.environ and 'TRAVIS_BRANCH' in os.environ:
18 | print("This is TRAVIS-CI build")
19 | print("TRAVIS_BUILD_NUMBER = {}".format(os.environ['TRAVIS_BUILD_NUMBER']))
20 | print("TRAVIS_BRANCH = {}".format(os.environ['TRAVIS_BRANCH']))
21 |
22 | __version__ += '.{}{}'.format(
23 | '' if 'release' in os.environ['TRAVIS_BRANCH'] or os.environ['TRAVIS_BRANCH'] == 'master' else 'dev',
24 | os.environ['TRAVIS_BUILD_NUMBER'],
25 | )
26 |
27 | devStatus = '5 - Production/Stable' if 'release' in os.environ['TRAVIS_BRANCH'] or os.environ['TRAVIS_BRANCH'] == 'master' else devStatus
28 |
29 | else:
30 | print("This is local build")
31 | __version__ += '.dev0' # set version as major.minor.localbuild if local build: python setup.py install
32 |
33 | print("ExampleProject build version = {}".format(__version__)) # Перед сборкой выведется сообщение о том, какая версия собирается
34 |
35 | # Это основной раздел настроек setuptools для сборки вашей программы
36 | setup(
37 | name='dohq-example-project', # имя проекта под которым люди будут искать вашу программу в PyPI и инсталлить через "pip install dohq-example-project"
38 |
39 | version=__version__,
40 |
41 | description='About Example Project: https://github.com/devopshq/ExampleProject', # короткое описание проекта - отображается рядом с пакетом в PyPI
42 |
43 | long_description='GitHub Pages: https://devopshq.github.io/ExampleProject/', # подробная документация должна быть доступна в GitHub Pages по этой ссылке
44 |
45 | license='MIT', # только MIT лицензия для Open DevOps Community
46 |
47 | author='Open DevOps Community', # укажите имя основного автора, либо укажите Open DevOps Community
48 |
49 | author_email='tim55667757@gmail.com', # е-mail автора либо ссылка на Open DevOps Community
50 |
51 | url='https://devopshq.github.io/ExampleProject/', # сюда пишем ссылку на GitHub Pages или другой сайт с документацией
52 |
53 | download_url='https://github.com/devopshq/ExampleProject.git', # здесь указываем ссылку на проект в GitHub
54 |
55 | entry_points={'console_scripts': ['exampleproject = exampleproject.Main:Main']}, # Точка входа указывает на основной метод, который нужно запустить при запуске программы из консоли. Например, если основной модуль в пакете exampleproject называется Main, то в данном примере будет запущен метод Main() этого скрипта, если вы наберёте в консоли команду "exampleproject".
56 |
57 | classifiers=[ # все допустимые классификаторы для PyPI подробно перечислены на страничке: https://pypi.python.org/pypi?%3Aaction=list_classifiers
58 | 'Development Status :: {}'.format(devStatus),
59 | 'Environment :: Console',
60 | 'Intended Audience :: Developers',
61 | 'Topic :: Utilities',
62 | 'License :: OSI Approved :: MIT License',
63 | 'Natural Language :: Russian',
64 | 'Programming Language :: Python :: 3.6',
65 | ],
66 |
67 | keywords=[ # перечислите все ключевые слова, которые ассоциируются с вашим инструментом, каждое слово отдельной записью
68 | 'exampleproject',
69 | 'PyPI',
70 | 'DevOpsHQ',
71 | 'devops',
72 | ],
73 |
74 | packages=[ # необходимо перечислить ВСЕ каталоги с пакетами, если они присутствуют в вашем проекте, либо оставить '.', что будет указывать на то, что корень проекта сам является пакетом (в корне должен быть __init__.py)
75 | 'exampleproject',
76 | ],
77 |
78 | setup_requires=[ # необходимо перечислить ВСЕ библиотеки, от которых зависит сборка вашего инструмента
79 | ],
80 |
81 | tests_require=[ # необходимо перечислить ВСЕ библиотеки, которые должны быть установлены для запуска тестов
82 | 'pytest',
83 | ],
84 |
85 | install_requires=[ # необходимо перечислить ВСЕ библиотеки, от которых зависит ваш инструмент (requirements), кроме стандартных библиотек, и они будут установлены автоматически при установке вашего инструмента
86 | ],
87 |
88 | package_data={ # необходимо перечислить ВСЕ файлы, которые должны войти в итоговый пакет, например:
89 | '': [
90 | './exampleproject/*.py', # если проект содержит другие модули, их и все входящие в них файлы тоже нужно перечислить
91 |
92 | './tests/*.py', # все юнит-тесты, если вы хотите, чтобы люди могли их запускать после установки вашей библиотеки
93 |
94 | 'LICENSE', # файл лицензии нужно добавить в пакет
95 | 'README.md', # файл документации нужно добавить в пакет
96 | 'README_EN.md', # файл документации на английском нужно также добавить в пакет
97 | ],
98 | },
99 |
100 | zip_safe=True,
101 | )
102 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devopshq/ExampleProject/de6db39c1695d1e8e8eaec5eff019c3c69430912/tests/__init__.py
--------------------------------------------------------------------------------
/tests/conftest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | def pytest_sessionstart(session):
5 |
6 | print("This is pre-test part example.")
7 |
--------------------------------------------------------------------------------
/tests/test_Main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | import pytest
5 | from exampleproject import Main
6 |
7 |
8 | class TestMain():
9 |
10 | @pytest.fixture(scope='class', autouse=True)
11 | def init(self):
12 | print("This is start of test example.")
13 |
14 | def test_Main(self):
15 | assert Main.Main() == "This is Main module for ExampleProject that do nothing.\nRead more about DevOpsHQ Community here: https://github.com/devopshq/ExampleProject"
16 |
--------------------------------------------------------------------------------