def test_invalidate_config(): with pytest.raises(pipeline.BuildpipeException): config = box_from_yaml(""" stairs: - name: test scope: project command: - make test """) pipeline.compile_steps(config)
def test_project_env(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" stairs: - name: test scope: project buildkite: command: - make test projects: - name: project path: project env: DEPLOYMENT_TYPE: job """) mock_get_changed_files.return_value = {'project/README.md'} mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test env: BUILDPIPE_PROJECT_NAME: project BUILDPIPE_PROJECT_PATH: project BUILDPIPE_STAIR_NAME: test BUILDPIPE_STAIR_SCOPE: project DEPLOYMENT_TYPE: job PROJECT_NAME: project PROJECT_PATH: project STAIR_NAME: test STAIR_SCOPE: project label: test project """).lstrip()
def test_project_substring(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" stairs: - name: test scope: project buildkite: command: - make test projects: - name: project path: project - name: project-api path: project-api """) mock_get_changed_files.return_value = {'project-api/README.md'} mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test env: PROJECT_NAME: project-api PROJECT_PATH: project-api STAIR_NAME: test STAIR_SCOPE: project label: test project-api """).lstrip()
def test_pipeline_exception(): with pytest.raises(pipeline.BuildpipeException): config = box_from_yaml(""" deploy: {} stairs: - name: test scope: project buildkite: command: - make test projects: - name: myproject path: myproject emoji: ":python:" skip_stairs: - foo """) pipeline.compile_steps(config)
def test_block_stairs(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" deploy: branch: master block: block: "Release!" stairs: - name: test scope: project buildkite: command: - make test - name: deploy scope: project deploy: true buildkite: command: - make deploy projects: - name: myproject path: myproject emoji: ":python:" block_stairs: - deploy """) mock_get_changed_files.return_value = { 'origin..HEAD', 'myproject/README.md' } mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test env: BUILDPIPE_PROJECT_NAME: myproject BUILDPIPE_PROJECT_PATH: myproject BUILDPIPE_STAIR_NAME: test BUILDPIPE_STAIR_SCOPE: project label: 'test myproject :python:' - wait - block: Release! - command: - make deploy concurrency: 1 concurrency_group: deploy-myproject env: BUILDPIPE_PROJECT_NAME: myproject BUILDPIPE_PROJECT_PATH: myproject BUILDPIPE_STAIR_NAME: deploy BUILDPIPE_STAIR_SCOPE: project label: 'deploy myproject :python:' """).lstrip()
def test_wait_continue_on_failure(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" stairs: - name: test scope: project continue_on_failure: true buildkite: command: - make test - name: cleanup scope: stair buildkite: command: - make cleanup projects: - name: project path: project """) mock_get_changed_files.return_value = {'project/README.md'} mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test env: BUILDPIPE_PROJECT_NAME: project BUILDPIPE_PROJECT_PATH: project BUILDPIPE_STAIR_NAME: test BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: project PROJECT_PATH: project STAIR_NAME: test STAIR_SCOPE: project label: test project - continue_on_failure: true wait: null - command: - make cleanup env: BUILDPIPE_STAIR_NAME: cleanup BUILDPIPE_STAIR_SCOPE: stair label: cleanup """).lstrip()
def test_tag_groups(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" stairs: - name: step1 scope: project tags: - foo - ["bar", "baz"] buildkite: command: - make step1 projects: - name: project1 path: project1 tags: - bar - baz - name: project2 path: project2 - name: project3 path: project3 skip: - bar """) mock_get_changed_files.return_value = { 'project1/README.md', 'project2/README.md', 'project3/README.md' } mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make step1 env: BUILDPIPE_PROJECT_NAME: project1 BUILDPIPE_PROJECT_PATH: project1 BUILDPIPE_STAIR_NAME: step1 BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: project1 PROJECT_PATH: project1 STAIR_NAME: step1 STAIR_SCOPE: project label: step1 project1 """).lstrip()
def test_no_deploy(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" deploy: branch: master timezone: UTC allowed_hours_regex: '9|1[0-7]' stairs: - name: test scope: project buildkite: command: - make test - name: deploy scope: project deploy: true buildkite: command: - make deploy projects: - name: myproject path: myproject emoji: ":python:" """) mock_get_changed_files.return_value = { 'origin..HEAD', 'myproject/README.md' } mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test env: BUILDPIPE_PROJECT_NAME: myproject BUILDPIPE_PROJECT_PATH: myproject BUILDPIPE_STAIR_NAME: test BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: myproject PROJECT_PATH: myproject STAIR_NAME: test STAIR_SCOPE: project label: 'test myproject :python:' """).lstrip()
def test_skip_stairs(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" stairs: - name: test scope: project buildkite: command: - make test - name: build scope: project buildkite: command: - make build projects: - name: myproject path: myproject emoji: ":python:" skip_stairs: - build """) mock_get_changed_files.return_value = { 'origin..HEAD', 'myproject/README.md' } mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test env: BUILDPIPE_PROJECT_NAME: myproject BUILDPIPE_PROJECT_PATH: myproject BUILDPIPE_STAIR_NAME: test BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: myproject PROJECT_PATH: myproject STAIR_NAME: test STAIR_SCOPE: project label: 'test myproject :python:' """).lstrip()
def test_tags(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" stairs: - name: test-integration scope: project tags: - integration buildkite: command: - make test-integration projects: - name: project1 path: project1 tags: - integration - name: project2 path: project2 - name: project3 path: project3 skip_stairs: - test-integration """) mock_get_changed_files.return_value = { 'project1/README.md', 'project2/README.md', 'project3/README.md' } mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - make test-integration env: PROJECT_NAME: project1 PROJECT_PATH: project1 STAIR_NAME: test-integration STAIR_SCOPE: project label: test-integration project1 """).lstrip()
def test_compile_steps(mock_get_changed_files, mock_get_git_branch): config = box_from_yaml(""" deploy: {} stairs: - name: test scope: project buildkite: command: - cd $$BUILDPIPE_PROJECT_PATH - make test - name: build scope: project emoji: ":docker:" buildkite: agents: - queue=build branches: master command: - cd $$BUILDPIPE_PROJECT_PATH - make build - make publish-image - name: tag scope: stair emoji: ":github:" buildkite: branches: master command: make tag - name: deploy-staging scope: project emoji: ":shipit:" deploy: true buildkite: branches: master command: - cd $$BUILDPIPE_PROJECT_PATH - make deploy-staging - name: deploy-prod scope: project emoji: ":shipit:" deploy: true buildkite: branches: master env: SOME_ENV: "true" command: - cd $$BUILDPIPE_PROJECT_PATH - make deploy-prod projects: - name: pyproject path: pyproject emoji: ":python:" """) mock_get_changed_files.return_value = { 'origin..HEAD', 'pyproject/README.md' } mock_get_git_branch.return_value = 'master' steps = pipeline.compile_steps(config) pipeline_yml = steps_to_yaml(steps) assert pipeline_yml == textwrap.dedent(""" steps: - wait - command: - cd $$BUILDPIPE_PROJECT_PATH - make test env: BUILDPIPE_PROJECT_NAME: pyproject BUILDPIPE_PROJECT_PATH: pyproject BUILDPIPE_STAIR_NAME: test BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: pyproject PROJECT_PATH: pyproject STAIR_NAME: test STAIR_SCOPE: project label: 'test pyproject :python:' - wait - agents: - queue=build branches: master command: - cd $$BUILDPIPE_PROJECT_PATH - make build - make publish-image env: BUILDPIPE_PROJECT_NAME: pyproject BUILDPIPE_PROJECT_PATH: pyproject BUILDPIPE_STAIR_NAME: build BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: pyproject PROJECT_PATH: pyproject STAIR_NAME: build STAIR_SCOPE: project label: 'build pyproject :docker:' - wait - branches: master command: make tag env: BUILDPIPE_STAIR_NAME: tag BUILDPIPE_STAIR_SCOPE: stair label: 'tag :github:' - wait - branches: master command: - cd $$BUILDPIPE_PROJECT_PATH - make deploy-staging concurrency: 1 concurrency_group: deploy-staging-pyproject env: BUILDPIPE_PROJECT_NAME: pyproject BUILDPIPE_PROJECT_PATH: pyproject BUILDPIPE_STAIR_NAME: deploy-staging BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: pyproject PROJECT_PATH: pyproject STAIR_NAME: deploy-staging STAIR_SCOPE: project label: 'deploy-staging pyproject :shipit:' - wait - branches: master command: - cd $$BUILDPIPE_PROJECT_PATH - make deploy-prod concurrency: 1 concurrency_group: deploy-prod-pyproject env: BUILDPIPE_PROJECT_NAME: pyproject BUILDPIPE_PROJECT_PATH: pyproject BUILDPIPE_STAIR_NAME: deploy-prod BUILDPIPE_STAIR_SCOPE: project PROJECT_NAME: pyproject PROJECT_PATH: pyproject SOME_ENV: 'true' STAIR_NAME: deploy-prod STAIR_SCOPE: project label: 'deploy-prod pyproject :shipit:' """).lstrip()