diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000..de52145427636 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,135 @@ +name: Release Readiness + +on: + workflow_dispatch: + inputs: + version: + description: 'The pandas version to release.' + default: '1.1.3' + required: true + # push-tag: + # description: 'Push tag on success?' + # default: 'false' + # required: true + +jobs: + build-sdist: + name: Build the sdist and maybe push the tag + runs-on: ubuntu-latest + env: + TAG: v${{ github.event.inputs.version }} + steps: + - name: Setting git user to Pandas Development Team + run: | + git config --global user.email "pandas-dev@python.org" + git config --global user.name "Pandas Development Team" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install packaging + - name: Checkout pandas + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Tag the release. (This doesn't push the tag) + run: | + python ./scripts/tag.py $TAG + git log -n 5 + - name: Update for build environment + run: | + sudo apt-get update + sudo apt-get install -y build-essential + sudo apt-get clean + - name: Setting conda path + run: echo ::add-path::$CONDA/bin + - name: Update conda + run: | + conda config --set quiet true --set always_yes true + conda update -n base -c defaults conda + conda list + - name: Update conda environment for build process + run: | + conda install -y cython + conda clean --all + conda list + - name: build the sdist + run: | + rm -rf dist + git clean -xfd + python setup.py clean --quiet + python setup.py sdist --formats=gztar --quiet + - name: Store sdist archive as artifact + uses: actions/upload-artifact@v2 + with: + name: pandas-${{ github.event.inputs.version }}.tar.gz + path: dist/pandas-${{ github.event.inputs.version }}.tar.gz + if-no-files-found: error + + pip-test: + name: Pip Test + needs: build-sdist + runs-on: ubuntu-latest + steps: + - name: Setting conda path + run: echo ::add-path::$CONDA/bin + - name: Update conda + run: | + conda config --set quiet true --set always_yes true + conda update -n base -c defaults conda + conda list + - name: Create conda environment + run: | + conda create -n pip-test -y python=3.7 numpy pytz python-dateutil pytest pytest-mock hypothesis nomkl + conda clean --all + conda list + - name: get sdist from artifacts + uses: actions/download-artifact@v2 + with: + name: pandas-${{ github.event.inputs.version }}.tar.gz + path: pandas/dist/ + - name: Create wheel + run: | + source activate pip-test + python -m pip wheel --no-deps --wheel-dir=pandas/dist pandas/dist/pandas-${{ github.event.inputs.version }}.tar.gz + - name: Install pandas + run: | + source activate pip-test + python -m pip install --no-deps --no-index --find-links=pandas/dist --only-binary=pandas pandas + conda list + - name: Test + # test_missing_required_dependencies: https://github.com/pandas-dev/pandas/issues/33999 + run: | + source activate pip-test + python -c "import pandas; pandas.test(extra_args=['-m not clipboard', '--skip-slow', '--skip-network', '--skip-db', '-k not test_missing_required_dependency'])" + + conda-test: + name: Conda Test + needs: build-sdist + runs-on: ubuntu-latest + env: + PANDAS_VERSION: ${{ github.event.inputs.version }} + steps: + - name: Setting conda path + run: echo ::add-path::$CONDA/bin + - name: Update conda + run: | + conda config --set quiet true --set always_yes true + conda update -n base -c defaults conda + conda list + - name: Create conda environment + run: | + conda create -n conda-build -y conda-build conda-verify gcc_linux-64 gxx_linux-64 + conda clean --all + conda list + - name: Checkout pandas + uses: actions/checkout@v2 + - name: get sdist from artifacts + uses: actions/download-artifact@v2 + with: + name: pandas-${{ github.event.inputs.version }}.tar.gz + path: dist/ + - name: Conda Build and Test + run: | + source activate conda-build + conda build --numpy=1.17.3 --python=3.8 ./recipe --output-folder=dist + diff --git a/conda.recipe/bld.bat b/conda.recipe/bld.bat deleted file mode 100644 index 284926fae8c04..0000000000000 --- a/conda.recipe/bld.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -%PYTHON% setup.py install diff --git a/conda.recipe/build.sh b/conda.recipe/build.sh deleted file mode 100644 index f341bce6fcf96..0000000000000 --- a/conda.recipe/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -$PYTHON setup.py install diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml deleted file mode 100644 index e833ea1f1f398..0000000000000 --- a/conda.recipe/meta.yaml +++ /dev/null @@ -1,40 +0,0 @@ -package: - name: pandas - version: {{ environ.get('GIT_DESCRIBE_TAG','').replace('v', '', 1) }} - -build: - number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} - {% if GIT_DESCRIBE_NUMBER|int == 0 %}string: np{{ CONDA_NPY }}py{{ CONDA_PY }}_0 - {% else %}string: np{{ CONDA_NPY }}py{{ CONDA_PY }}_{{ GIT_BUILD_STR }}{% endif %} - -source: - git_url: ../ - -requirements: - build: - - {{ compiler('c') }} - - {{ compiler('cxx') }} - host: - - python - - pip - - cython - - numpy - - setuptools >=3.3 - - python-dateutil >=2.7.3 - - pytz - run: - - python {{ python }} - - {{ pin_compatible('numpy') }} - - python-dateutil >=2.7.3 - - pytz - -test: - requires: - - pytest - commands: - - python -c "import pandas; pandas.test()" - - -about: - home: https://pandas.pydata.org - license: BSD diff --git a/recipe/meta.yaml b/recipe/meta.yaml new file mode 100644 index 0000000000000..f5e514f6af106 --- /dev/null +++ b/recipe/meta.yaml @@ -0,0 +1,51 @@ +{% set version = environ.get("PANDAS_VERSION") %} + +package: + name: pandas + version: {{ version }} + +source: + url: ../dist/pandas-{{ version }}.tar.gz + +build: + number: 0 + script: python -m pip install --no-deps --ignore-installed . + +requirements: + build: + - {{ compiler('c') }} + - {{ compiler('cxx') }} + host: + - python + - pip + - cython >=0.29.13 + - numpy + run: + - python + - {{ pin_compatible('numpy') }} + - python-dateutil >=2.6.1 + - pytz >=2017.2 + +test: + requires: + - pytest + - pytest-mock + - hypothesis + commands: + # test_missing_required_dependencies: https://github.com/pandas-dev/pandas/issues/33999 + - python -c "import pandas; pandas.test(extra_args=['-m not clipboard', '--skip-slow', '--skip-network', '--skip-db', '-k not test_missing_required_dependency'])" + +about: + home: http://pandas.pydata.org + license: BSD 3-clause + license_file: LICENSE + summary: 'High-performance, easy-to-use data structures and data analysis tools.' + +extra: + recipe-maintainers: + - jreback + - jorisvandenbossche + - msarahan + - ocefpaf + - TomAugspurger + - WillAyd diff --git a/scripts/tag.py b/scripts/tag.py new file mode 100644 index 0000000000000..3767f99044352 --- /dev/null +++ b/scripts/tag.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +""" +Tag a pandas release. + +This does not push the tag. +""" +import argparse +import subprocess +import sys + +from packaging import version + + +def check_tag(tag): + assert tag.startswith("v"), f"Invalid tag '{tag}', must start with 'v'" + ver = version.parse(tag.lstrip("v")) + assert isinstance(ver, version.Version), f"Invalid tag '{tag}'" + if "rc" in tag: + assert ".rc" not in tag, "RC tags should be formatted like '.0rcX' " + return tag + + +def checkout(tag): + if tag[-1] == "0" or "rc" in tag: + # off master + base = "master" + else: + base = ".".join([tag[1:].rsplit(".", 1)[0], "x"]) + + subprocess.check_call(["git", "checkout", base]) + # subprocess.check_call(["git", "pull", "--ff-only", "upstream", base]) + + +def commit(tag): + subprocess.check_call(["git", "clean", "-xdf"]) + print(f"Creating tag {tag}") + subprocess.check_call( + [ + "git", + "commit", + "--allow-empty", + "-m", + "RLS: {}".format(tag[1:]), + ] + ) + subprocess.check_call(["git", "tag", "-a", tag, "-m", "Version {}".format(tag[1:])]) + + +def parse_args(args=None): + parser = argparse.ArgumentParser(__name__, usage=__doc__) + parser.add_argument("tag", type=check_tag) + + return parser.parse_args(args) + + +def main(args=None): + args = parse_args(args) + checkout(args.tag) + commit(args.tag) + + +if __name__ == "__main__": + sys.exit(main())