CircleCIでSassをCSSに変換してS3へデプロイする
これは何?
CircleCIのジョブでSassをCSSにトランスパイルし、ミニファイしてS3へデプロイするために必要な設定をまとめたものです。
ゴール
my_repositoyリポジトリのassets/css/style.scss
をstyle.min.css
にトランスパイル&ミニファイし、S3のproduction-bucketにassets/css/style.min.css
としてデプロイします。
デプロイパイプライン
- リポジトリへプルリクエスト
- この時点で実行されるジョブでSass→CSSトランスパイルが実行される
- その結果をステージング用のS3バケットにデプロイする
- マージされる
- masterブランチなら、本番用とステージング用S3バケットにそれぞれデプロイ
- それ以外のブランチなら、ステージング用のバケットにデプロイ
必要な設定
CSSトランスパイル
- この時点で実行されるジョブでSass→CSSトランスパイルが実行される
- その結果をステージング用のS3バケットにデプロイする
- masterブランチなら、本番用とステージング用S3バケットにそれぞれデプロイ
- それ以外のブランチなら、ステージング用のバケットにデプロイ
CSSトランスパイル
トランスパイル用のタスクランナーとしてgulpを利用します。
gulpfile.js
'use strict';
const gulp = require('gulp');
const sass = require('gulp-sass');
const workDir = './assets/css';
sass.compiler = require('node-sass');
const compileSass = (cb) => {
const options = {
outputStyle: "expanded",
};
gulp
.src(`${workDir}/style.scss`)
.pipe(sass(options))
.pipe(gulp.dest(workDir));
cb();
}
const compileSassCompressed = (cb) => {
const rename = require('gulp-rename'); // ファイル名にminを付けたいのでそれ用のモジュールを使います
const options = {
outputStyle: "compressed", // ここで圧縮指定
};
gulp
.src(`${workDir}/style.scss`)
.pipe(sass(options))
.pipe(rename({
suffix: ".min",
}))
.pipe(gulp.dest(workDir));
cb();
}
exports.compileSass = compileSass; // こっちは使っていません
exports.default = compileSassCompressed;
実行は以下をビルドの過程に入れておきます。
$ npx gulp
# npx便利ですねー
参考
CircleCI
- S3へのデプロイはcircleci/aws-s3 Orbを利用して楽してます
- デプロイ時に、パブリックアクセスを許可させるためには以降に記載のバケット設定をする必要がありました
CircleCI用コンフィグ
version: 2.1
orbs:
aws-s3: circleci/[email protected]
# 本番用デプロイとステージング用デプロイジョブそれぞれで同じ処理をするので、デプロイ処理をコマンド化しています
commands:
deploy-to-s3:
description: "Deploy Assets to S3"
parameters:
bucket_name:
type: string
steps:
- checkout
- restore_cache:
keys:
- my_repository-css-v0-{{ .BuildNum }}
- my_repository-css-v0-
# Deploy CSS assets to S3
- aws-s3/copy:
arguments: |
--acl public-read \
--cache-control "max-age=604800"
from: assets/css/style.min.css
to: "s3://<< parameters.bucket_name >>/assets/css/style.min.css"
# 本番用デプロイとステージング用デプロイジョブで同じDockerイメージを使うのでこっちもエグゼキューターとして定義しています
executors:
deploy-executor:
docker:
# aws cliを使うので、pythonがないとだめです
- image: cimg/python:latest
jobs:
build:
parallelism: 1
working_directory: ~/my_repository
docker:
- image: circleci/node:9.11.2
steps:
- checkout
- restore_cache:
keys:
- my_repository-npm-v0-{{ checksum "package-lock.json" }}
- my_repository-npm-v0-
- run:
name: npm Install
command: npm install
- save_cache:
key: my_repository-npm-v0-{{ checksum "package-lock.json" }}
paths:
- ./node_modules
- run:
name: Run Sass Lint
command: ./node_modules/.bin/sass-lint -c config/.sass-lint.yml --verbose --no-exit
- run:
name: Compile Scss
command: npx gulp
- save_cache:
key: my_repository-css-v0-{{ .BuildNum }}
paths:
- assets
- store_test_results:
path: test_results
deploy-as-staging:
working_directory: ~/my_repository
executor: deploy-executor
steps:
- deploy-to-s3:
bucket_name: "staging-bucket"
deploy-as-production:
working_directory: ~/my_repository
executor: deploy-executor
steps:
- deploy-to-s3:
bucket_name: "production-bucket"
workflows:
build_and_deploy:
jobs:
- build
- deploy-as-staging:
requires:
- build
- deploy-as-production:
requires:
- build
filters:
branches:
only: master
参考
AWS側の設定
- IAM
- deployグループを作成し、S3フルアクセスを付与
- circleci-userユーザを作成し、deployグループに所属
- S3
- デプロイ先のバケットを作成
- ブロックパブリックアクセス (バケット設定)を「(新しい/任意の)アクセスコントロールリスト (ACL) を介して許可されたバケットとオブジェクトへのパブリックアクセスをブロックする」をオフ
- バケットポリシーを以下にする
バケットポリシー
{
"Version": "2012-10-17",
"Id": "Policy1583424049389",
"Statement": [
{
"Sid": "Stmt1583424044685",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::アカウント名:user/circleci-user"
},
"Action": [
"s3:DeleteObject",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::production-bucket/*"
}
]
}
- CORS設定を以下にする
- アプリのドメインとS3のドメインが異なる場合は必要
CORSの設定
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
参考
Author And Source
この問題について(CircleCIでSassをCSSに変換してS3へデプロイする), 我々は、より多くの情報をここで見つけました https://qiita.com/HrsUed/items/663ef3d4bcb155dea035著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .