diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..9a7d0a0 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,97 @@ +version: 2 + +aliases: + + - &deploy_ssh_fingerprint "e8:d7:da:b8:6a:fb:75:50:8d:5f:48:61:3c:46:49:50" + + # Shared configuration applied to each job. + - &container_config + working_directory: /app + environment: + + + - &container_config + working_directory: /workspace/code + docker: + - image: integratedexperts/ci-builder + environment: + COMPOSER_ALLOW_SUPERUSER: 1 + DEPLOY_SSH_FINGERPRINT: *deploy_ssh_fingerprint + + - &step_setup_git + run: | + mkdir -p "${HOME}/.ssh/" + echo -e "Host *\n\tStrictHostKeyChecking no\n" > "${HOME}/.ssh/config" + DEPLOY_SSH_FILE="${DEPLOY_SSH_FINGERPRINT//:}" + DEPLOY_SSH_FILE="${HOME}/.ssh/id_rsa_${DEPLOY_SSH_FILE//\"}" + if [ -f "${DEPLOY_SSH_FILE}" ]; then + echo "Found Deploy SSH key file ${DEPLOY_SSH_FILE}" + ssh-add -D > /dev/null + ssh-add "${DEPLOY_SSH_FILE}" + fi + git config --global user.name "$DEPLOY_USER_NAME" + git config --global user.email "$DEPLOY_USER_EMAIL" + +jobs: + build: + <<: *container_config + steps: + - attach_workspace: + at: /workspace + - add_ssh_keys: + fingerprints: + - *deploy_ssh_fingerprint + - *step_setup_git + - checkout + - run: composer validate --ansi --strict + - run: composer install + - run: composer test + - persist_to_workspace: + root: /workspace + paths: + - code + + deploy: + <<: *container_config + steps: + - attach_workspace: + at: /workspace + - add_ssh_keys: + fingerprints: + - *deploy_ssh_fingerprint + - *step_setup_git + - checkout + # Planting test asset file. + - run: touch test-file-$(date "+%Y%m%d-%H%M%S").txt + # Demonstration of deployment in 'force-push' mode. + - run: | + vendor/bin/robo artefact \ + git@github.com:integratedexperts/robo-git-artefact-destination.git \ + --mode=force-push \ + --branch=mode-force-push \ + --report=$HOME/report-mode-force-push.txt \ + --push + DEPLOY_BRANCH=$(sed -n 's/Remote branch://p' $HOME/report-mode-force-push.txt | sed 's/ //g') + echo "Deployed to $DEPLOY_BRANCH" + # Demonstration of deployment in 'branch' mode. + - run: | + vendor/bin/robo artefact \ + git@github.com:integratedexperts/robo-git-artefact-destination.git \ + --mode=branch \ + --branch=mode-branch-[timestamp:Y-m-d_H-i-s] \ + --report=$HOME/report-mode-branch.txt \ + --push + DEPLOY_BRANCH=$(sed -n 's/Remote branch://p' $HOME/report-mode-branch.txt | sed 's/ //g') + echo "Deployed to $DEPLOY_BRANCH" + +workflows: + version: 2 + main: + jobs: + - build + - deploy: + requires: + - build + filters: + branches: + only: master diff --git a/.gitignore b/.gitignore index e4ee8cd..4bbca26 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ vendor artefact -.vagrant -Vagrantfile -.beetbox composer.lock git_* diff --git a/circle.yml b/circle.yml deleted file mode 100644 index e7a2952..0000000 --- a/circle.yml +++ /dev/null @@ -1,50 +0,0 @@ -machine: - php: - version: 7.1.6 - -dependencies: - cache_directories: - - ~/.composer/cache - pre: - - rm /opt/circleci/php/$(phpenv global)/etc/conf.d/xdebug.ini - -test: - pre: - - | - git config --global user.email "$DEPLOY_USER_EMAIL" && git config --global user.name "$DEPLOY_USER_NAME" - mkdir -p ~/.ssh/ && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config - DEPLOY_SSH_FILE="${DEPLOY_SSH_FINGERPRINT//:}" && DEPLOY_SSH_FILE="id_${DEPLOY_SSH_FILE//\"}" && ssh-add -D && ssh-add ~/.ssh/$DEPLOY_SSH_FILE - override: - - composer cs - - composer test - -deployment: - demo: - branch: master - commands: - # Planting test asset file. - - touch test-file-$(date "+%Y%m%d-%H%M%S").txt - - # Demonstration of deployment in 'force-push' mode. - - | - vendor/bin/robo artefact \ - git@github.com:integratedexperts/robo-git-artefact-destination.git \ - --mode=force-push \ - --branch=mode-force-push \ - --report=$HOME/report-mode-force-push.txt \ - --push - - | - DEPLOY_BRANCH=$(sed -n 's/Remote branch://p' $HOME/report-mode-force-push.txt | sed 's/ //g') - echo "Deployed to $DEPLOY_BRANCH" - - # Demonstration of deployment in 'branch' mode. - - | - vendor/bin/robo artefact \ - git@github.com:integratedexperts/robo-git-artefact-destination.git \ - --mode=branch \ - --branch=mode-branch-[timestamp:Y-m-d_H-i-s] \ - --report=$HOME/report-mode-branch.txt \ - --push - - | - DEPLOY_BRANCH=$(sed -n 's/Remote branch://p' $HOME/report-mode-branch.txt | sed 's/ //g') - echo "Deployed to $DEPLOY_BRANCH" diff --git a/composer.json b/composer.json index 41c74d0..084a0ee 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "integratedexperts/robo-git-artefact", "description": "Robo task to push git artefact to remote repository", "type": "robo-tasks", - "license": "GPL-2.0+", + "license": "GPL-2.0-or-later", "authors": [ { "name": "Alex Skrypnyk", @@ -16,7 +16,6 @@ "require-dev": { "squizlabs/php_codesniffer": "2.*", "escapestudios/symfony2-coding-standard": "~2.0", - "beet/box": "^0.7.2", "phpunit/phpunit": "^6.3" }, "scripts": { diff --git a/src/ArtefactTrait.php b/src/ArtefactTrait.php index 7b486d4..94a055a 100644 --- a/src/ArtefactTrait.php +++ b/src/ArtefactTrait.php @@ -209,8 +209,9 @@ protected function prepareArtefact() $this->gitSwitchToBranch($this->src, $this->artefactBranch, true); if (!empty($this->gitignoreFile)) { - $this->replaceGitignore($this->gitignoreFile, $this->src); $this->disableLocalExclude($this->src); + $this->replaceGitignore($this->gitignoreFile, $this->src); + $this->gitUpdateIndex($this->src); $this->removeExcludedFiles($this->src); } @@ -543,6 +544,29 @@ protected function restoreLocalExclude($path) } } + + /** + * Update index for all files. + * + * @param $location + * Path to repository. + */ + protected function gitUpdateIndex($location) + { + $files = $this->fsFinder + ->in($location) + ->ignoreDotFiles(false) + ->notPath('vendor') + ->files(); + + foreach ($files as $file) { + $this->gitCommandRun( + $this->src, + 'update-index --add '.$file + ); + } + } + /** * Remove excluded files. * @@ -556,6 +580,15 @@ protected function restoreLocalExclude($path) */ protected function removeExcludedFiles($location, $gitignore = '.gitignore') { + $gitignoreContent = file_get_contents($location.DIRECTORY_SEPARATOR.$gitignore); + if (!$gitignoreContent) { + $this->printDebug('Unable to load '.$gitignoreContent); + } else { + $this->printDebug('-----.gitignore---------'); + $this->printDebug($gitignoreContent); + $this->printDebug('-----.gitignore---------'); + } + $command = sprintf('ls-files --directory -i --exclude-from=%s %s', $location.DIRECTORY_SEPARATOR.$gitignore, $location); $result = $this->gitCommandRun($location, $command, 'Unable to remove excluded files'); $excludedFiles = array_filter(preg_split('/\R/', $result->getMessage())); diff --git a/tests/BranchTest.php b/tests/BranchTest.php index f5f042f..71d6e92 100644 --- a/tests/BranchTest.php +++ b/tests/BranchTest.php @@ -135,6 +135,7 @@ public function testGitignoreCustom() $this->gitAssertFilesNotExist($this->dst, '3.txt'); // Now, remove the .gitignore and push again. + $this->gitCreateFixtureFile($this->src, '3.txt'); $this->gitRemoveFixtureFile($this->src, 'mygitignore'); $this->gitCommitAll($this->src, 'Commit number 3'); $this->now = time() - rand(1, 10 * 60); diff --git a/tests/CommandTrait.php b/tests/CommandTrait.php index bb31404..7fe03ae 100644 --- a/tests/CommandTrait.php +++ b/tests/CommandTrait.php @@ -383,7 +383,10 @@ protected function gitAssertNoFilesCommitted($path, $expectedFiles, $branch = nu } $expectedFiles = is_array($expectedFiles) ? $expectedFiles : [$expectedFiles]; $committedFiles = $this->gitGetCommittedFiles($path); - $this->assertEquals(count(array_intersect($this->gitGetCommittedFiles($path), $expectedFiles)), 0, sprintf('Committed files: %s', implode(', ', $committedFiles))); + sort($expectedFiles); + sort($committedFiles); + $intersectedFiles = array_intersect($committedFiles, $expectedFiles); + $this->assertEquals(count($intersectedFiles), 0, sprintf("Committed: %s\nExpected: %s\nIntersected: %s", implode(', ', $committedFiles), implode(', ', $expectedFiles), implode(', ', $intersectedFiles))); } protected function assertFixtureCommits($count, $path, $branch, $additionalCommits = [], $assertFiles = true) diff --git a/tests/ForcePushTest.php b/tests/ForcePushTest.php index d3f5f2f..7871c2a 100644 --- a/tests/ForcePushTest.php +++ b/tests/ForcePushTest.php @@ -92,22 +92,31 @@ public function testGitignore() public function testGitignoreCustom() { $this->gitCreateFixtureCommits(2); - $this->gitCreateFixtureFile($this->src, 'uncom_ignored_com.txt'); + $this->gitCreateFixtureFile($this->src, 'uncomignored_com.txt'); + $this->gitCreateFixtureFile($this->src, 'uncom_com.txt'); + + $this->gitCreateFixtureFile($this->src, 'mygitignore', 'uncomignored_com.txt'); - $this->gitCreateFixtureFile($this->src, 'mygitignore', 'uncom_ignored_com.txt'); $this->assertBuildSuccess('--gitignore='.$this->src.DIRECTORY_SEPARATOR.'mygitignore'); $this->assertFixtureCommits(2, $this->dst, 'testbranch', ['Deployment commit']); - $this->gitAssertFilesNotExist($this->dst, 'uncom_ignored_com.txt'); + $this->gitAssertFilesNotExist($this->dst, 'uncomignored_com.txt'); + $this->gitAssertFilesExist($this->dst, 'uncom_com.txt'); // Now, remove the .gitignore and push again. + // We have to create 'uncomignored_com.txt' file since it was rightfully + // removed during previous build run and the source repo branch was not + // reset (uncommitted files would be removed, unless they are excluded + // in .gitignore). + $this->gitCreateFixtureFile($this->src, 'uncomignored_com.txt'); $this->gitRemoveFixtureFile($this->src, 'mygitignore'); $this->gitCommitAll($this->src, 'Commit number 3'); $this->assertBuildSuccess(); $this->assertFixtureCommits(3, $this->dst, 'testbranch', ['Deployment commit'], false); - $this->gitAssertFilesCommitted($this->dst, ['1.txt', '2.txt', 'uncom_ignored_com.txt'], 'testbranch'); - $this->gitAssertFilesExist($this->dst, ['1.txt', '2.txt', 'uncom_ignored_com.txt'], 'testbranch'); + $this->gitAssertFilesCommitted($this->dst, ['1.txt', '2.txt', 'uncomignored_com.txt'], 'testbranch'); + $this->gitAssertFilesExist($this->dst, ['1.txt', '2.txt', 'uncomignored_com.txt'], 'testbranch'); + $this->gitAssertNoFilesCommitted($this->dst, ['uncom_com.txt'], 'testbranch'); } public function testGitignoreCustomRemoveCommittedFiles() @@ -136,6 +145,41 @@ public function testGitignoreCustomRemoveCommittedFiles() $this->gitAssertFilesNotExist($this->dst, ['1.txt', 'ignored_ignored.txt', 'subdir/com_ignored.txt', 'uncom_ignored.txt'], 'testbranch'); } + public function testGitignoreCustomWhitelisting() + { + $this->gitCreateFixtureFile($this->src, '.gitignore', ['ignored_ignored.txt', 'ignored_com.txt']); + + $this->gitCreateFixtureFile($this->src, 'ignored_ignored.txt'); + $this->gitCreateFixtureFile($this->src, 'ignored_com.txt'); + $this->gitCreateFixtureFile($this->src, 'com_com.txt'); + $this->gitCreateFixtureFile($this->src, 'com_ignored.txt'); + $this->gitCreateFixtureCommits(2); + + $this->gitCommitAll($this->src, 'Custom third commit'); + + $this->gitCreateFixtureFile($this->src, 'uncom_ignored.txt'); + $this->gitCreateFixtureFile($this->src, 'uncom_com.txt'); + $this->gitCreateFixtureFile($this->src, 'uncom_del.txt'); + + $this->gitAssertFilesCommitted($this->src, ['1.txt', '2.txt', 'com_com.txt', 'com_ignored.txt']); + $this->gitAssertNoFilesCommitted($this->src, ['ignored_ignored.txt', 'ignored_com.txt', 'uncom_ignored.txt', 'uncom_com.txt', 'uncom_del.txt']); + + // Now, add non-ignored files (whitelisting). + $this->gitCreateFixtureFile($this->src, 'mygitignore', ['/*', '!2.txt', '!ignored_com.txt', '!com_com.txt', '!uncom_com.txt']); + + // Run the build. + $this->assertBuildSuccess('--debug --gitignore='.$this->src.DIRECTORY_SEPARATOR.'mygitignore'); + + $this->assertFixtureCommits(2, $this->dst, 'testbranch', ['Custom third commit', 'Deployment commit'], false); + + $this->gitAssertFilesCommitted($this->dst, ['2.txt', 'com_com.txt', 'ignored_com.txt', 'uncom_com.txt'], 'testbranch'); + + $this->gitAssertNoFilesCommitted($this->dst, ['1.txt', 'ignored_ignored.txt', 'com_ignored.txt', 'uncom_ignored.txt', 'uncom_del.txt'], 'testbranch'); + + $this->gitAssertFilesExist($this->dst, ['2.txt', 'ignored_com.txt', 'com_com.txt', 'uncom_com.txt'], 'testbranch'); + $this->gitAssertFilesNotExist($this->dst, ['1.txt', 'ignored_ignored.txt', 'com_ignored.txt', 'uncom_ignored.txt', 'uncom_del.txt'], 'testbranch'); + } + public function testBuildTag() { $this->gitCreateFixtureCommits(2);