Hola Habr! Mi nombre es Artyom Zheltak , soy líder de equipo y también profesor en el curso "Desarrollador de Golang" en OTUS. En previsión del inicio de una nueva secuencia del curso , quiero compartir mi artículo con usted.
Creo que Golang es genial, pero todavía hay muchos proyectos de php y otros trabajando en VPS, VDS en el mundo. Puede colocar una ventana acoplable allí, pero esto (según el autor) es una nueva complicación de la tarea. Puede compilar un archivo y cargarlo a través de FTP: es inseguro y no es feng shui, SFTP es más seguro, pero no lo haga de nuevo. Entonces automaticemos este proceso a través de
CircleCI . Escribiremos el archivo de configuración para CI paso a paso, al final recopilaremos el resultado y ejecutaremos el despliegue.

Requisitos de implementación
- Mínimas innovaciones de servidor
- La implementación debe ser automatizada
- El punto de entrada para la implementación es el etiquetado para el ensamblaje de desarrollo y la confirmación manual adicional para prod
- El ensamblaje debe pasar la prueba automática
- Versión de mecanismo de retroceso manual
¿Por qué CircleCI?
Desde el principio, el proyecto utilizó un repositorio privado de bitbucket. (Ahora los repositorios privados ya están en el github.) Sin abandonar el ecosistema, Atlasian decidió tomar CircleCI (en adelante, CI). Me gustó eso:
- ajuste mínimo
- función de depuración ssh
- versión gratuita pero con limitaciones
- 2500 créditos / por semana (aproximadamente 250 minutos de finalización) #go se recopila y se implementa rápidamente, tenemos suficiente
- ejecución de un solo subproceso # no tenemos muchos proyectos de mascotas
- solo linux y windows # necesitamos linux
Primera parte, flujo de trabajo
Cree una carpeta .circle y cree un archivo config.yml en ella y describa el flujo de trabajo esperado allí (el orden de ejecución de la tarea)
workflows: version: 2 tagged-build: jobs: - test - dev_deploy: requires: - test - approve_master_deploy: type: approval requires: - test - dev_deploy - prod_deploy: requires: - dev_deploy - approve_master_deploy
Aquí está el resultado:

Describimos un patrón según el cual cada confirmación se verificará primero mediante pruebas, luego se implementará en dev, luego, con confirmación manual, se enviará al servidor de batalla. Para guiar el brillo, agregue un filtro para que la tarea funcione solo por etiqueta.
- dev_deploy: requires: - test filters: branches: ignore: /.*/ tags: only: /.*/
El segundo paso, el más fácil.
Comencemos ejecutando las pruebas, habrá un mínimo de código.
jobs: test: docker: - image: circleci/golang:1.12 working_directory: ~/go-example/ steps: - checkout # linter' - run: go test -cover -v ./...
Después de que nuestro código haya sido probado y aprobado las comprobaciones de estilo de código, puede implementarlo en dev. Sugiero usar el supervisor (ver 3.1.4 en el momento de la redacción) para comenzar el servicio go, recopilaremos registros para ellos.
Agregue el archivo supervisor_ph.conf a la carpeta .circleci, dentro de CI PH_NAME cambiará al nombre del proyecto. Y en el mismo archivo escribiremos la salida de los registros.
[program:PH_NAME] stopasgroup=true user=deploy-user autostart=true autorestart=true stdout_logfile=/var/log/supervisor/PH_NAME.log stderr_logfile=/var/log/supervisor/PH_NAME.log redirect_stderr=true
Todo lo que distingue nuestro proyecto de los demás:

Tiempo de implementación
Para dev y prod, solo se cambian los servidores y se agrega un sufijo al nombre de la aplicación. La configuración se almacena en variables de entorno. (
Aplicaciones de 12 factores ) Llevaremos esta parte al medio ambiente, duplicaremos el resto.
prod_deploy: environment: TARGET_IP: 0.0.0.0 TARGET_DIR: /var/www/deploy-user/go-example REMOTE_USER: deploy-user SERVICE_NAME: go_example_prod docker: - image: circleci/golang:1.12 working_directory: ~/go-example/ steps: - checkout - add_ssh_keys # ci , - run: go build -ldflags "-X main.version=$CIRCLE_TAG" -o ./main ./src/main - run: ssh -o "StrictHostKeyChecking=no" $REMOTE_USER@$TARGET_IP "mkdir $TARGET_DIR/v$CIRCLE_TAG" # , - run: scp main $REMOTE_USER@$TARGET_IP:$TARGET_DIR/v$CIRCLE_TAG/ # - run: sed "s/PH_NAME/$SERVICE_NAME/g" .circleci/supervisor_ph.conf > .circleci/$SERVICE_NAME.conf - run: echo command=$TARGET_DIR/v$CIRCLE_TAG/main >> .circleci/$SERVICE_NAME.conf - run: scp .circleci/$SERVICE_NAME.conf $REMOTE_USER@$TARGET_IP:$TARGET_DIR/v$CIRCLE_TAG/ - run: ssh $REMOTE_USER@$TARGET_IP "ln -sf $TARGET_DIR/v$CIRCLE_TAG/$SERVICE_NAME.conf /etc/supervisord.d" - run: ssh $REMOTE_USER@$TARGET_IP "supervisorctl -c /etc/supervisord.conf reread && supervisorctl -c /etc/supervisord.conf update" - run: curl "$TELEGRAM_SERVICE?msg=$SERVICE_NAME%20v$CIRCLE_TAG%20deployed&channel=go_deploy"
Para las notificaciones, utilizamos nuestro propio bot, que se llama mediante curl. El comando `when: on_fail` funciona si algo salió mal, también se puede usar para revertir los cambios. Aunque tenemos un bot de telegramas, en general puede prescindir de él y usar notificaciones estándar: Slack, IRC. Además, las notificaciones de error van al correo electrónico.
La variable `$ TELEGRAM_SERVICE` se agrega a través de la sección CREAR CONFIGURACIÓN → Variables de entorno.
- run: command: curl "$TELEGRAM_SERVICE?msg=$SERVICE_NAME%20v$CIRCLE_TAG%20failed&channel=go_deploy" when: on_fail
Línea de meta
Empujamos en github o en bitbucket. Después de ir a CircleCI en el elemento Agregar proyecto

Luego seleccione Comenzar a construir. El último paso será agregar una clave ssh para autorización en el servidor bajo el usuario seleccionado.

Todo se puede implementar, poner una etiqueta y comenzar a disfrutar de la vida. La versión final ./.circleci/config.yml -
aquí