diff --git a/cmd/ddev/cmd/config_test.go b/cmd/ddev/cmd/config_test.go index 7e01f39fb9b..c436d292956 100644 --- a/cmd/ddev/cmd/config_test.go +++ b/cmd/ddev/cmd/config_test.go @@ -34,6 +34,11 @@ func TestCmdConfigHooks(t *testing.T) { app.Hooks = map[string][]ddevapp.YAMLTask{"post-config": {{"exec-host": "touch hello-post-config-" + app.Name}}, "pre-config": {{"exec-host": "touch hello-pre-config-" + app.Name}}} err = app.WriteConfig() assert.NoError(err) + // Make sure we get rid of this for other uses + defer func() { + app.Hooks = nil + _ = app.WriteConfig() + }() _, err = exec.RunCommand(DdevBin, []string{"config", "--project-type=" + app.Type}) assert.NoError(err) diff --git a/cmd/ddev/cmd/root.go b/cmd/ddev/cmd/root.go index 8c5edb853b8..0722d0d6c10 100644 --- a/cmd/ddev/cmd/root.go +++ b/cmd/ddev/cmd/root.go @@ -26,9 +26,11 @@ var ( // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ - Use: "ddev", - Short: "DDEV-Local local development environment", - Long: "Create and maintain a local web development environment.", + Use: "ddev", + Short: "DDEV-Local local development environment", + Long: `Create and maintain a local web development environment. +Docs: https://ddev.readthedocs.io +Support: https://ddev.readthedocs.io/en/stable/#support`, Version: version.DdevVersion, PersistentPreRun: func(cmd *cobra.Command, args []string) { ignores := []string{"version", "config", "hostname", "help", "auth-pantheon", "import-files"} diff --git a/cmd/ddev/cmd/share_test.go b/cmd/ddev/cmd/share_test.go index 2880681a843..5551ce735eb 100644 --- a/cmd/ddev/cmd/share_test.go +++ b/cmd/ddev/cmd/share_test.go @@ -35,6 +35,11 @@ func TestShareCmd(t *testing.T) { require.NoError(t, err) scanner := bufio.NewScanner(cmdReader) + // Make absolutely sure the ngrok process gets killed off, because otherwise + // the testbot (windows) can remain occupied forever. + // nolint: errcheck + defer pKill(cmd) + // Read through the ngrok json output until we get the url it has opened go func() { for scanner.Scan() { @@ -54,7 +59,12 @@ func TestShareCmd(t *testing.T) { // If URL is provided, try to hit it and look for expected response if url, ok := logData["url"]; ok { resp, err := http.Get(url + site.Safe200URIWithExpectation.URI) - assert.NoError(err) + if err != nil { + t.Logf("http.Get on url=%s failed, err=%v", url+site.Safe200URIWithExpectation.URI, err) + err = pKill(cmd) + assert.NoError(err) + return + } //nolint: errcheck defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) diff --git a/docs/developers/buildkite-testmachine-setup.md b/docs/developers/buildkite-testmachine-setup.md index 77eec8bce91..9e95124ad98 100644 --- a/docs/developers/buildkite-testmachine-setup.md +++ b/docs/developers/buildkite-testmachine-setup.md @@ -4,8 +4,8 @@ We are using [Buildkite](https://buildkite.com/drud) for Windows and macOS testi ## Windows Test Agent Setup: -0. Create the user "testbot" on the machine. The password should be the password of testbot@drud.com. -1. Install [chocolatey](https://chocolatey.org/) +0. Create the user "testbot" on the machine. The password should be the password of testbot@drud.com (available in 1password) +1. Install [chocolatey](https://chocolatey.org/docs/installation) with an administrative cmd window `@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"` 2. Install golang/mysql-cli/make/git/docker-ce/nssm with `choco install -y git mysql-cli golang make docker-desktop nssm GoogleChrome zip jq composer cmder netcat ddev mkcert` (If docker-toolbox, use that instead; you may have to download the release separately to get correct version.) 3. `mkcert -install` 3. Enable gd, fileinfo, and curl extensions in /c/tools/php73/php.ini @@ -44,11 +44,11 @@ We are using [Buildkite](https://buildkite.com/drud) for Windows and macOS testi 0. Create the user "testbot" on the machine. The password should be the password of testbot@drud.com. 1. Change the name of the machine to something in keeping with current style. Maybe `testbot-macstadium-macos-3`. -1. Install [homebrew](https://brew.sh/) `xcode select --install` and `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` -2. Install golang/git/docker with `brew cask install iterm2 google-chrome docker nosleep && brew tap buildkite/buildkite && brew tap drud/ddev && brew install golang git buildkite-agent mariadb jq p7zip bats-core composer ddev netcat mkcert` +1. Install [homebrew](https://brew.sh/) `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` +2. Install golang/git/docker with `brew cask install iterm2 google-chrome docker nosleep && brew tap buildkite/buildkite && brew tap drud/ddev && brew install golang git buildkite-agent mariadb jq p7zip bats-core composer ddev netcat mkcert && brew cask install ngrok` 3. `mkcert -install` 3. Run docker manually and go through its configuration routine. -3. Run `iterm`. On Mojave it will prompt for requiring full disk access permissions, follow through with that. +3. Run `iterm`. On Mojave it may prompt for requiring full disk access permissions, follow through with that. 3. Set up nfsd by running `macos_ddev_nfs_setup.sh` 4. Add the path `/private/var` to `/etc/exports` and `sudo nfsd restart`. 5. Edit the buildkite-agent.cfg in /usr/local/etc/buildkite-agent.cfg to add diff --git a/docs/developers/release-checklist.md b/docs/developers/release-checklist.md index acdb242696e..842dd3d4c2e 100644 --- a/docs/developers/release-checklist.md +++ b/docs/developers/release-checklist.md @@ -1,17 +1,17 @@ ## `ddev` Release Checklist -- [ ] Create provisional tagged images. `git fetch upstream && git checkout upstream/master && cd containers` and `for item in *; do pushd $item; make push VERSION= DOCKER_ARGS=--no-cache ; popd; done` -- [ ] Update the default container versions in `pkg/version/version.go` and create a pull request -- [ ] Ensure all updates have been merged into the master branch -- [ ] Create a tag for the new version according to the instructions below, initiating a tag build -- [ ] Build and push artifacts with the .circleci/trigger_release.sh tool: `.circleci/trigger_release.sh --release-tag=v1.7.1 --circleci-token=circleToken900908b3443ea58316baf928b --github-token=githubPersonalToken853ae6f72c40525cd21036f742904a --windows-signing-password=windowscodepassword | jq -r 'del(.circle_yml)' | jq -r 'del(.circle_yml)'` -- [ ] Add the commit list (`git log vXXX..vYYY --oneline --decorate=no`) to the release page -- [ ] Update the `ddev` [Homebrew formula](https://github.com/drud/homebrew-ddev) with the source .tar.gz and SHA checksum of the tarball and the bottle builds and tarballs. The bottles for macOS (sierra) and x86_64_linux are built and pushed to the release page automatically by the CircleCI release build process. -- [ ] Test `brew upgrade ddev` and make sure ddev is the right version and behaves well -- [ ] Test the Windows installer and confirm it's signed correctly -- [ ] Update the release page with specifics about the current release -- [ ] Publish the release (unmark it as "prerelease") -- [ ] Download the ddev_chocolatey tarball and extract it. cd into the extraction directory and push it to chocolatey with `docker run --rm -v $PWD:/tmp/chocolatey -w /tmp/chocolatey linuturk/mono-choco push -s https://push.chocolatey.org/ --api-key=choco-apikey-a720-7890909913f7` (Although this ought to be done by the release build process on CircleCI it's not successful as of v1.7.1.) -- [ ] On [ReadTheDocs](https://readthedocs.org/projects/ddev/builds) click the button to "build version" "latest". Then on [versions](https://readthedocs.org/projects/ddev/versions/) page make sure that "stable" reflects the hash of the new version. +1. Create provisional tagged images. `git fetch upstream && git checkout upstream/master && cd containers` and `for item in *; do pushd $item; make push VERSION= DOCKER_ARGS=--no-cache ; popd; done` +2. Update the default container versions in `pkg/version/version.go` and create a pull request +3. Ensure all updates have been merged into the master branch +4. Create a tag for the new version according to the instructions below, initiating a tag build +5. Build and push artifacts with the .circleci/trigger_release.sh tool: `.circleci/trigger_release.sh --release-tag=v1.7.1 --circleci-token=circleToken900908b3443ea58316baf928b --github-token=githubPersonalToken853ae6f72c40525cd21036f742904a --windows-signing-password=windowscodepassword | jq -r 'del(.circle_yml)' | jq -r 'del(.circle_yml)'` +6. Add the commit list (`git log vXXX..vYYY --oneline --decorate=no`) to the release page +7. Update the `ddev` homebrew formulas (ddev-edge and ddev) as necessary, https://github.com/drud/homebrew-ddev and https://github.com/drud/homebrew-ddev-edge, with the source .tar.gz and SHA checksum of the tarball and the bottle builds and tarballs. The bottles and checksums for macOS (sierra) and x86_64_linux are built and pushed to the release page automatically by the CircleCI release build process. +8. Test `brew upgrade ddev` both on macOS and Linux and make sure ddev is the right version and behaves well +9. Test the Windows installer and confirm it's signed correctly +10. Update the release page with specifics about the current release +11. Publish the release (unmark it as "prerelease") +12. Download the ddev_chocolatey tarball and extract it. cd into the extraction directory and push it to chocolatey with `docker run --rm -v $PWD:/tmp/chocolatey -w /tmp/chocolatey linuturk/mono-choco push -s https://push.chocolatey.org/ --api-key=choco-apikey-a720-7890909913f7` (Although this ought to be done by the release build process on CircleCI it's not successful as of v1.7.1.) +13. On [ReadTheDocs](https://readthedocs.org/projects/ddev/builds) click the button to "build version" "latest". Then on [versions](https://readthedocs.org/projects/ddev/versions/) page make sure that "stable" reflects the hash of the new version. ### Creating a Tag diff --git a/docs/index.md b/docs/index.md index 24f6910518c..36c67daf118 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,11 +28,13 @@ Docker and docker-compose are required before anything will work with ddev. This ### Homebrew/Linuxbrew - macOS/Linux -For macOS and Linux users, we recommend installing and upgrading via [homebrew](https://brew.sh/) (macOS) or [Linuxbrew](http://linuxbrew.sh/) (Linux): +For macOS and Linux users, we recommend installing and upgrading via [homebrew](https://brew.sh/) (macOS) or [Homebrew on Linux](https://docs.brew.sh/Homebrew-on-Linux) (Linux): ``` brew tap drud/ddev && brew install ddev ``` +If you would like more frequent "edge" releases then use `brew tap drud/ddev-edge` instead. + (Optional) As a one-time initialization, run `mkcert -install`. Linux users may have to take additional actions as discussed below in "Linux `mkcert -install` additional instructions". Later, to upgrade to a newer version of ddev, run: diff --git a/pkg/ddevapp/composer_test.go b/pkg/ddevapp/composer_test.go index bcc7538a23d..faf66267654 100644 --- a/pkg/ddevapp/composer_test.go +++ b/pkg/ddevapp/composer_test.go @@ -43,6 +43,11 @@ func TestComposer(t *testing.T) { //nolint: errcheck defer app.Stop(true, false) app.Hooks = map[string][]ddevapp.YAMLTask{"post-composer": {{"exec-host": "touch hello-post-composer-" + app.Name}}, "pre-composer": {{"exec-host": "touch hello-pre-composer-" + app.Name}}} + // Make sure we get rid of this for other uses + defer func() { + app.Hooks = nil + _ = app.WriteConfig() + }() err = app.Start() assert.NoError(err) _, _, err = app.Composer([]string{"install"}) diff --git a/pkg/ddevapp/config_test.go b/pkg/ddevapp/config_test.go index ec194767d68..27a5a91be4d 100644 --- a/pkg/ddevapp/config_test.go +++ b/pkg/ddevapp/config_test.go @@ -696,7 +696,7 @@ func TestPHPOverrides(t *testing.T) { switchDir := site.Chdir() defer switchDir() - runTime := testcommon.TimeTrack(time.Now(), fmt.Sprintf("%s PHPOverrides", site.Name)) + runTime := testcommon.TimeTrack(time.Now(), fmt.Sprintf("%s %s", site.Name, t.Name())) // Copy test overrides into the project .ddev directory err := fileutil.CopyDir(filepath.Join(testDir, "testdata/TestPHPOverrides/.ddev/php"), filepath.Join(site.Dir, ".ddev/php")) diff --git a/pkg/ddevapp/ddevapp_test.go b/pkg/ddevapp/ddevapp_test.go index f4e393d1896..59ffe3fa07d 100644 --- a/pkg/ddevapp/ddevapp_test.go +++ b/pkg/ddevapp/ddevapp_test.go @@ -694,6 +694,8 @@ func TestDdevImportDB(t *testing.T) { _ = os.RemoveAll("hello-post-import-db-" + app.Name) } // We don't want all the projects running at once. + app.Hooks = nil + _ = app.WriteConfig() err = app.Stop(true, false) assert.NoError(err) @@ -1066,6 +1068,8 @@ func TestDdevRestoreSnapshot(t *testing.T) { assert.Error(err) assert.Contains(err.Error(), "is not compatible") + app.Hooks = nil + _ = app.WriteConfig() err = app.Stop(true, false) assert.NoError(err) @@ -1363,6 +1367,10 @@ func TestDdevExec(t *testing.T) { assert.NoError(err) app.Hooks = map[string][]ddevapp.YAMLTask{"post-exec": {{"exec-host": "touch hello-post-exec-" + app.Name}}, "pre-exec": {{"exec-host": "touch hello-pre-exec-" + app.Name}}} + defer func() { + app.Hooks = nil + _ = app.WriteConfig() + }() startErr := app.StartAndWaitForSync(0) if startErr != nil { @@ -1567,8 +1575,11 @@ func TestDdevPause(t *testing.T) { err = app.StartAndWaitForSync(0) app.Hooks = map[string][]ddevapp.YAMLTask{"post-pause": {{"exec-host": "touch hello-post-pause-" + app.Name}}, "pre-pause": {{"exec-host": "touch hello-pre-pause-" + app.Name}}} - //nolint: errcheck - defer app.Stop(true, false) + defer func() { + app.Hooks = nil + _ = app.WriteConfig() + _ = app.Stop(true, false) + }() require.NoError(t, err) err = app.Pause() assert.NoError(err) @@ -1646,8 +1657,11 @@ func TestDdevDescribe(t *testing.T) { app.Hooks = map[string][]ddevapp.YAMLTask{"post-describe": {{"exec-host": "touch hello-post-describe-" + app.Name}}, "pre-describe": {{"exec-host": "touch hello-pre-describe-" + app.Name}}} startErr := app.StartAndWaitForSync(0) - //nolint: errcheck - defer app.Stop(true, false) + defer func() { + _ = app.Stop(true, false) + app.Hooks = nil + _ = app.WriteConfig() + }() // If we have a problem starting, get the container logs and output. if startErr != nil { out, logsErr := app.CaptureLogs("web", false, "") diff --git a/pkg/ddevapp/pantheon_test.go b/pkg/ddevapp/pantheon_test.go index 7b6625f1726..bdb64bc4217 100644 --- a/pkg/ddevapp/pantheon_test.go +++ b/pkg/ddevapp/pantheon_test.go @@ -183,6 +183,8 @@ func TestPantheonPull(t *testing.T) { err = os.Remove("hello-post-pull-" + app.Name) assert.NoError(err) + app.Hooks = nil + _ = app.WriteConfig() err = app.Stop(true, false) assert.NoError(err) }