├── .eslintrc.json ├── .travis.yml ├── .gitignore ├── LICENSE ├── package.json ├── index.js └── README.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint-config-airbnb-base" 4 | ], 5 | "rules": { 6 | "indent": ["error", 4], 7 | "no-var": "error", 8 | "comma-dangle": ["error", "never"], 9 | "no-console": 0, 10 | "no-restricted-syntax": 0 11 | }, 12 | "env": { 13 | "node": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '6' 10 | before_script: 11 | - npm prune 12 | after_success: 13 | if ([ "$TRAVIS_PULL_REQUEST" == "false" ]); then 14 | eval 'npm run test'; 15 | fi 16 | branches: 17 | except: 18 | - /^v\d+\.\d+\.\d+$/ 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Andrey Gubanov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deploy-to-git", 3 | "version": "0.4.1", 4 | "description": "Automatically deploy build artifacts to a Git repository", 5 | "bin": "index.js", 6 | "scripts": { 7 | "test": "eslint .", 8 | "upgrade": "npx npm-check-updates -u && npm install", 9 | "patch": "npm version patch && npm publish && git push && git push --tags", 10 | "minor": "npm version minor && npm publish && git push && git push --tags" 11 | }, 12 | "config": { 13 | "validate-commit-msg": { 14 | "types": [ 15 | "feat", 16 | "fix", 17 | "refactor", 18 | "perf", 19 | "test", 20 | "chore", 21 | "revert" 22 | ] 23 | }, 24 | "ghooks": { 25 | "commit-msg": "validate-commit-msg" 26 | } 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "https://github.com/finom/deploy-to-git.git" 31 | }, 32 | "keywords": [ 33 | "CI", 34 | "deploy", 35 | "git", 36 | "github", 37 | "gitlab", 38 | "bitbucket", 39 | "artifacts" 40 | ], 41 | "author": "Andrey Gubanov", 42 | "license": "MIT", 43 | "bugs": { 44 | "url": "https://github.com/finom/deploy-to-git/issues" 45 | }, 46 | "homepage": "https://github.com/finom/deploy-to-git#readme", 47 | "devDependencies": { 48 | "eslint": "^8.6.0", 49 | "eslint-config-airbnb-base": "^15.0.0", 50 | "ghooks": "^2.0.4", 51 | "validate-commit-msg": "^2.14.0" 52 | }, 53 | "dependencies": { 54 | "yargs": "^17.3.1" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const { execSync } = require('child_process'); 3 | const yargs = require('yargs/yargs'); 4 | const { hideBin } = require('yargs/helpers'); 5 | 6 | const { argv } = yargs(hideBin(process.argv)); 7 | 8 | const variablePrefix = 'npm_package_config_deployToGit_'; 9 | const fields = { 10 | repository: true, 11 | branch: true, 12 | folder: true, 13 | commit: true, 14 | script: true, 15 | user_name: true, 16 | user_email: true, 17 | beforePushScript: false 18 | }; 19 | const cwd = process.cwd(); 20 | const config = {}; 21 | 22 | for (const [field, isRequired] of Object.entries(fields)) { 23 | const configVar = argv[field] || process.env[`${variablePrefix}${field}`]; 24 | 25 | if (!configVar && isRequired) { 26 | throw Error(`deployOnGit requires "${field}" field in package config`); 27 | } 28 | 29 | if (configVar) { 30 | config[field] = configVar.replace(/\$([a-zA-Z0-9_]+)/g, (match, envVarName) => { 31 | const envVar = process.env[envVarName]; 32 | 33 | if (!envVar) { 34 | throw Error(`Environment variable "${envVarName}" presented at string "${configVar}" is missing`); 35 | } 36 | 37 | return envVar; 38 | }); 39 | } 40 | } 41 | 42 | console.log('Starting deploy to Git...'); 43 | console.log(`Cloning the repository to "${config.folder}" folder...`); 44 | 45 | execSync(`git clone -b ${config.branch} ${config.repository} ${config.folder}`, { cwd, stdio: 'inherit' }); 46 | 47 | console.log(`Starting script "${config.script}"...`); 48 | execSync(`${config.script}`, { cwd, stdio: 'inherit' }); 49 | 50 | console.log('Configuring and committing...'); 51 | execSync([ 52 | `cd ${config.folder}`, 53 | `git config user.email "${config.user_email}"`, 54 | `git config user.name "${config.user_name}"`, 55 | 'git add .', 56 | `git commit --allow-empty -m "${config.commit}"` 57 | ].join('&&'), { cwd, stdio: 'inherit' }); 58 | 59 | if (config.beforePushScript) { 60 | console.log('Running beforePushScript...'); 61 | 62 | execSync(`cd ${config.folder} && ${config.beforePushScript}`, { cwd, stdio: 'inherit' }); 63 | } 64 | 65 | console.log('Pushing...'); 66 | 67 | execSync(`cd ${config.folder} && git push --tags ${config.repository} ${config.branch}`, { cwd, stdio: 'inherit' }); 68 | 69 | console.log('Deploying to git is finished.'); 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deploy-to-git [![npm version](https://badge.fury.io/js/deploy-to-git.svg)](https://badge.fury.io/js/deploy-to-git) [![Build Status](https://travis-ci.org/finom/deploy-to-git.svg?branch=master)](https://travis-ci.org/finom/deploy-to-git) 2 | 3 | Automatically or manually deploy build artifacts to a Git repository. The tool works awesome with [semantic-release](https://github.com/semantic-release/semantic-release) and any CI service. 4 | 5 | ``` 6 | npm install --save-dev deploy-to-git 7 | ``` 8 | 9 | ## Configuring 10 | 11 | Configuration for the tool needs to be placed at ``config.deployToGit`` object inside ``package.json``. 12 | 13 | - ``repository`` - a repository 14 | - ``branch`` - a branch of the repository where you want to push the artifacts 15 | - ``folder`` - a folder where artifacts are generated by the build and where the repository is cloned 16 | - ``script`` - a script which runs the build 17 | - ``commit`` - commit text 18 | - ``user`` - commitee information for Git - an object with keys ``name`` and ``email`` 19 | - ``beforePushScript`` (optional) - a command that should be run after a commit (e. g. add needed git tags). 20 | 21 | Substrings started with ``$`` are replaced by corresponding environment variables. 22 | 23 | ## Getting started 24 | 25 | Let's say you want to deploy artifacts to branch called ``artifacts``. Let's say used build tool compiles the artifacts to ``build`` folder via NPM script called ``build-my-app``. You'll need: 26 | 27 | 1. Create ``artifacts`` branch manually and remove all files from it (because you probably create the branch copying main branch contents). Push it to remote repository. 28 | 2. Add README or whatever you want to have at this branch. 29 | 3. Add ``build`` folder to ``.gitignore`` of your main branch. 30 | 4. Configure ``deploy-to-git`` 31 | 32 | ```js 33 | "scripts": { 34 | "deploy": "deploy-to-git", 35 | "build-my-app": "a-build-script" 36 | } 37 | "config": { 38 | "deployToGit": { 39 | "repository": "git@github.com:owner/your-repo.git", 40 | "branch": "artifacts", 41 | "folder": "build", 42 | "script": "npm run build-my-app", 43 | "commit": "Automatic commit text", 44 | "user": { 45 | "email": "you@example.com", 46 | "name": "Your name" 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | That's it. When you run ``npm run deploy`` the tool does the following: 53 | 54 | 1. Clone the repository to ``build`` folder. 55 | 2. Run script ``npm run build-my-app`` which creates/replaces files at ``build`` folder. 56 | 3. Commit and push changes. 57 | 58 | Tip: remove ``build`` folder before ``deploy-to-git`` run. 59 | 60 | For more info check out [index.js](https://github.com/finom/deploy-to-git/blob/master/index.js). 61 | 62 | ## Travis CI 63 | 64 | To run it on Travis CI use the following format of ``repository`` field: ``https://$GH_TOKEN@github.com/owner/your-repo.git``. You can generate GH_TOKEN at Github settings and add it to Travis CI manually. For more info just google it ("generate github token", "add environment variable to Travis") :) 65 | 66 | It is generated automatically if you use semantic-release-cli. 67 | 68 | ## semantic-release 69 | 70 | Just add ``deploy-to-github`` to ``semantic-release`` script. 71 | 72 | ``` 73 | "deploy": "deploy-to-git", 74 | "semantic-release": "semantic-release pre && npm run deploy && npm publish && semantic-release post", 75 | ``` 76 | 77 | Tip: You can use a release version in a commit message: 78 | ``` 79 | "commit": "Publising $npm_package_version", 80 | ``` 81 | 82 | ## Real example 83 | 84 | Real example can be found [there](https://github.com/finom/github-embed). The application is compiled via webpack to ``bundle`` folder and pushed to [gh-pages branch](https://github.com/finom/github-embed/tree/gh-pages). 85 | --------------------------------------------------------------------------------