建立基于开源git平台的模改定制主题代码自动部署
什么叫CI自动化
持续集成(Continuous integration,CI)是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
选择CI平台
通常来说,如果是企业或者存在空余的服务器资源,可以考虑使用jenkins来执行CI(在条件许可情况下,似乎总是推荐自行部署,它非常好用),但出于某些因素,或者个人喜好,也可以考虑github等协作平台的第三方CI。在这里,我们选择github Actions,主要也是将需要自行维护的基础架构降到最低(使用github Actions是不用收费的)
建立CI自动化脚本
建立自动化框架
首先,我们需要可以为我们提供自动化测试的单元测试,我使用phpunit-7
来执行单元测试,首先,我们需要拉取wordpress的官方开发库,命令如下:
git clone git://develop.git.wordpress.org/
然后这个项目的结构如下:
tests
├── e2e
│ ├── config
│ └── specs
├── gutenberg
├── phpunit
│ ├── data
│ │ ├── blocks
│ │ │ ├── fixtures
│ │ │ └── notice
│ │ ├── export
│ │ ├── feed
│ │ ├── formatting
│ │ │ └── utf-8
│ │ ├── images
│ │ ├── languages
│ │ │ ├── plugins
│ │ │ └── themes
│ │ ├── plugins
│ │ ├── pomo
│ │ ├── themedir1
│ │ │ ├── broken-theme
│ │ │ ├── camelCase
│ │ │ ├── child-parent-itself
│ │ │ ├── default
│ │ │ ├── internationalized-theme
│ │ │ ├── page-templates
│ │ │ │ ├── 38766
│ │ │ │ └── subdir
│ │ │ ├── page-templates-child
│ │ │ │ └── subdir
│ │ │ ├── rest-api
│ │ │ ├── sandbox
│ │ │ ├── stylesheetonly
│ │ │ ├── subdir
│ │ │ │ ├── theme2
│ │ │ │ └── theme with spaces
│ │ │ ├── theme1
│ │ │ └── theme1-dupe
│ │ ├── theme-file-child
│ │ ├── theme-file-parent
│ │ └── uploads
│ ├── includes
│ │ ├── factory
│ │ ├── phpunit6
│ │ └── phpunit7
│ │ └── MockObject
│ │ ├── Builder
│ │ └── Generator
│ └── tests
│ ├── actions
│ ├── admin
│ ├── ajax
│ ├── attachment
│ ├── blocks
│ ├── bookmark
│ ├── canonical
│ ├── category
│ ├── comment
│ ├── customize
│ ├── date
│ ├── db
│ ├── dependencies
│ ├── editor
│ ├── error-protection
│ ├── external-http
│ ├── feed
│ ├── filesystem
│ ├── formatting
│ ├── functions
│ ├── general
│ ├── hooks
│ ├── http
│ ├── image
│ ├── import
│ ├── includes
│ ├── l10n
│ ├── link
│ ├── load
│ ├── media
│ ├── menu
│ ├── meta
│ ├── multisite
│ ├── oembed
│ ├── option
│ ├── pomo
│ ├── post
│ ├── privacy
│ ├── query
│ ├── rest-api
│ │ └── json_schema_test_suite
│ ├── rewrite
│ ├── sitemaps
│ ├── taxonomy
│ ├── term
│ ├── theme
│ ├── url
│ ├── user
│ ├── widgets
│ └── xmlrpc
│ ├── mt
│ ├── mw
│ └── wp
└── qunit
├── fixtures
├── wp-admin
│ └── js
│ └── widgets
└── wp-includes
└── js
└── tinymce
└── plugins
└── wptextpattern
我们需要复制以下路径结构:
tests
│ ├── includes
│ │ ├── factory
│ │ ├── phpunit6
│ │ └── phpunit7
│ │ └── MockObject
│ │ ├── Builder
│ │ └── Generator
将这部分结构复制成以下目录,如:
tests
└── wordpress
├── includes
│ ├── factory
│ ├── phpunit6
│ └── phpunit7
接下来,我们需要下载最新的wordpress代码,然后执行如下命令:
mkdir -p tests/wordpress-framework
cp ~/path/to/wordpress/* tests/wordpress-framework
ls -s . tests/wordpress-framework/wp-content/themes/home
创建tests/bootstrap.php
:
<?php
/**
* Bootstrap the plugin unit testing environment.
*
* Edit 'active_plugins' setting below to point to your main plugin file.
*
* @package wordpress-plugin-tests
*/
// Activates this plugin in WordPress so it can be tested.
$GLOBALS['wp_tests_options'] = array(
'template' => 'home',
'wpsp_test' => true
);
define('DISABLE_MATTERMOST', true);
define('TEST_DEBUG',true);
define( 'WP_TESTS_TITLE', 'test Blogs' );
define( 'WP_TESTS_EMAIL', 'admin@example.org' );
require dirname(__FILE__) . '/wordpress/includes/bootstrap.php';
创建tests/wordpress/wp-tests-config.php
:
<?php
/* Path to the WordPress codebase you'd like to test. Add a backslash in the end. */
define( 'ABSPATH', dirname(dirname(dirname(dirname(__FILE__)))) . '/qhjack-home-theme-for-wordperess/tests/wordpress/wordpress-framework/' );
define( 'WP_DEBUG', true );
define( 'WP_TESTS_TITLE', 'test Blogs' );
define( 'WP_TESTS_EMAIL', 'jack9603301@163.com' );
// WARNING WARNING WARNING!
// tests DROPS ALL TABLES in the database. DO NOT use a production database
define( 'DB_NAME', 'wptest' );
define( 'DB_USER', 'wptest' );
define( 'DB_PASSWORD', 'wptest' );
define( 'DB_HOST', '127.0.0.1' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
$table_prefix = 'wp_'; // Only numbers, letters, and underscores please!
define( 'WP_PHP_BINARY', 'php' );
define( 'WP_TESTS_DOMAIN', 'localhost' );
define( 'WPLANG', '' );
/* Cron tries to make an HTTP request to the blog, which always fails, because tests are run in CLI mode only */
define( 'DISABLE_WP_CRON', true );
define( 'WP_ALLOW_MULTISITE', false );
if ( WP_ALLOW_MULTISITE ) {
define( 'WP_TESTS_BLOGS', 'first,second,third,fourth' );
}
if ( WP_ALLOW_MULTISITE && !defined('WP_INSTALLING') ) {
define( 'SUBDOMAIN_INSTALL', WP_TESTS_SUBDOMAIN_INSTALL );
define( 'MULTISITE', true );
define( 'DOMAIN_CURRENT_SITE', WP_TESTS_DOMAIN );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1);
define( 'BLOG_ID_CURRENT_SITE', 1);
//define( 'SUNRISE', TRUE );
}
创建phpunit.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
bootstrap="tests/bootstrap.php"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Plugin Test Suite">
<directory prefix="test." suffix=".php">tests/wordpress</directory>
<directory prefix="test." suffix=".php">tests/</directory>
</testsuite>
</testsuites>
<logging>
<log type="junit" target="tests/code_coverage/phpunit.xml" />
</logging>
</phpunit>
安装compose.phar
到项目,然后创建compose.phar
:
{
"name": "jack9603301/qhjack-home-theme-for-wordperess",
"description": "起航天空个人主题",
"type": "wordpress-theme",
"repositories": {
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
},
"keywords": [
"wordpress"
],
"authors": [
{
"name": "jack9603301",
"email": "jack9603301@163.com",
"homepage": "https://www.qhjack.cn/"
}
],
"require": {
"php": ">=5.3.0"
},
"homepage": "https://www.qhjack.cn",
"require-dev": {
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "7.*"
}
}
创建.gitignore
:
vendor
composer.lock
tests/code_coverage
建立CI自动测试和编译
创建CI自动化文件.github/workflows/phpunit.yml
:
name: qhjack phpuni
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Git Clone this repo
uses: actions/checkout@v2.3.4
with:
submodules: true
- name: Setup PHP 7.4
uses: nanasess/setup-php@v3.0.6
with:
php-version: 7.4
- name: Setup Mariadb
run: |
curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
sudo apt update
sudo apt-get install -y mariadb-server-10.5
sudo systemctl start mariadb
sudo mysql -uroot -proot -e 'create database wptest;'
sudo mysql -uroot -proot -e "CREATE USER 'wptest'@'%' IDENTIFIED BY 'wptest';"
sudo mysql -uroot -proot -e "GRANT ALL ON wptest.* TO 'wptest'@'%';"
- name: PHP Composer
run: |
./composer.phar install
- name: Pre Test
run: |
mkdir -p tests/code_coverage/
- name: Test
run: |
php vendor/bin/phpunit
创建CI自动化文件.github/workflows/qhjack.yml
:
name: qhjack deploy
on:
push:
tags:
- 'v*.*'
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Git Clone this repo
uses: actions/checkout@v2.3.4
with:
submodules: true
- name: Setup PHP 7.4
uses: nanasess/setup-php@v3.0.6
with:
php-version: 7.4
- name: Setup Mariadb
run: |
curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
sudo apt update
sudo apt-get install -y mariadb-server-10.5
sudo systemctl start mariadb
sudo mysql -uroot -proot -e 'create database wptest;'
sudo mysql -uroot -proot -e "CREATE USER 'wptest'@'%' IDENTIFIED BY 'wptest';"
sudo mysql -uroot -proot -e "GRANT ALL ON wptest.* TO 'wptest'@'%';"
- name: PHP Composer
run: |
./composer.phar install
- name: Pre Test
run: |
mkdir -p tests/code_coverage/
- name: Test
run: |
php vendor/bin/phpunit
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Git Clone this repo
uses: actions/checkout@v2.3.4
- name: Clean Test data
run: |
rm -rf tests
rm -f phpunit.xml
rm -f composer.json
rm -f composer.lock
rm -f composer.phar
rm -rf vendor
- name: Upload WordPress Server
env:
QHJACK_DEPLOY_SERVER_USERNAME: ${{ secrets.QHJACK_DEPLOY_SERVER_USERNAME }}
QHJACK_DEPLOY_SERVER_PASSWORD: ${{ secrets.QHJACK_DEPLOY_SERVER_PASSWORD }}
QHJACK_DEPLOY_SERVER_PUSH: ${{ secrets.QHJACK_DEPLOY_SERVER_PUSH }}
run: |
sshpass -p $QHJACK_DEPLOY_SERVER_PASSWORD scp -o StrictHostKeyChecking=no -r * $QHJACK_DEPLOY_SERVER_USERNAME@$QHJACK_DEPLOY_SERVER_PUSH:/glusterfs/webroot/qhjack/wp-content/themes/home/
- name: Apply Deploy
env:
QHJACK_DEPLOY_SERVER_USERNAME: ${{ secrets.QHJACK_DEPLOY_SERVER_USERNAME }}
QHJACK_DEPLOY_SERVER_PASSWORD: ${{ secrets.QHJACK_DEPLOY_SERVER_PASSWORD }}
QHJACK_DEPLOY_SERVERS: ${{ secrets.QHJACK_DEPLOY_SERVERS }}
QHJACK_DEPLOY_SERVER_PUSH: ${{ secrets.QHJACK_DEPLOY_SERVER_PUSH }}
QHJACK_DEPLOY_SERVER_PROXY: ${{ secrets.QHJACK_DEPLOY_SERVER_PROXY }}
run: |
for service_addr in ${QHJACK_DEPLOY_SERVERS[@]}
do
echo "Restart the service:$service_addr"
sshpass -p $QHJACK_DEPLOY_SERVER_PASSWORD ssh $QHJACK_DEPLOY_SERVER_USERNAME@$service_addr -o StrictHostKeyChecking=no 'systemctl restart php-fpm && systemctl restart nginx'
done
echo "Clear the cache"
sshpass -p $QHJACK_DEPLOY_SERVER_PASSWORD ssh $QHJACK_DEPLOY_SERVER_USERNAME@$QHJACK_DEPLOY_SERVER_PROXY -o StrictHostKeyChecking=no 'rm -rf "/www/services/nginx/cache/proxy/qhjack/*" && rm -rf "/www/services/nginx/cache/proxy_store/*"'
echo "Restart load balancing"
sshpass -p $QHJACK_DEPLOY_SERVER_PASSWORD ssh $QHJACK_DEPLOY_SERVER_USERNAME@$QHJACK_DEPLOY_SERVER_PROXY -o StrictHostKeyChecking=no 'systemctl restart nginx'
提交到github
首先,我们需要创建项目,并在项目的Settings->secrets
下创建所需要的环境变量,如下:
- QHJACK_DEPLOY_SERVERS
- QHJACK_DEPLOY_SERVER_PASSWORD
- QHJACK_DEPLOY_SERVER_PROXY
- QHJACK_DEPLOY_SERVER_PUSH
- QHJACK_DEPLOY_SERVER_USERNAME
然后执行如下命令:
git add *
git add .github
git commit -a
git push origin
如果你的本地repo还没有远程地址,应该输入:
git remote add origin <你的地址>