FIX ERROR — Fastlane: duplicate symbol

При сборке iOS приложения с Pod'ами при помощи Fastlane могут возникнуть такого рода ошибки:

duplicate symbol _OBJC_IVAR_$_RCTFrameAnimation._fromValue in
> libReact.a(RCTFrameAnimation.o)
> libRCTAnimation.a(RCTFrameAnimation.o)

 

Решение:

Для того чтобы это избежать, нужно добавить "post_install" шаг в файл "ios/Podfile"

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "React"
      target.remove_from_project
    end
  end
end

Tar — Основные команды

 

Создаем архив, используя gzip сжатие и вывод списка файлов:

tar -cvzf archive.tar.gz /var/www/html/mysite

 

Распаковка архива в текущую директорию:

tar -xf archive.tar.gz

 

Создаем архив, используя сжатие и исключая сохранение структуры полного пути в архиве:

tar -zcvf archive.tar.gz --directory='/var/www/html/' ./

 

Создаем архив, используя сжатие и исключая сохранение структуры полного пути в архиве, а так же исключая не нужные директории:

tar --exclude='./cache' --exclude='./logs' -zcvf archive.tar.gz --directory='/var/www/html/' ./

 

Для создания архива, но не обновляя atime статистику файла источника нужно использовать следующий ключ:

--atime-preserve=system

Virsh — Уменьшить размер образа

Со временем работы виртуальной машины QEMU размер образа начинает расти и может значительно превышать размер содержимого внутри гостевой ОС.

Данный пример поможет уменьшить размер образа для Unix систем.

 

Заходим в гостевую ОС и забиваем все свободное место нулями:

dd if=/dev/zero of=/mytempfile

 

Ждем завершения команды, это длительный процесс. Затем удаляем созданный файл:

rm -f /mytempfile

 

Выключаем виртуальную машину:

virsh shutdown vm_name

 

Делаем бекап образа. Это может занять очень длительное время, как теперь образ занимает столько, сколько вы указали при создании раздела.

cp image.qcow2 image.qcow2_backup

 

Конвертируем образ, тем самым убирая сектора забитые нулями:

qemu-img convert -p -O qcow2 image.qcow2_backup image.qcow2

 

Так же можно применить сжатие образа при помощи ключа "-c", но это может замедлить работу виртуальной машины.

 

И запускаем обратно виртуальную машину:

virsh start vm_name

Fastlane — Android bundle

 

Меняем в Fastlane тип сборки андроид приложения с "apk" на "bundle" и заливает в Google Play

 

Пример блока для "apk"

  lane :build_release do
    gradle(
      task: "clean",
      project_dir: "android/"
     )
    gradle(
      task: "assemble",
      build_type: "Release",
      project_dir: "android/",
      flags: "--no-daemon --max-workers 1",
    )
    upload_to_play_store(
      track: 'internal',
      package_name: 'com.myapp',
      json_key: './fastlane/.api-XXXXXXXXXXXXXXXXXXX-XXXXXX-XXXXXXXXXXXX.json'
    )
  end

 

Приводим его к следующему виду:

  lane :build_release do
    gradle(
      task: "clean",
      project_dir: "android/"
     )
    gradle(
      task: "bundle",
      build_type: "Release",
      project_dir: "android/",
      flags: "--no-daemon --max-workers 1",
    )
    upload_to_play_store(
      track: 'internal',
      skip_upload_apk: 'true',
      package_name: 'com.myapp',
      aab: "android/app/build/outputs/bundle/release/app.aab",
      json_key: './fastlane/.api-XXXXXXXXXXXXXXXXXXX-XXXXXX-XXXXXXXXXXXX.json'
      )
  end

AWS — ресайз изображений на лету

Ресайз изображения на лету используя:

  • Gateway API
  • Lambda
  • CloudFront
  • S3 Bucket

При этом в S3 Bucket будет только оригинал изображения.

 

 

Описание работы и CloudFormation template можно найти тут.

Скачиваем CloudFormation template с сайта или же по этой ссылке.

 

 

Заходим в консоль AWS

В сервисах находим "CloudFormation" — "Create stack"

Задаем имя нашему стеку, к примеру "image-resize-staging"

У нас готовый шаблон, поэтому выбираем "Template is ready"

 

Загружаем шаблон с файла.

 

SourceBuckets — пишем имя S3 Bucket, где хранятся оригиналы изображений.

CORS — если нужны, указываем

Так же будет предложено поставить веб интерфейс, для ознакомления с функциями ресайза.

Permission — если не указывать ничего, будет создана роль на основе прав текущего логина в AWS консоли.

 

 

Создаем стек. Нужно дождаться пока создастся CloudFront, это порядка 15 минут.

 

После завершения создания во вкладке "Outputs" можно посмотреть URL CloudFront

Так же к CloudFront можно привязать домен через CNAME.

CircleCI — node.js сайт деплой на AWS S3 Bucket

 

Пример сборки статического сайта на node.js, деплой артефактов в S3 Bucket и инвалидация кеша в CloudFront'е.

version: 2
jobs:
  build:
    working_directory: ~/source
    docker:
      - image: circleci/node:10
    steps:
      - checkout
      - restore_cache: # special step to restore the dependency cache
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: Replace ENV file
          command: cp .env.staging .env
      - run:
          name: Setup Dependencies
          command: yarn
      - run:
          name: Build static files
          command: yarn build
      - persist_to_workspace:
          root: ~/source
          paths:
            - .

  deploy:
    docker:
      - image: circleci/python:2.7
    working_directory: ~/source
    environment:
      BUCKET: artem-services-bucket
      DISTRIBUTION_ID: XXXXXXXXXXXXX
    steps:
      - attach_workspace:
          at: ~/source
      - run:
          name: Install AWS Cli
          command: sudo pip install awscli
      - run:
          name: Deploy
          command: aws s3 sync build/ s3://${BUCKET} --region eu-central-1 --delete
      - run:
          name: CloudFront invalidation
          command: aws cloudfront create-invalidation --distribution-id=${DISTRIBUTION_ID} --paths '/index.html'

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - build:
          filters:
            branches:
              only: staging
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: staging

 

Переменные:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

указаны в переменных CircleCI, в целях безопасности.

 

IAM Policy для инвалидации кеша можно посмотреть тут.

IAM Policy — CloudFront CreateInvalidation

AIM Policy для инвалидации кеша CloudFront

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "arn:aws:s3:::MY_S3_BUCKET"
        },
        {
            "Action": [
                "cloudfront:CreateInvalidation",
                "cloudfront:GetDistribution",
                "cloudfront:GetStreamingDistribution",
                "cloudfront:GetDistributionConfig",
                "cloudfront:GetInvalidation",
                "cloudfront:ListInvalidations",
                "cloudfront:ListStreamingDistributions",
                "cloudfront:ListDistributions"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

Jenkins — GitHub аккаунт с 2FA

 

Для того, чтобы Jenkins мог работать с репозиторием с аккаунта, на котором включена 2-х факторная авторизация, нужно сгенерировать "Personal access tokens"

 

Логинимся в GitHub и переходим по ссылке.

 

Выбираем "Generate new token" и ставим следующие галочки:

 

repo:invate — необходима для доступа к приватным репозиториям, без нее у вас будет доступ только к публичным

 

В Jenkins'е переходим в "Credentials" и добавляем новые "Add Credentials"

 

  • Kind: Username and password
  • Username: Ваш GitHub логин
  • Password: Ваш токен созданный ранее

 

Теперь в GitHub плагине вы можете использовать созданную связку доступов.

 

Для работы с Git в консоли необходимо указывать токен, к примеру:

git clone https://<token>@github.com/owner/repo.git

Docker — MySQL 8 создание образа с дампом

Пример сборки докер образа MySQL 8 с базой данных, с дамп файла.

Содержимое:

  • Dockerfile
  • mysqld.cnf
  • dump.sql

 

Dockerfile:

FROM mysql:8

RUN apt update && \
    apt install -y psmisc

ENV MYSQL_ROOT_PASSWORD MyRootPassword
ENV MYSQL_DATABASE artem_db
ENV MYSQL_USER database_user
ENV MYSQL_PASSWORD MyUserPassword

COPY dump.sql /docker-entrypoint-initdb.d/db.sql
COPY my.cnf /etc/mysql/my.cnf
RUN /entrypoint.sh mysqld &; sleep 30 && killall mysqld
RUN rm /docker-entrypoint-initdb.d/db.sql

 

Обратите внимание, что теперь переменные "MYSQL_USER" и "MYSQL_PASSWORD" задаются в Dockerfile

 

В файле "my.cnf" необходимо заменить только дефолтный путь хранения файлов MySQL

mysqld.cnf

# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# The MySQL  Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Custom config should go here
!includedir /etc/mysql/conf.d/

 

Путь в этой строке:

datadir		= /var/lib/mysql

На другой путь:

datadir		= /var/lib/mysql_artem_service

 

И собираем образ:

docker build -t artem_db .