From 24fa64759ee46189d31e698893fa3eaf85d03f49 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 24 Sep 2021 10:52:32 +0200 Subject: [PATCH 1/5] install mysql only if it isnt installed --- index.js | 81 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/index.js b/index.js index fb0bbd4..7415340 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,17 @@ function runSafe() { } } +function checkInstalled(package) { + command = "dpkg -l | grep " + package; + const args = Array.from(arguments); + console.log(command); + let env = Object.assign({}, process.env); + delete env.CI; // for Homebrew on macos-11.0 + const ret = execSync(command).toString(); + console.log(ret); + return !ret || ret !== ""; +} + function addToPath(newPath) { fs.appendFileSync(process.env.GITHUB_PATH, `${newPath}\n`); } @@ -67,22 +78,25 @@ if (process.platform == 'darwin') { '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}`); + installDir = "C:\\Program Files\\MySQL"; + if (! fs.existsSync(installDir)) { + 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(installDir); + 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`); + } + run(`"${bin}\\mysqld" --install`); + run(`net start MySQL`); - // start - bin = `C:\\Program Files\\MySQL\\MySQL Server ${mysqlVersion}\\bin`; - if (mysqlVersion != '5.6') { - run(`"${bin}\\mysqld" --initialize-insecure`); + addToPath(bin); } - run(`"${bin}\\mysqld" --install`); - run(`net start MySQL`); - - addToPath(bin); run(`"${bin}\\mysql" -u root -e "SELECT VERSION()"`); @@ -91,25 +105,28 @@ if (process.platform == 'darwin') { 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}`; + // 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`); } - - // 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`); } } From 9e5636bcaae9e7635a80bead70321f9ae512239d Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 24 Sep 2021 09:31:11 +0200 Subject: [PATCH 2/5] add password and username as parameter --- README.md | 11 +++++++++++ action.yml | 10 ++++++++++ index.js | 53 +++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6462722..0863309 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/action.yml b/action.yml index 4956d74..664e202 100644 --- a/action.yml +++ b/action.yml @@ -2,8 +2,18 @@ name: Setup MySQL 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 runs: using: node12 main: index.js diff --git a/index.js b/index.js index 7415340..2ef822c 100644 --- a/index.js +++ b/index.js @@ -41,6 +41,8 @@ function addToPath(newPath) { 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'] || ""; // TODO make OS-specific if (!['8.0', '5.7', '5.6'].includes(mysqlVersion)) { @@ -56,7 +58,7 @@ function useTmpDir() { process.chdir(tmpDir); } -if (process.platform == 'darwin') { +function installMac() { // install run(`brew install mysql@${mysqlVersion}`); @@ -65,14 +67,17 @@ 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 +} + +function installWindwos() { + // install const versionMap = { '8.0': '8.0.22', '5.7': '5.7.32', @@ -101,11 +106,15 @@ if (process.platform == 'darwin') { 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 { - // check if it is installed + 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"`); + } +} + +function installLinux() { + // check if it is installed if(!checkInstalled("mysql-server-${mysqlVersion}")) { if (image == 'ubuntu20') { if (mysqlVersion != '8.0') { @@ -137,13 +146,25 @@ if (process.platform == 'darwin') { run(`sudo mysqladmin -proot password ''`); // 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`; } + +if (process.platform == 'darwin') { + 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); } From 738f744c922905ea27f42d2e3411b699c9dd014a Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 24 Sep 2021 09:39:01 +0200 Subject: [PATCH 3/5] extend tests * add two user * test admin * test first and second user --- .github/workflows/build.yml | 55 +++++++++++++++++++++++++++++-------- action.yml | 1 + index.js | 25 +++++++++++++---- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b66fc4e..ce77b7f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 @@ -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'" diff --git a/action.yml b/action.yml index 664e202..e53f176 100644 --- a/action.yml +++ b/action.yml @@ -1,4 +1,5 @@ name: Setup MySQL +description: install and start the mysql server inputs: mysql-version: description: The MySQL version to download (if necessary) and use diff --git a/index.js b/index.js index 2ef822c..1714308 100644 --- a/index.js +++ b/index.js @@ -74,6 +74,7 @@ function installMac() { } // set path addToPath(bin); + return bin; } function installWindwos() { @@ -84,6 +85,7 @@ function installWindwos() { '5.6': '5.6.50' }; installDir = "C:\\Program Files\\MySQL"; + bin = `C:\\Program Files\\MySQL\\MySQL Server ${mysqlVersion}\\bin`; if (! fs.existsSync(installDir)) { const fullVersion = versionMap[mysqlVersion]; useTmpDir(); @@ -93,14 +95,16 @@ function installWindwos() { 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`); } 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}\\mysql" -u root -e "SELECT VERSION()"`); @@ -111,6 +115,7 @@ function installWindwos() { run(`"${bin}\\mysql" -u root -e "GRANT ALL PRIVILEGES ON *.* TO '${username}'@'localhost'"`); run(`"${bin}\\mysql" -u root -e "FLUSH PRIVILEGES"`); } + return bin; } function installLinux() { @@ -143,7 +148,11 @@ function installLinux() { run('sudo systemctl start mysql'); // remove root password - run(`sudo mysqladmin -proot password ''`); + try { + run(`sudo mysqladmin -proot password ''`); + } catch (error) { + console.log("error on remove password: ", error); + } // add user if(username && username !== "") { @@ -152,11 +161,12 @@ function installLinux() { run(`sudo mysql -e "FLUSH PRIVILEGES"`); } bin = `/usr/bin`; + return bin; } if (process.platform == 'darwin') { - installMac(); + bin = installMac(); } else if (process.platform == 'win32') { bin = installWindwos(); } else if (process.platform == 'linux') { @@ -166,5 +176,10 @@ if (process.platform == 'darwin') { } if (database) { - runSafe(path.join(bin, 'mysqladmin'), 'create', database); +try { + run(path.join(bin, 'mysqladmin'), ' -u root create', database); +} catch (error) { + console.log("error on create database: ", error); +} + } From 09fd88951134ea49eafaebd450f64af51ac7b553 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Mon, 27 Sep 2021 09:54:47 +0200 Subject: [PATCH 4/5] Add mysql installation path --- action.yml | 4 ++++ index.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index e53f176..73713e9 100644 --- a/action.yml +++ b/action.yml @@ -15,6 +15,10 @@ inputs: 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 diff --git a/index.js b/index.js index 1714308..16d23bb 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,66 @@ 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(' ')); @@ -43,7 +103,7 @@ const defaultVersion = (image == 'ubuntu16' || image == 'ubuntu18') ? '5.7' : '8 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}`; @@ -84,15 +144,13 @@ function installWindwos() { '5.7': '5.7.32', '5.6': '5.6.50' }; - installDir = "C:\\Program Files\\MySQL"; - bin = `C:\\Program Files\\MySQL\\MySQL Server ${mysqlVersion}\\bin`; - if (! fs.existsSync(installDir)) { + 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`); - fs.mkdirSync(installDir); - fs.renameSync(`mysql-${fullVersion}-winx64`, `C:\\Program Files\\MySQL\\MySQL Server ${mysqlVersion}`); + integrateFolderRecursiveSync(`mysql-${fullVersion}-winx64`, mysqlInstallDirectory); // start if (mysqlVersion != '5.6') { From f6795ffd4d131b9aa7068bee6bef10225f7c512f Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 22 Oct 2021 10:58:12 +0200 Subject: [PATCH 5/5] remove debugging logs --- index.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 16d23bb..174fe79 100644 --- a/index.js +++ b/index.js @@ -74,7 +74,6 @@ function integrateFolderRecursiveSync(source, target) { 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'}); @@ -86,11 +85,9 @@ function runSafe() { function checkInstalled(package) { command = "dpkg -l | grep " + package; const args = Array.from(arguments); - console.log(command); let env = Object.assign({}, process.env); delete env.CI; // for Homebrew on macos-11.0 const ret = execSync(command).toString(); - console.log(ret); return !ret || ret !== ""; } @@ -209,7 +206,7 @@ function installLinux() { try { run(`sudo mysqladmin -proot password ''`); } catch (error) { - console.log("error on remove password: ", error); + console.error("error on remove password: ", error); } // add user @@ -237,7 +234,7 @@ if (database) { try { run(path.join(bin, 'mysqladmin'), ' -u root create', database); } catch (error) { - console.log("error on create database: ", error); + console.error("error on create database: ", error); } }