diff --git a/.travis.yml b/.travis.yml index e9944753..626046c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,11 +27,7 @@ jobs: - npm install -g now - python tests/fixtures.py fixtures.db fixtures.json - export ALIAS=`echo $TRAVIS_COMMIT | cut -c 1-7` - - echo "{\"name\":\"datasette-latest-$ALIAS\",\"alias\":\"latest.datasette.io\"}" > now.json - - datasette publish now fixtures.db -m fixtures.json --token=$NOW_TOKEN --branch=$TRAVIS_COMMIT --version-note=$TRAVIS_COMMIT --name=datasette-latest-$ALIAS - - now --target production --token=$NOW_TOKEN - - echo "{\"name\":\"datasette-latest-$ALIAS\",\"alias\":\"$ALIAS.datasette.io\"}" > now.json - - now --target production --token=$NOW_TOKEN + - datasette publish now fixtures.db -m fixtures.json --token=$NOW_TOKEN --branch=$TRAVIS_COMMIT --version-note=$TRAVIS_COMMIT --name=datasette-latest-$ALIAS --alias=latest.datasette.io --alias=$ALIAS.datasette.io - stage: release tagged version if: tag IS present python: 3.6 @@ -39,8 +35,7 @@ jobs: - npm install -g now - export ALIAS=`echo $TRAVIS_COMMIT | cut -c 1-7` - export TAG=`echo $TRAVIS_TAG | sed 's/\./-/g' | sed 's/.*/v&/'` - - echo "{\"name\":\"datasette-latest-$ALIAS\",\"alias\":\"$TAG.datasette.io\"}" > now.json - - now --target production --token=$NOW_TOKEN + - now alias $ALIAS.datasette.io $TAG.datasette.io --token=$NOW_TOKEN # Build and release to Docker Hub - docker login -u $DOCKER_USER -p $DOCKER_PASS - export REPO=datasetteproject/datasette diff --git a/datasette/publish/now.py b/datasette/publish/now.py index 4670b142..5c5a3967 100644 --- a/datasette/publish/now.py +++ b/datasette/publish/now.py @@ -1,7 +1,7 @@ from datasette import hookimpl import click import json -from subprocess import call +from subprocess import run, PIPE from .common import ( add_common_publish_arguments_and_options, @@ -22,7 +22,7 @@ def publish_subcommand(publish): ) @click.option("--force", is_flag=True, help="Pass --force option to now") @click.option("--token", help="Auth token to use for deploy") - @click.option("--alias", help="Desired alias e.g. yoursite.now.sh") + @click.option("--alias", multiple=True, help="Desired alias e.g. yoursite.now.sh") @click.option("--spatialite", is_flag=True, help="Enable SpatialLite extension") def now( files, @@ -77,20 +77,23 @@ def publish_subcommand(publish): }, ): now_json = {"version": 1} - if alias: - now_json["alias"] = alias - open("now.json", "w").write(json.dumps(now_json)) + open("now.json", "w").write(json.dumps(now_json, indent=4)) args = [] if force: args.append("--force") if token: args.append("--token={}".format(token)) if args: - call(["now"] + args) + done = run(["now"] + args, stdout=PIPE) else: - call("now") + done = run("now", stdout=PIPE) + deployment_url = done.stdout if alias: - alias_args = ["alias"] - if token: - alias_args.append("--token={}".format(token)) - call(["now"] + alias_args) + # I couldn't get --target=production working, so I call + # 'now alias' with arguments directly instead - but that + # means I need to figure out what URL it was deployed to. + for single_alias in alias: + # Because --alias can be specified multiple times + run(["now", "alias", deployment_url, single_alias]) + else: + print(deployment_url.decode("latin1")) diff --git a/tests/test_publish_heroku.py b/tests/test_publish_heroku.py index 1e8d4bd6..08fdeaea 100644 --- a/tests/test_publish_heroku.py +++ b/tests/test_publish_heroku.py @@ -60,17 +60,3 @@ def test_publish_heroku(mock_call, mock_check_output, mock_which): mock_call.assert_called_once_with( ["heroku", "builds:create", "-a", "f", "--include-vcs-ignore"] ) - - -@mock.patch("shutil.which") -@mock.patch("datasette.publish.now.call") -def test_publish_now_force_token(mock_call, mock_which): - mock_which.return_value = True - runner = CliRunner() - with runner.isolated_filesystem(): - open("test.db", "w").write("data") - result = runner.invoke( - cli.cli, ["publish", "now", "test.db", "--force", "--token=X"] - ) - assert 0 == result.exit_code - mock_call.assert_called_once_with(["now", "--force", "--token=X"]) diff --git a/tests/test_publish_now.py b/tests/test_publish_now.py index 940a8292..aa6ef7cf 100644 --- a/tests/test_publish_now.py +++ b/tests/test_publish_now.py @@ -1,6 +1,7 @@ from click.testing import CliRunner from datasette import cli from unittest import mock +import subprocess @mock.patch("shutil.which") @@ -24,20 +25,20 @@ def test_publish_now_invalid_database(mock_which): @mock.patch("shutil.which") -@mock.patch("datasette.publish.now.call") -def test_publish_now(mock_call, mock_which): +@mock.patch("datasette.publish.now.run") +def test_publish_now(mock_run, mock_which): mock_which.return_value = True runner = CliRunner() with runner.isolated_filesystem(): open("test.db", "w").write("data") result = runner.invoke(cli.cli, ["publish", "now", "test.db"]) assert 0 == result.exit_code - mock_call.assert_called_once_with("now") + mock_run.assert_called_once_with("now", stdout=subprocess.PIPE) @mock.patch("shutil.which") -@mock.patch("datasette.publish.now.call") -def test_publish_now_force_token(mock_call, mock_which): +@mock.patch("datasette.publish.now.run") +def test_publish_now_force_token(mock_run, mock_which): mock_which.return_value = True runner = CliRunner() with runner.isolated_filesystem(): @@ -46,4 +47,28 @@ def test_publish_now_force_token(mock_call, mock_which): cli.cli, ["publish", "now", "test.db", "--force", "--token=X"] ) assert 0 == result.exit_code - mock_call.assert_called_once_with(["now", "--force", "--token=X"]) + mock_run.assert_called_once_with( + ["now", "--force", "--token=X"], stdout=subprocess.PIPE + ) + + +@mock.patch("shutil.which") +@mock.patch("datasette.publish.now.run") +def test_publish_now_multiple_aliases(mock_run, mock_which): + mock_which.return_value = True + mock_run.return_value = mock.Mock(0) + mock_run.return_value.stdout = b"https://demo.example.com/" + runner = CliRunner() + with runner.isolated_filesystem(): + open("test.db", "w").write("data") + runner.invoke( + cli.cli, + ["publish", "now", "test.db", "--alias", "alias1", "--alias", "alias2"], + ) + mock_run.assert_has_calls( + [ + mock.call("now", stdout=subprocess.PIPE), + mock.call(["now", "alias", b"https://demo.example.com/", "alias1"]), + mock.call(["now", "alias", b"https://demo.example.com/", "alias2"]), + ] + )