Автоматическая сборка Android приложения с помощью Jenkins и публикация в Google Play Market + Telegram Bot оповещение

Для того что бы поднять Jenkins в докер, какие Volume пробрасывать сами решайте, это полностью скопированная моя конфигурация для примера

docker run -it -d -v jenkins_home:/var/jenkins_home -v /usr/lib/android-sdk:/usr/lib/android-sdk -v /opt/tomcat-latest/webapps:/opt/tomcat-latest/webapps -p 8070:8080 -p 50000:50000 --env JENKINS_OPTS="--prefix=/jenkins" --restart always leganas/ls_repository:jenkins

Git хук, который выполняет curl к jenkins , если push событие было в ветку мастер. Этот гит хук можно прописывать не только в Gita, можно сразу в папку gita в хуки прописать и будет так же работать в любом git репозитарии.

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" = "$branch" ]; then
       curl --user USER:API_Token https://legan.by/jenkins/job/MenuAndMarket/build?token=TOKEN_JENKINS
    fi
done

ПС. Если ветка не важна, можно убрать всё кроме 1 строки и самой строчки curl

Настройки build.gradle уровня app для автоматической генерации номера версии на приложения на основании даты и времени

...

def getVersionNameTimestamp() {
    return new Date().format('yy.MM.ddHHmm')
}

def getVersionCodeTimestamp() {
    def date = new Date()
    def formattedDate = date.format('yyMMddHHmm')
    def code = formattedDate.toInteger()
    println sprintf("VersionCode: %d", code)
    return code
}

...

android {

...

defaultConfig {
     ...
        versionCode getVersionCodeTimestamp()
        versionName "${getVersionNameTimestamp()}"

Настройки build.gradle уровня app для автоматической подписи apk

// Load keystore
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

...

android {
    signingConfigs {
        config {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
        }
    }

...

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }

Пример JSON Shema приходящий от Gitea , есть прекрасный ресурс позволяющий превратить это в Java классы http://www.jsonschema2pojo.org/

{
  "secret": "3gEsCfjlV2ugRwgpU#w1*WaW*wa4NXgGmpCfkbG3",
  "ref": "refs/heads/develop",
  "before": "28e1879d029cb852e4844d9c718537df08844e03",
  "after": "bffeb74224043ba2feb48d137756c8a9331c449a",
  "compare_url": "http://localhost:3000/gitea/webhooks/compare/28e1879d029cb852e4844d9c718537df08844e03...bffeb74224043ba2feb48d137756c8a9331c449a",
  "commits": [
    {
      "id": "bffeb74224043ba2feb48d137756c8a9331c449a",
      "message": "Webhooks Yay!",
      "url": "http://localhost:3000/gitea/webhooks/commit/bffeb74224043ba2feb48d137756c8a9331c449a",
      "author": {
        "name": "Gitea",
        "email": "someone@gitea.io",
        "username": "gitea"
      },
      "committer": {
        "name": "Gitea",
        "email": "someone@gitea.io",
        "username": "gitea"
      },
      "timestamp": "2017-03-13T13:52:11-04:00"
    }
  ],
  "repository": {
    "id": 140,
    "owner": {
      "id": 1,
      "login": "gitea",
      "full_name": "Gitea",
      "email": "someone@gitea.io",
      "avatar_url": "https://localhost:3000/avatars/1",
      "username": "gitea"
    },
    "name": "webhooks",
    "full_name": "gitea/webhooks",
    "description": "",
    "private": false,
    "fork": false,
    "html_url": "http://localhost:3000/gitea/webhooks",
    "ssh_url": "ssh://gitea@localhost:2222/gitea/webhooks.git",
    "clone_url": "http://localhost:3000/gitea/webhooks.git",
    "website": "",
    "stars_count": 0,
    "forks_count": 1,
    "watchers_count": 1,
    "open_issues_count": 7,
    "default_branch": "master",
    "created_at": "2017-02-26T04:29:06-05:00",
    "updated_at": "2017-03-13T13:51:58-04:00"
  },
  "pusher": {
    "id": 1,
    "login": "gitea",
    "full_name": "Gitea",
    "email": "someone@gitea.io",
    "avatar_url": "https://localhost:3000/avatars/1",
    "username": "gitea"
  },
  "sender": {
    "id": 1,
    "login": "gitea",
    "full_name": "Gitea",
    "email": "someone@gitea.io",
    "avatar_url": "https://localhost:3000/avatars/1",
    "username": "gitea"
  }
}

 

org.hibernate.property.access.spi.PropertyAccessException

org.hibernate.property.access.spi.PropertyAccessException: Error accessing field by reflection for persistent property

Ебанутая ошибка с с которой я бился пол дня, оказывается возникает из-за какого то непонятного конфликта с spring-boot-devtools

просто убираем 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

и ВСЁ, почему так происходит не понятно. 

при работе с через SpringDATA JPA такой ошибки не возникает, а если использовать чисты Hibernate то вот …. 

Создание SSL-сертификатов для Nginx с Let’s Encrypt под Ubuntu 16.04

Некоммерческий удостоверяющий центр Let’s Encrypt, развивающийся под эгидой Linux Foundation — хороший способ получить бесплатный (не самоподписанный!) SSL/TLS-сертификат сроком на три месяца, с возможностью автопродления.

В данном руководстве все действия будут выполняться с помощью официального клиента letsencrypt. Он позволяет создать достоверный сертификат, пригодный для использования в различных приложениях, конкретно же речь пойдет об Nginx.

Требования:

  • Ubuntu Server 16.04;
  • пользователь с sudo-привилегиями;
  • собственно домен; 
  • DNS-запись A вашего домена должна указывать на IPv4-адрес вашего же сервера в Vscale (необходимо для подтверждения владения; доменом). Это также в силе для поддоменов (вроде www.example.site).

Шаг 1. Установка необходимого ПО

Обновим локальные индексы менеджера пакетов и установим клиент letsencrypt:

$ sudo apt-get update
$ sudo apt-get install letsencrypt -y

Мы пойдём по пути использования Web-root плагина letsencrypt, суть работы которого заключается в том, что он помещает специальный файл в каталог /.well-known (путь указан относительно корня веб-директории), необходимый для валидации вашего домена серверной частью ПО Let’s Encrypt.

Если по какой-либо причине ещё не был установлен веб-сервер Nginx — сделайте это с помощью следующих команд:

$ sudo add-apt-repository ppa:nginx/development
$ sudo apt-get update
$ sudo apt-get install nginx -y

Шаг 2. Подготовка к выпуску сертификата

Откройте конфигурационный файл Nginx:

$ sudo nano /etc/nginx/sites-available/default

внутри серверного блока (server { …) поместите блок location:

        location ~ /.well-known {
                allow all;
        }

выйдите из редактора, сохранив изменения, по нажатию Ctrl+X, y, Enter.

Протестируйте конфигурационный файл Nginx на корректность:

$ sudo nginx -t

Перезапустите Nginx:

$ sudo service nginx reload

Шаг 3. Выпуск сертификата

Запустите клиент letsencrypt с повышением и нужными Вам параметрами (/var/www/html — корень вашей веб-директории (по-умолчанию), example.site — домен):

$ sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d example.site -d www.example.site

После этого вам будет предложено ввести e-mail (для получения уведомлений об истечении сертификата, если вы вдруг не захотите настроить автопродление) и согласиться с лицензионным соглашением.

Итак, теперь у вас есть 4 PEM-файла, относящихся к сертификату — можно вывести их имена командой (example.site — ваш домен):

$ sudo ls -l /etc/letsencrypt/live/example.site

Шаг 4. Генерация параметров Диффи-Хеллмана

Для улучшения безопасности — cгенерируем параметры Диффи-Хеллмана и запишем в файл (процесс займёт некоторое время):

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Шаг 5. Изменение конфигурации Nginx:

Опять отредактируем конфигурационный файл Nginx:

$ sudo nano /etc/nginx/sites-available/default

Привожу проверенный вариант:

server {
 listen 80;
 listen [::]:80;

 server_name example.site;
 # редирект на HTTPS
 return 301 https://$server_name$request_uri;

 server_tokens off;
}

server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;

 server_name example.site;

 ssl_certificate /etc/letsencrypt/live/example.site/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/example.site/privkey.pem;
 ssl_dhparam /etc/ssl/certs/dhparam.pem;
 ssl_session_timeout 1d;
 ssl_session_cache shared:SSL:50m;
 ssl_session_tickets off;
 # конфигурация Modern
 ssl_protocols TLSv1.2;
 ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
 ssl_prefer_server_ciphers on;
 # HSTS - форсированно устанавливать соединение по HTTPS
 add_header Strict-Transport-Security "max-age=15768000";
 # Разрешение прикрепления OCSP-ответов сервером
 ssl_stapling on;
 # Разрешение проверки сервером ответов OCSP
 ssl_stapling_verify on;

 root /var/www/html;
 index index.html index.htm index.nginx-debian.html;
 # Запрещение выдачи версии nginx в HTTP-заголовках
 server_tokens off;

 location / {
 try_files $uri $uri/ =404;
 }
 # для валидации Let's Encrypt
 location ~ /.well-known {
 allow all;
 }
}

Для более подробного разъяснения SSL-директив в конфигурации Nginx: документация (на русском) ngx_http_ssl_module.

Преимущества такой конфигурации:

  • поддержка бинарного протокола HTTP2
  • HTTPS-only
  • заточена под максимальную безопасность и современные версии браузеров
  • A+-рейтинг по версии SSL Labs

Шаг 6 (необязательный). Настройка автопродления сертификата

Вручную продлить сертификат на 3 месяца можно так:

$ sudo letsencrypt renew

Естественно, следует перезапустить Nginx:

$ sudo service nginx reload

Для автоматизации процесса добавим задание в планировщик сron.

Откройте список заданий cron:

$ crontab -e

Добавьте следующие строки:

30 5 * * 1 sudo letsencrypt renew
35 5 * * 1 sudo service nginx reload

Каждый понедельник, в 05:30 будет производиться запуск клиента Let’s Encrypt, и в случае необходимости — выполняться продление сертификата.

Заключение

Let’s Encrypt выпускает совершенно стандартные сертификаты, без возможности какой-либо настройки. Вся суть состоит в конфигурации веб-сервера Nginx, а именно в нахождении баланса совместимости и безопасности.