Commit 451458d6 authored by echel0n's avatar echel0n

Merge branch 'add-ci-release-stage' into 'develop'

Added CI/CD release stage to build app

See merge request !24
parents 5ade5180 28291d80
......@@ -12,7 +12,6 @@ changelog.md
readme.md
README.txt
crowdin.yaml
Gruntfile.js
MANIFEST.in
package.json
package-lock.json
......
stages:
- release
- build
- review
- deploy
- review_webpack
- review_docker
- review_deploy
- release_build
- release_sentry
- release_deploy
sentry_release_master:
stage: release
mr:build:webpack:
stage: review_webpack
image:
name: getsentry/sentry-cli
entrypoint: [""]
script:
- export SENTRY_URL=$SENTRY_URL
- export SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
- export SENTRY_ORG=$SENTRY_ORG
- export SENTRY_PROJECT=$SENTRY_PROJECT
- sentry-cli releases new --project $SENTRY_PROJECT $(cat sickrage/version.txt)
- sentry-cli releases set-commits --auto $(cat sickrage/version.txt)
- sentry-cli releases finalize $(cat sickrage/version.txt)
- sentry-cli releases deploys $(cat sickrage/version.txt) new -e master
only:
- /^[0-9.]+$/
except:
- branches
- triggers
sentry_release_develop:
stage: release
image:
name: getsentry/sentry-cli
entrypoint: [""]
name: nikolaik/python-nodejs:python3.7-nodejs10-alpine
variables:
NODE_ENV: "development"
script:
- export SENTRY_URL=$SENTRY_URL
- export SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
- export SENTRY_ORG=$SENTRY_ORG
- export SENTRY_PROJECT=$SENTRY_PROJECT
- sentry-cli releases new --project $SENTRY_PROJECT $(cat sickrage/version.txt)
- sentry-cli releases set-commits --auto $(cat sickrage/version.txt)
- sentry-cli releases finalize $(cat sickrage/version.txt)
- sentry-cli releases deploys $(cat sickrage/version.txt) new -e develop
- apk add --no-cache git
- npm install -qs
- npm run build
only:
- /^[0-9.]+dev[0-9]+$/
except:
- branches
- triggers
- merge_requests
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- sickrage/core/webserver/static/
build:mr:
stage: build
mr:build:docker:
stage: review_docker
dependencies:
- mr:build:webpack
image:
name: docker:latest
entrypoint: ["/bin/sh", "-c"]
......@@ -56,18 +37,20 @@ build:mr:
services:
- docker:dind
script:
- docker login -u "${CI_REGISTRY_USER}" -p "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}"
- docker login -u "${CI_REGISTRY_USER}" -p "${CI_JOB_TOKEN}" "${CI_REGISTRY}"
- docker build --network host -t "${CI_REGISTRY_IMAGE}:latest" .
- docker tag "${CI_REGISTRY_IMAGE}:latest" "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}"
- test ! -z "${CI_COMMIT_TAG}" && docker push "${CI_REGISTRY_IMAGE}:latest"
- docker push "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}"
only:
- merge_requests
cache:
key: ${CI_COMMIT_REF_SLUG}
deploy:mr:
stage: review
mr:review:start:
stage: review_deploy
dependencies:
- build:mr
- mr:build:docker
image:
name: lachlanevenson/k8s-kubectl:latest
entrypoint: ["/bin/sh", "-c"]
......@@ -91,16 +74,19 @@ deploy:mr:
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://review.sickrage.ca/$CI_COMMIT_REF_SLUG
on_stop: stop:mr
on_stop: mr:review:stop
only:
- merge_requests
stop:mr:
stage: review
mr:review:stop:
stage: review_deploy
image:
name: lachlanevenson/k8s-kubectl:latest
entrypoint: ["/bin/sh", "-c"]
script:
- wget -O /usr/bin/reg https://github.com/genuinetools/reg/releases/download/v0.13.0/reg-linux-amd64
- chmod +x /usr/bin/reg
- reg -r ${CI_REGISTRY} -u ${CI_REGISTRY_USER} -p ${CI_JOB_TOKEN} rm ${CI_REGISTRY_IMAGE}
- kubectl delete secret -n ${KUBE_NAMESPACE} gitlab-registry
- kubectl delete ing -l ref=${CI_ENVIRONMENT_SLUG}
- kubectl delete all -l ref=${CI_ENVIRONMENT_SLUG}
......@@ -113,8 +99,112 @@ stop:mr:
only:
- merge_requests
deploy_pypi:
stage: deploy
build:master:
stage: release_build
image:
name: nikolaik/python-nodejs:python3.7-nodejs10-alpine
variables:
NODE_ENV: "development"
script:
- apk add --no-cache git
- npm install -qs
- pip install bumpversion
- pip install -r requirements-dev.txt
- npm run build
- python setup.py extract_messages
- crowdin-cli-py upload sources
- crowdin-cli-py download
- python setup.py compile_catalog
- bumpversion --allow-dirty patch sickrage/version.txt
- git config --global user.email $(git --no-pager show -s --format='%ae' HEAD)
- git config --global user.name $(git --no-pager show -s --format='%an' HEAD)
- git add --all
- git tag -a $(cat sickrage/version.txt) -m "Release v$(cat sickrage/version.txt)"
- git commit -m "[TASK] Releasing v$(cat sickrage/version.txt)"
- git push https://$GIT_ACCESS_USER:[email protected]$CI_SERVER_HOST/$CI_PROJECT_PATH.git HEAD:$CI_COMMIT_REF_NAME --follow-tags
only:
- master
except:
refs:
- tags
- triggers
variables:
- $CI_COMMIT_MESSAGE =~ /\[TASK\] Releasing/
build:develop:
stage: release_build
image:
name: nikolaik/python-nodejs:python3.7-nodejs10-alpine
variables:
NODE_ENV: "development"
script:
- apk add --no-cache git
- npm install -qs
- pip install bumpversion
- pip install -r requirements-dev.txt
- npm run build
- python setup.py extract_messages
- crowdin-cli-py upload sources
- crowdin-cli-py download
- python setup.py compile_catalog
- bumpversion --allow-dirty preversion sickrage/version.txt
- git config --global user.email $(git --no-pager show -s --format='%ae' HEAD)
- git config --global user.name $(git --no-pager show -s --format='%an' HEAD)
- git add --all
- git tag -a $(cat sickrage/version.txt) -m "Pre-release v$(cat sickrage/version.txt)"
- git commit -m "[TASK] Pre-Releasing v$(cat sickrage/version.txt)"
- git push https://$GIT_ACCESS_USER:[email protected]$CI_SERVER_HOST/$CI_PROJECT_PATH.git HEAD:$CI_COMMIT_REF_NAME --follow-tags
only:
- develop
except:
refs:
- tags
- triggers
variables:
- $CI_COMMIT_MESSAGE =~ /\[TASK\] Pre-Releasing/
sentry:master:
stage: release_sentry
image:
name: getsentry/sentry-cli
entrypoint: [""]
script:
- export SENTRY_URL=$SENTRY_URL
- export SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
- export SENTRY_ORG=$SENTRY_ORG
- export SENTRY_PROJECT=$SENTRY_PROJECT
- sentry-cli releases new --project $SENTRY_PROJECT $(cat sickrage/version.txt)
- sentry-cli releases set-commits --auto $(cat sickrage/version.txt)
- sentry-cli releases finalize $(cat sickrage/version.txt)
- sentry-cli releases deploys $(cat sickrage/version.txt) new -e master
only:
- /^[0-9.]+$/
except:
- branches
- triggers
sentry:develop:
stage: release_sentry
image:
name: getsentry/sentry-cli
entrypoint: [""]
script:
- export SENTRY_URL=$SENTRY_URL
- export SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
- export SENTRY_ORG=$SENTRY_ORG
- export SENTRY_PROJECT=$SENTRY_PROJECT
- sentry-cli releases new --project $SENTRY_PROJECT $(cat sickrage/version.txt)
- sentry-cli releases set-commits --auto $(cat sickrage/version.txt)
- sentry-cli releases finalize $(cat sickrage/version.txt)
- sentry-cli releases deploys $(cat sickrage/version.txt) new -e develop
only:
- /^[0-9.]+dev[0-9]+$/
except:
- branches
- triggers
deploy:pypi:
stage: release_deploy
image: python:3.7-alpine3.9
script:
- apk add --no-cache py-pip
......@@ -128,8 +218,8 @@ deploy_pypi:
- branches
- triggers
deploy_docker_master:
stage: deploy
deploy:docker:master:
stage: release_deploy
variables:
UPSTREAM_BRANCH: master
UPSTREAM_COMMIT_SHA: $CI_COMMIT_SHA
......@@ -142,8 +232,8 @@ deploy_docker_master:
- branches
- triggers
deploy_docker_develop:
stage: deploy
deploy:docker:develop:
stage: release_deploy
variables:
UPSTREAM_BRANCH: develop
UPSTREAM_COMMIT_SHA: $CI_COMMIT_SHA
......@@ -156,8 +246,8 @@ deploy_docker_develop:
- branches
- triggers
deploy_synology:
stage: deploy
deploy:synology:
stage: release_deploy
variables:
UPSTREAM_BRANCH: master
UPSTREAM_COMMIT_SHA: $CI_COMMIT_SHA
......@@ -170,8 +260,8 @@ deploy_synology:
- branches
- triggers
deploy_readynas:
stage: deploy
deploy:readynas:
stage: release_deploy
variables:
UPSTREAM_COMMIT_TAG: $CI_COMMIT_TAG
UPSTREAM_PROJECT_NAME: $CI_PROJECT_NAME
......@@ -186,8 +276,8 @@ deploy_readynas:
- branches
- triggers
deploy_qnap:
stage: deploy
deploy:qnap:
stage: release_deploy
variables:
UPSTREAM_COMMIT_TAG: $CI_COMMIT_TAG
UPSTREAM_PROJECT_NAME: $CI_PROJECT_NAME
......
module.exports = function (grunt) {
const shell = require('shelljs');
const webpackConfig = require('./webpack.config');
require('load-grunt-tasks')(grunt);
grunt.initConfig({
webpack: {
options: {
stats: !process.env.NODE_ENV || process.env.NODE_ENV === 'development'
},
prod: webpackConfig,
dev: webpackConfig
},
changelog: {
release: {
options: {
after: '256',
logArguments: [
'--pretty=* %h - %ad: %s',
'--no-merges',
'--date=short'
],
fileHeader: '# Changelog',
featureRegex: /^(.*)$/gim,
partials: {
features: '{{#each features}}{{> feature}}{{/each}}\n',
feature: '- {{this}} {{this.date}}\n',
fixes: '{{#each fixes}}{{> fix}}{{/each}}\n',
fix: '- {{this}} {{this.date}}\n'
},
dest: "changelog.md"
}
}
},
exec: {
// Translations
'crowdin_upload_sources': {cmd: 'crowdin-cli-py upload sources'},
'crowdin_upload_translations': {cmd: 'crowdin-cli-py upload translations'},
'crowdin_download_translations': {cmd: 'crowdin-cli-py download'},
'babel_extract': {cmd: 'python setup.py extract_messages'},
'babel_update': {cmd: 'python setup.py update_catalog'},
'babel_compile': {cmd: 'python setup.py compile_catalog'},
// Git Commands
'git': {
cmd: function (cmd, branch) {
branch = branch ? ' ' + branch : '';
return 'git ' + cmd + branch;
}
},
'git_push': {
cmd: function (remote, branch, tags) {
let pushCmd = 'git push ' + remote + ' ' + branch;
if (tags) {
pushCmd += ' --tags';
}
return pushCmd;
},
stderr: false,
callback: function (err, stdout, stderr) {
grunt.log.write(stderr);
}
},
'git_commit': {
cmd: function (message) {
return 'git commit -am "' + message + '"';
},
stderr: false,
callback: function (err, stdout, stderr) {
grunt.log.write(stderr);
}
},
'git_last_tag': {
cmd: 'git for-each-ref refs/tags --sort=-taggerdate --count=1 --format=%(refname:short)',
stdout: false,
callback: function (err, stdout) {
stdout = stdout.trim();
if (/^\d{1,2}.\d{1,2}.\d+(?:.dev\d+)?$/.test(stdout)) {
grunt.config('last_tag', stdout);
} else {
grunt.fatal('Could not get the last tag name. We got: ' + stdout);
}
}
},
'git_list_changes': {
cmd: function () {
return 'git log --oneline --pretty=format:%s ' + grunt.config('last_tag') + '..HEAD';
},
stdout: false,
maxBuffer: 500 * 1024,
callback: function (err, stdout) {
const commits = stdout.trim()
.replace(/`/gm, '').replace(/^\([\w\d\s,.\-+_/>]+\)\s/gm, ''); // removes ` and tag information
if (commits) {
grunt.config('commits', commits);
} else {
grunt.fatal('Getting new commit list failed!');
}
}
},
'git_tag': {
cmd: function (version) {
return 'git tag ' + version + ' -m "' + grunt.config('commits') + '"';
},
stdout: false
}
}
});
grunt.registerTask('upload_trans', 'Upload translations', function () {
grunt.log.writeln('Extracting and uploading translations to Crowdin...'.magenta);
const tasks = [
'exec:babel_extract',
'exec:crowdin_upload_sources'
];
if (process.env.CROWDIN_API_KEY) {
grunt.task.run(tasks);
} else {
grunt.log.warn('Environment variable `CROWDIN_API_KEY` is not set, aborting task'.bold);
}
});
grunt.registerTask('download_trans', 'Download translations', function () {
grunt.log.writeln('Downloading and compiling translations from Crowdin...'.magenta);
const tasks = [
'exec:crowdin_download_translations',
'exec:babel_compile'
];
if (process.env.CROWDIN_API_KEY) {
grunt.task.run(tasks);
} else {
grunt.log.warn('Environment variable `CROWDIN_API_KEY` is not set, aborting task.'.bold);
}
});
grunt.registerTask('sync_trans', 'Sync translations with Crowdin', function () {
grunt.log.writeln('Syncing translations with Crowdin...'.magenta);
const tasks = [
'upload_trans',
'download_trans'
];
if (process.env.CROWDIN_API_KEY) {
grunt.task.run(tasks);
} else {
grunt.log.warn('Environment variable `CROWDIN_API_KEY` is not set, aborting task.'.bold);
}
});
grunt.registerTask('bump_version', function (new_version) {
const vFile = 'sickrage/version.txt';
grunt.file.write(vFile, new_version)
});
grunt.registerTask('pre-release', function () {
grunt.task.run(['exec:git:checkout:develop']);
const vFile = 'sickrage/version.txt';
const version = grunt.file.read(vFile);
const versionParts = version.split('.');
const vArray = {
vMajor: versionParts[0],
vMinor: versionParts[1],
vPatch: versionParts[2],
vPre: versionParts[3] || 0
};
if (vArray.vPre === 0) {
vArray.vPatch = parseFloat(vArray.vPatch) + 1;
}
if (vArray.vPre !== 0) {
vArray.vPre = vArray.vPre.split('dev')[1];
vArray.vPre = parseFloat(vArray.vPre) + 1;
} else {
vArray.vPre = parseFloat(vArray.vPre) + 1;
}
const newVersion = vArray.vMajor + '.' + vArray.vMinor + '.' + vArray.vPatch + '.dev' + vArray.vPre;
const tasks = [
'changelog',
'webpack:dev',
//'sync_trans',
'bump_version:' + newVersion,
'exec:git_commit:Pre-Release v' + newVersion,
'exec:git_last_tag', 'exec:git_list_changes', 'exec:git_tag:' + newVersion,
'exec:git_push:origin:develop:tags',
];
grunt.task.run(tasks);
});
grunt.registerTask('release', function () {
grunt.task.run(['exec:git:checkout:develop']);
const vFile = 'sickrage/version.txt';
const version = grunt.file.read(vFile);
const versionParts = version.split('.');
const vArray = {
vMajor: versionParts[0],
vMinor: versionParts[1],
vPatch: versionParts[2],
vPre: versionParts[3] || 0
};
if (vArray.vPre === 0) {
vArray.vPatch = parseFloat(vArray.vPatch) + 1;
}
if (vArray.vPre !== 0) {
vArray.vPre = vArray.vPre.split('dev')[1];
vArray.vPre = parseFloat(vArray.vPre) + 1;
} else {
vArray.vPre = parseFloat(vArray.vPre) + 1;
}
const newVersion = vArray.vMajor + '.' + vArray.vMinor + '.' + vArray.vPatch;
const tasks = [
'exec:git:checkout:-b release-v' + newVersion + ':develop',
'changelog',
'webpack:prod',
//'sync_trans',
'bump_version:' + newVersion,
'exec:git_commit:Release v' + newVersion,
'exec:git:checkout:master',
'exec:git:merge:release-v' + newVersion,
'exec:git_last_tag', 'exec:git_list_changes', 'exec:git_tag:' + newVersion,
'exec:git_push:origin:master:tags',
'exec:git:checkout:develop',
'exec:git:merge:release-v' + newVersion,
'exec:git_push:origin:develop',
'exec:git:branch:-d release-v' + newVersion,
];
grunt.task.run(tasks);
});
};
\ No newline at end of file
......@@ -10,8 +10,7 @@
},
"homepage": "https://www.sickrage.ca",
"scripts": {
"dev": "webpack --mode development",
"prod": "webpack --mode production"
"build": "webpack --config webpack.config.js -p"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "^5.1.0",
......
......@@ -3,5 +3,5 @@ crowdin-cli-py
babel
wheel
tox
wheel
vcrpy-unittest
\ No newline at end of file
vcrpy-unittest
Mako
\ No newline at end of file
[bumpversion]
current_version = 9.4.184.dev4
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<releaselevel>[a-z]+)(?P<preversion>\d+))?
serialize =
{major}.{minor}.{patch}.{releaselevel}{preversion}
{major}.{minor}.{patch}
commit = False
tag = False
[metadata]
description-file = README.txt
......@@ -24,4 +33,5 @@ input_file = sickrage/locale/messages.pot
output_dir = sickrage/locale
input_file = sickrage/locale/messages.pot
ignore_obsolete = true
previous = true
\ No newline at end of file
previous = true
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment