Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 43 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ jobs:
include:
- os: ubuntu-20.04
mysql-version: 8.0
- os: ubuntu-20.04
mysql-version: 5.7
- os: ubuntu-18.04
mysql-version: 8.0
- os: ubuntu-18.04
mysql-version: 5.7
- os: ubuntu-16.04
mysql-version: 8.0
- os: ubuntu-16.04
mysql-version: 5.7
- os: macos-11.0
mysql-version: 8.0
- os: macos-11.0
Expand All @@ -44,14 +42,47 @@ jobs:
mysql-version: 5.6
steps:
- uses: actions/checkout@v2
- uses: ./.

- name: Install mysql
uses: ./.
with:
mysql-version: ${{ matrix.mysql-version }}
database: testdb
username: "1234"
password: "abcd"

- name: Install mysql second time
uses: ./.
with:
mysql-version: ${{ matrix.mysql-version }}
database: testdb
- run: mysql --version
- run: mysql -e 'SELECT VERSION()'
- run: mysql -e 'SELECT CURRENT_USER()'
- run: mysql -e 'SELECT DATABASE()'
- run: mysql -e "SHOW VARIABLES LIKE 'socket'"
- run: mysqladmin create testdb2
- run: mysql -D testdb -e 'SELECT DATABASE()'
username: "5678"
password: "efgh"

- name: Test admin
run: |
mysql --version
mysql -uroot -e 'SELECT * FROM mysql.user;'
mysql -uroot -e 'SELECT VERSION()'
mysql -uroot -e 'SELECT CURRENT_USER()'
mysql -uroot -e 'SELECT DATABASE()'
mysql -uroot -e "SHOW VARIABLES LIKE 'socket'"
mysqladmin -uroot create testdb2
mysql -uroot -D testdb2 -e 'SELECT DATABASE()'
echo Y | mysqladmin -uroot drop testdb2

- name: Test first user
run: |
mysql --version
mysql -u1234 -pabcd -e 'SELECT VERSION()'
mysql -u1234 -pabcd -e 'SELECT CURRENT_USER()'
mysql -u1234 -pabcd -e 'SELECT DATABASE()'
mysql -u1234 -pabcd -e "SHOW VARIABLES LIKE 'socket'"

- name: Test second user
run: |
mysql --version
mysql -u5678 -pefgh -e 'SELECT VERSION()'
mysql -u5678 -pefgh -e 'SELECT CURRENT_USER()'
mysql -u5678 -pefgh -e 'SELECT DATABASE()'
mysql -u5678 -pefgh -e "SHOW VARIABLES LIKE 'socket'"
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ Specify a version
with:
mysql-version: 8.0
```
## Optional User and password

Optionally you can add an additional user. The user can have an optional password.

```yml
- uses: ankane/setup-mysql@v1
with:
mysql-version: 8.0
username: user
password: password
```

Currently supports

Expand Down
15 changes: 15 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
name: Setup MySQL
description: install and start the mysql server
inputs:
mysql-version:
description: The MySQL version to download (if necessary) and use
required: true
database:
description: Database to create
required: false
username:
description: Username for the database
required: false
default: ""
password:
description: Password for the user
default: ""
required: false
install-directory:
description: Installation path of MySQL. Only relevant on Windows
default: ${{ runner.workspace }}\MySQL
required: false
runs:
using: node12
main: index.js
212 changes: 160 additions & 52 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,68 @@ function run(command) {
execSync(command, {stdio: 'inherit', env: env});
}

function copyFileSync( source, target ) {
// Source https://stackoverflow.com/a/26038979/2127939
var targetFile = target;

// If target is a directory, a new file with the same name will be created
if ( fs.existsSync( target ) ) {
if ( fs.lstatSync( target ).isDirectory() ) {
targetFile = path.join( target, path.basename( source ) );
}
}

fs.writeFileSync(targetFile, fs.readFileSync(source));
}

function copyFolderRecursiveSync( source, target ) {
// Source https://stackoverflow.com/a/26038979/2127939
var files = [];

// Check if folder needs to be created or integrated
var targetFolder = path.join( target, path.basename( source ) );
if ( !fs.existsSync( targetFolder ) ) {
fs.mkdirSync( targetFolder );
}

// Copy
if ( fs.lstatSync( source ).isDirectory() ) {
files = fs.readdirSync( source );
files.forEach( function ( file ) {
var curSource = path.join( source, file );
if ( fs.lstatSync( curSource ).isDirectory() ) {
copyFolderRecursiveSync( curSource, targetFolder );
} else {
copyFileSync( curSource, targetFolder );
}
} );
}
}

function integrateFolderRecursiveSync(source, target) {
var files = [];

// Check if folder needs to be created or integrated
var targetFolder = target;
if ( !fs.existsSync( targetFolder ) ) {
fs.mkdirSync( targetFolder );
}
// Copy
if ( fs.lstatSync( source ).isDirectory() ) {
files = fs.readdirSync( source );
files.forEach( function ( file ) {
var curSource = path.join( source, file );
if ( fs.lstatSync( curSource ).isDirectory() ) {
copyFolderRecursiveSync( curSource, targetFolder );
} else {
copyFileSync( curSource, targetFolder );
}
} );
}
}

function runSafe() {
const args = Array.from(arguments);
console.log(args.join(' '));
const command = args.shift();
// spawn is safer and more lightweight than exec
const ret = spawnSync(command, args, {stdio: 'inherit'});
Expand All @@ -23,14 +82,25 @@ function runSafe() {
}
}

function checkInstalled(package) {
command = "dpkg -l | grep " + package;
const args = Array.from(arguments);
let env = Object.assign({}, process.env);
delete env.CI; // for Homebrew on macos-11.0
const ret = execSync(command).toString();
return !ret || ret !== "";
}

function addToPath(newPath) {
fs.appendFileSync(process.env.GITHUB_PATH, `${newPath}\n`);
}

const image = process.env['ImageOS'];
const defaultVersion = (image == 'ubuntu16' || image == 'ubuntu18') ? '5.7' : '8.0';
const mysqlVersion = parseFloat(process.env['INPUT_MYSQL-VERSION'] || defaultVersion).toFixed(1);

const username = process.env['INPUT_USERNAME'] || "";
const password = process.env['INPUT_PASSWORD'] || "";
const mysqlInstallDirectory = process.env['INPUT_install-directory'] || "";
// TODO make OS-specific
if (!['8.0', '5.7', '5.6'].includes(mysqlVersion)) {
throw `MySQL version not supported: ${mysqlVersion}`;
Expand All @@ -45,7 +115,7 @@ function useTmpDir() {
process.chdir(tmpDir);
}

if (process.platform == 'darwin') {
function installMac() {
// install
run(`brew install mysql@${mysqlVersion}`);

Expand All @@ -54,79 +124,117 @@ if (process.platform == 'darwin') {
run(`${bin}/mysql.server start`);

// add user
run(`${bin}/mysql -e "CREATE USER '$USER'@'localhost' IDENTIFIED BY ''"`);
run(`${bin}/mysql -e "GRANT ALL PRIVILEGES ON *.* TO '$USER'@'localhost'"`);
run(`${bin}/mysql -e "FLUSH PRIVILEGES"`);

if(username && username !== "") {
run(`${bin}/mysql -e "CREATE USER '${username}'@'localhost' IDENTIFIED BY '${password}'"`);
run(`${bin}/mysql -e "GRANT ALL PRIVILEGES ON *.* TO '${username}'@'localhost'"`);
run(`${bin}/mysql -e "FLUSH PRIVILEGES"`);
}
// set path
addToPath(bin);
} else if (process.platform == 'win32') {
// install
return bin;
}

function installWindwos() {
// install
const versionMap = {
'8.0': '8.0.22',
'5.7': '5.7.32',
'5.6': '5.6.50'
};
const fullVersion = versionMap[mysqlVersion];
useTmpDir();
run(`curl -Ls -o mysql.zip https://dev.mysql.com/get/Downloads/MySQL-${mysqlVersion}/mysql-${fullVersion}-winx64.zip`)
run(`unzip -q mysql.zip`);
fs.mkdirSync(`C:\\Program Files\\MySQL`);
fs.renameSync(`mysql-${fullVersion}-winx64`, `C:\\Program Files\\MySQL\\MySQL Server ${mysqlVersion}`);

// start
bin = `C:\\Program Files\\MySQL\\MySQL Server ${mysqlVersion}\\bin`;
if (mysqlVersion != '5.6') {
run(`"${bin}\\mysqld" --initialize-insecure`);
bin = `${mysqlInstallDirectory}\\bin`;
if (! fs.existsSync(mysqlInstallDirectory)) {
const fullVersion = versionMap[mysqlVersion];
useTmpDir();
run(`curl -Ls -o mysql.zip https://dev.mysql.com/get/Downloads/MySQL-${mysqlVersion}/mysql-${fullVersion}-winx64.zip`)
run(`unzip -q mysql.zip`);
integrateFolderRecursiveSync(`mysql-${fullVersion}-winx64`, mysqlInstallDirectory);

// start
if (mysqlVersion != '5.6') {
run(`"${bin}\\mysqld" --initialize-insecure`);
}
run(`"${bin}\\mysqld" --install`);
run(`net start MySQL`);
addToPath(bin);
// create windows only user odbc
run(`"${bin}\\mysql" -u root -e "CREATE USER 'ODBC'@'localhost' IDENTIFIED BY ''"`);
run(`"${bin}\\mysql" -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'ODBC'@'localhost'"`);
run(`"${bin}\\mysql" -u root -e "FLUSH PRIVILEGES"`);
}
run(`"${bin}\\mysqld" --install`);
run(`net start MySQL`);

addToPath(bin);

run(`"${bin}\\mysql" -u root -e "SELECT VERSION()"`);

// add user
run(`"${bin}\\mysql" -u root -e "CREATE USER 'ODBC'@'localhost' IDENTIFIED BY ''"`);
run(`"${bin}\\mysql" -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'ODBC'@'localhost'"`);
run(`"${bin}\\mysql" -u root -e "FLUSH PRIVILEGES"`);
} else {
if (image == 'ubuntu20') {
if (mysqlVersion != '8.0') {
// install
run(`sudo apt-get install mysql-server-${mysqlVersion}`);
}
} else {
if (mysqlVersion != '5.7') {
if (mysqlVersion == '5.6') {
throw `MySQL version not supported yet: ${mysqlVersion}`;
}
if(username && username !== "") {
run(`"${bin}\\mysql" -u root -e "CREATE USER '${username}'@'localhost' IDENTIFIED BY '${password}'"`);
run(`"${bin}\\mysql" -u root -e "GRANT ALL PRIVILEGES ON *.* TO '${username}'@'localhost'"`);
run(`"${bin}\\mysql" -u root -e "FLUSH PRIVILEGES"`);
}
return bin;
}

// install
useTmpDir();
run(`wget -q -O mysql-apt-config.deb https://dev.mysql.com/get/mysql-apt-config_0.8.16-1_all.deb`);
run(`echo mysql-apt-config mysql-apt-config/select-server select mysql-${mysqlVersion} | sudo debconf-set-selections`);
run(`sudo dpkg -i mysql-apt-config.deb`);
// TODO only update single list
run(`sudo apt-get update`);
run(`sudo apt-get install mysql-server`);
function installLinux() {
// check if it is installed
if(!checkInstalled("mysql-server-${mysqlVersion}")) {
if (image == 'ubuntu20') {
if (mysqlVersion != '8.0') {
// install
run(`sudo apt-get install mysql-server-${mysqlVersion}`);
}
} else {
if (mysqlVersion != '5.7') {
if (mysqlVersion == '5.6') {
throw `MySQL version not supported yet: ${mysqlVersion}`;
}

// install
useTmpDir();
run(`wget -q -O mysql-apt-config.deb https://dev.mysql.com/get/mysql-apt-config_0.8.16-1_all.deb`);
run(`echo mysql-apt-config mysql-apt-config/select-server select mysql-${mysqlVersion} | sudo debconf-set-selections`);
run(`sudo dpkg -i mysql-apt-config.deb`);
// TODO only update single list
run(`sudo apt-get update`);
run(`sudo apt-get install mysql-server`);
}
}
}

// start
run('sudo systemctl start mysql');

// remove root password
run(`sudo mysqladmin -proot password ''`);
try {
run(`sudo mysqladmin -proot password ''`);
} catch (error) {
console.error("error on remove password: ", error);
}

// add user
run(`sudo mysql -e "CREATE USER '$USER'@'localhost' IDENTIFIED BY ''"`);
run(`sudo mysql -e "GRANT ALL PRIVILEGES ON *.* TO '$USER'@'localhost'"`);
run(`sudo mysql -e "FLUSH PRIVILEGES"`);

if(username && username !== "") {
run(`sudo mysql -e "CREATE USER '${username}'@'localhost' IDENTIFIED BY '${password}'"`);
run(`sudo mysql -e "GRANT ALL PRIVILEGES ON *.* TO '${username}'@'localhost'"`);
run(`sudo mysql -e "FLUSH PRIVILEGES"`);
}
bin = `/usr/bin`;
return bin;
}


if (process.platform == 'darwin') {
bin = installMac();
} else if (process.platform == 'win32') {
bin = installWindwos();
} else if (process.platform == 'linux') {
bin = installLinux();
} else {
console.error(process.platform + " is not supported");
}

if (database) {
runSafe(path.join(bin, 'mysqladmin'), 'create', database);
try {
run(path.join(bin, 'mysqladmin'), ' -u root create', database);
} catch (error) {
console.error("error on create database: ", error);
}

}