diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index e805e56..36c8411 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -7,6 +7,8 @@ on: push: branches: - master + tags: + - "v*" schedule: - cron: "25 5 * * *" @@ -41,14 +43,19 @@ jobs: - name: "Tests" env: PR_BRANCH: ${{ github.event.pull_request.base.ref }} - PUSH_REF: ${{ github.event.push.ref }} + REF: ${{ github.ref }} EVENT: ${{ github.event_name }} #EVENT_INFO: ${{ toJson(github.event) }} # useful debug - BRANCH: "${{github.event.pull_request.base.ref}}${{github.event.push.ref}}" run: | + if [ "$EVENT" != "pull_request" ]; then + BRANCH=$REF + else + BRANCH=$PR_BRANCH + fi + echo "Generic: $GITHUB_REF" + echo "PUSH_REF: $PUSH_REF" echo "EVENT: $EVENT" echo "BRANCH: $BRANCH" python -c "import autorelease" autorelease-release -h - python release_check.py --branch $BRANCH --event $EVENT \ - --allow-patch-skip + python release_check.py diff --git a/autorelease-travis.yml b/autorelease-travis.yml index 01ffa0a..bbd4d90 100644 --- a/autorelease-travis.yml +++ b/autorelease-travis.yml @@ -1,4 +1,4 @@ -# AUTORELEASE v0.2.3 +# AUTORELEASE v0.2.4.dev0 # for nonrelease, use @master # for release, use v${VERSION}, e.g., v1.0.0 stages: @@ -9,7 +9,7 @@ stages: - deploy pypi import: - - dwhswenson/autorelease:travis_stages/deploy_testpypi.yml@v0.2.3 - - dwhswenson/autorelease:travis_stages/test_testpypi.yml@v0.2.3 - - dwhswenson/autorelease:travis_stages/cut_release.yml@v0.2.3 - - dwhswenson/autorelease:travis_stages/deploy_pypi.yml@v0.2.3 + - dwhswenson/autorelease:travis_stages/deploy_testpypi.yml@master + - dwhswenson/autorelease:travis_stages/test_testpypi.yml@master + - dwhswenson/autorelease:travis_stages/cut_release.yml@master + - dwhswenson/autorelease:travis_stages/deploy_pypi.yml@master diff --git a/autorelease/check_runners.py b/autorelease/check_runners.py index 1b59af4..5de6e6a 100644 --- a/autorelease/check_runners.py +++ b/autorelease/check_runners.py @@ -1,5 +1,6 @@ from __future__ import print_function import sys +import os import textwrap import argparse import packaging.version as vers @@ -83,6 +84,26 @@ def _reasonable_desired_version_test(self, allow_equal, ) ] + @staticmethod + def _get_branch_name(branch_name): + if branch_name.startswith('refs/heads/'): + branch = branch_name[11:] + elif branch_name.startswith('refs/tags/'): + branch = branch_name[10:] + else: + branch = branch_name + + return branch + + def select_tests(self): + print(os.environ.get("GITHUB_ACTION")) + if os.environ.get("GITHUB_ACTION", None): + tests = self.select_test_from_github_env() + else: + tests = self.select_tests_from_sysargs() + return tests + + def select_tests_from_sysargs(self): # TODO: this can be cleaned up by separating reusable parts parser = argparse.ArgumentParser() @@ -91,14 +112,42 @@ def select_tests_from_sysargs(self): parser.add_argument('--allow-patch-skip', action='store_true', default=False) opts = parser.parse_args() - if opts.branch in self.release_branches: + + branch = self._get_branch_name(opts.branch) + return self.select_tests_from_branch_event(branch, opts.event, + opts.allow_patch_skip) + + def select_test_from_github_env(self): + parser = argparse.ArgumentParser() + parser.add_argument('--allow-patch-skip', action='store_true', + default=False) + opts = parser.parse_args() + event = os.environ.get("GITHUB_EVENT_NAME", None) + ref = os.environ.get("GITHUB_REF", None) + pr_ref = os.environ.get("GITHUB_BASE_REF", None) + print(ref, pr_ref) + print(os.environ.get("GITHUB_HEAD_REF", None)) + if event == "pull_request" and pr_ref is not None: + branch = pr_ref + elif event != "pull_request": + branch = ref + else: + raise RuntimeError("PR without branch?") + print(branch, event) + return self.select_tests_from_branch_event(branch, event, + opts.allow_patch_skip) + + + def select_tests_from_branch_event(self, branch, event, allow_patch_skip): + if branch in self.release_branches: print("TESTING AS RELEASE") - allow_equal = (opts.event == 'cron' - or opts.branch == self.tag_branch) + allow_equal = (event == 'cron' + or event == 'schedule' + or branch == self.tag_branch) tests = (self.tests + self._reasonable_desired_version_test( allow_equal=allow_equal, - allow_patch_skip=opts.allow_patch_skip) + allow_patch_skip=allow_patch_skip) + self._is_release_tests(expected=True)) else: print("TESTING AS NONRELEASE") diff --git a/autorelease/gh_actions_stages/autorelease-default-env.sh b/autorelease/gh_actions_stages/autorelease-default-env.sh new file mode 100644 index 0000000..74dd461 --- /dev/null +++ b/autorelease/gh_actions_stages/autorelease-default-env.sh @@ -0,0 +1,5 @@ +INSTALL_AUTORELEASE="python -m pip install autorelease==0.2.3" +if [ -f autorelease-env.sh ]; then + source autorelease-env.sh +fi + diff --git a/autorelease/gh_actions_stages/autorelease-deploy.yml b/autorelease/gh_actions_stages/autorelease-deploy.yml new file mode 100644 index 0000000..9a8f03b --- /dev/null +++ b/autorelease/gh_actions_stages/autorelease-deploy.yml @@ -0,0 +1,33 @@ +name: Autorelease +on: + release: + types: [published] + +jobs: + deploy_pypi: + runs-on: ubuntu-latest + name: "Deploy to PyPI" + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.x" + - run: | # TODO: move this to an action + source ./.github/workflows/autorelease-default-env.sh + if [ -f "autorelease-env.sh" ]; then + cat autorelease-env.sh >> $GITHUB_ENV + fi + eval $INSTALL_AUTORELEASE + name: "Install autorelease" + - run: | + python -m pip install twine wheel + name: "Install release tools" + - run: | + python setup.py sdist bdist_wheel + twine check dist/* + name: "Build and check package" + - uses: pypa/gh-action-pypi-publish@master + with: + password: ${{ secrets.pypi_password }} + name: "Deploy to pypi" + diff --git a/autorelease/gh_actions_stages/autorelease-gh-rel.yml b/autorelease/gh_actions_stages/autorelease-gh-rel.yml new file mode 100644 index 0000000..bb5cd27 --- /dev/null +++ b/autorelease/gh_actions_stages/autorelease-gh-rel.yml @@ -0,0 +1,29 @@ +name: Autorelease +on: + push: + branches: + - stable + +jobs: + release-gh: + runs-on: ubuntu-latest + name: "Cut release" + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.7" + - run: | # TODO: move this to an action + source ./.github/workflows/autorelease-default-env.sh + if [ -f "autorelease-env.sh" ]; then + cat autorelease-env.sh >> $GITHUB_ENV + fi + eval $INSTALL_AUTORELEASE + name: "Install autorelease" + - run: | + VERSION=`python setup.py --version` + PROJECT=`python setup.py --name` + echo $PROJECT $VERSION + autorelease-release --project $PROJECT --version $VERSION --token $AUTORELEASE_TOKEN + env: + AUTORELEASE_TOKEN: ${{ secrets.AUTORELEASE_TOKEN }} diff --git a/autorelease/gh_actions_stages/autorelease-prep.yml b/autorelease/gh_actions_stages/autorelease-prep.yml new file mode 100644 index 0000000..4967413 --- /dev/null +++ b/autorelease/gh_actions_stages/autorelease-prep.yml @@ -0,0 +1,60 @@ +name: "Autorelease" +on: + pull_request: + branches: + - stable + +defaults: + run: + shell: bash + +jobs: + deploy_testpypi: + runs-on: ubuntu-latest + name: "Deployment test" + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.x" + - run: | # TODO: move this to an action + source ./.github/workflows/autorelease-default-env.sh + if [ -f "autorelease-env.sh" ]; then + cat autorelease-env.sh >> $GITHUB_ENV + fi + eval $INSTALL_AUTORELEASE + name: "Install autorelease" + - run: | + python -m pip install twine wheel + name: "Install release tools" + - run: | + bump-dev-version + python setup.py --version + name: "Bump testpypi dev version" + - run: | + python setup.py sdist bdist_wheel + twine check dist/* + name: "Build and check package" + - uses: pypa/gh-action-pypi-publish@master + with: + password: ${{ secrets.testpypi_password }} + repository_url: https://test.pypi.org/legacy/ + name: "Deploy to testpypi" + test_testpypi: + runs-on: ubuntu-latest + name: "Test deployed" + needs: deploy_testpypi + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.x" + - run: | # TODO: move this to an action + source ./.github/workflows/autorelease-default-env.sh + if [ -f "autorelease-env.sh" ]; then + cat autorelease-env.sh >> $GITHUB_ENV + fi + eval $INSTALL_AUTORELEASE + name: "Install autorelease" + - run: test-testpypi + diff --git a/autorelease/scripts/cli.py b/autorelease/scripts/cli.py new file mode 100644 index 0000000..624d90b --- /dev/null +++ b/autorelease/scripts/cli.py @@ -0,0 +1,22 @@ +import click + +from autorelease.scripts.vendor import vendor_actions + +@click.group() +def cli(): + pass + + +@click.group() +def vendor(): + pass + +@vendor.command() +def actions(): + print("vendoring actions") + vendor_actions(base_path='.') + +cli.add_command(vendor) + +if __name__ == "__main__": + cli() diff --git a/autorelease/scripts/vendor.py b/autorelease/scripts/vendor.py new file mode 100644 index 0000000..787415d --- /dev/null +++ b/autorelease/scripts/vendor.py @@ -0,0 +1,23 @@ +import pkg_resources +import pathlib +import shutil + +import click + +def vendor(resources, base_path, relative_target_dir): + for resource in resources: + orig_loc = pkg_resources.resource_filename('autorelease', resource) + name = pathlib.Path(orig_loc).name + target_dir = base_path / relative_target_dir + target_dir.mkdir(parents=True, exist_ok=True) + target_loc = base_path / relative_target_dir / name + # print(f"cp {orig_loc} {target_loc}") + shutil.copy(orig_loc, target_loc) + +def vendor_actions(base_path): + resources = ['autorelease-default-env.sh', 'autorelease-prep.yml', + 'autorelease-gh-rel.yml', 'autorelease-deploy.yml'] + resources = ['gh_actions_stages/' + res for res in resources] + target_dir = pathlib.Path('.github/workflows') + vendor(resources, base_path, target_dir) + diff --git a/devtools/conda-recipe/meta.yaml b/devtools/conda-recipe/meta.yaml index f1110f4..9d6b7d7 100644 --- a/devtools/conda-recipe/meta.yaml +++ b/devtools/conda-recipe/meta.yaml @@ -1,7 +1,7 @@ package: name: autorelease # add ".dev0" for unreleased versions - version: "0.2.3" + version: "0.2.4" source: path: ../../ diff --git a/release_check.py b/release_check.py index 12f73af..dfd7d83 100644 --- a/release_check.py +++ b/release_check.py @@ -27,7 +27,7 @@ repo_path='.' ) checker.release_branches = RELEASE_BRANCHES + [RELEASE_TAG] - tests = checker.select_tests_from_sysargs() + tests = checker.select_tests() skip = [] #skip = [checker.git_repo_checks.reasonable_desired_version] diff --git a/script_stages/test-testpypi b/script_stages/test-testpypi index aa3e6c9..7b48618 100644 --- a/script_stages/test-testpypi +++ b/script_stages/test-testpypi @@ -25,7 +25,7 @@ if [ -n "$AUTORELEASE_TEST_TESTPYPI" ]; then else python -m pip install pytest cd ~ - python -c "import $PACKAGE_IMPORT_NAME" + python -c "import $PACKAGE_IMPORT_NAME" || exit 1 py.test --pyargs $PACKAGE_IMPORT_NAME || exit 1 fi diff --git a/setup.cfg b/setup.cfg index 12970fa..ea3c613 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = autorelease -version = 0.2.3 +version = 0.2.4 # version should end in .dev0 if this isn't to be released short_description = Tools to keep the release process clean. description = Tools to keep the release process clean. @@ -35,11 +35,16 @@ install_requires = future requests python-dateutil + click packages = find: scripts = script_stages/deploy-pypi script_stages/test-testpypi +[options.package_data] +autorelease = + - ../gh_actions_stages/* + [options.entry_points] console_scripts = autorelease-release = autorelease.scripts.release:main @@ -47,6 +52,7 @@ console_scripts = bump-dev-version = autorelease.scripts.bump_dev_version:main pypi-max-version = autorelease.scripts.bump_dev_version:get_max wait-for-testpypi = autorelease.scripts.bump_dev_version:wait_for_max + autorelease = autorelease.scripts.cli:cli [bdist_wheel] universal=1