diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml new file mode 100644 index 0000000..6307747 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml @@ -0,0 +1,50 @@ +name: 🐛 Bug report +description: Create a report to help us improve 🤔. +labels: ["bug"] + +body: + - type: markdown + attributes: + value: Thank you for reporting a bug! Before you do so, please ensure that you have tested on the latest released version of the code. If it does, please also use the search to see if there are any other related issues or pull requests. + + - type: textarea + attributes: + label: Environment + description: Please give the actual version number (_e.g._ 0.1.0) if you are using a release version, or the first 7-8 characters of the commit hash if you have installed from `git`. If anything else is relevant, you can add it to the list. + # The trailing spaces on the following lines are to make filling the form + # in easier. The type is 'textarea' rather than three separate 'input's + # to make the resulting issue body less noisy with headings. + value: | + - **qiskit-addon-aqc-tensor version**: + - **Python version**: + - **Operating system**: + validations: + required: true + + - type: textarea + attributes: + label: What is happening and why is it wrong? + description: A short description of what is going wrong, in words. + validations: + required: true + + - type: textarea + attributes: + label: How can we reproduce the issue? + description: Give some steps that show the bug. A [minimal working example](https://stackoverflow.com/help/minimal-reproducible-example) of code with output is best. If you are copying in code, please remember to enclose it in triple backticks (` ``` [multiline code goes here] ``` `) so that it [displays correctly](https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax). + validations: + required: true + + - type: textarea + attributes: + label: Traceback + description: If your code provided an error traceback, please paste it below, enclosed in triple backticks (` ``` [multiline code goes here] ``` `) so that it [displays correctly](https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax). + validations: + required: false + + - type: textarea + attributes: + label: Any suggestions? + description: Not required, but if you have suggestions for how a contributor should fix this, or any problems we should be aware of, let us know. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml new file mode 100644 index 0000000..4b66a76 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yaml @@ -0,0 +1,14 @@ +name: 🚀 Feature request +description: Suggest an idea for this project 💡! +labels: ["type: feature request"] + +body: + - type: markdown + attributes: + value: Please make sure to browse the opened and closed issues to make sure that this idea has not previously been discussed. + + - type: textarea + attributes: + label: What should we add? + validations: + required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..7141543 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + labels: ["dependencies"] + schedule: + interval: "weekly" + - package-ecosystem: "pip" + directory: "/" + labels: ["dependencies"] + versioning-strategy: increase + schedule: + interval: "monthly" diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..f0a38a9 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,37 @@ +# GitHub Actions workflows + +This directory contains a number of workflows for use with [GitHub Actions](https://docs.github.com/actions). They specify what standards should be expected for development of this software, including pull requests. These workflows are designed to work out of the box for any research software prototype, especially those based on [Qiskit](https://qiskit.org/). + +## Lint check (`lint.yml`) + +This workflow checks that the code is formatted properly and follows the style guide by installing tox and running the [lint environment](/tests/#lint-environment) (`tox -e lint`). + +## Latest version tests (`test_latest_versions.yml`) + +This workflow installs the latest version of tox and runs [the current repository's tests](/tests/#test-py-environments) under each supported Python version on Linux and under a single Python version on macOS and Windows. This is the primary testing workflow. It runs for all code changes and additionally once per day, to ensure tests continue to pass as new versions of dependencies are released. + +## Development version tests (`test_development_versions.yml`) + +This workflow installs tox and modifies `pyproject.toml` to use the _development_ versions of certain Qiskit packages, using [extremal-python-dependencies](https://github.com/IBM/extremal-python-dependencies). For all other packages, the latest version is installed. This workflow runs on two versions of Python: the minimum supported version and the maximum supported version. Its purpose is to identify as soon as possible (i.e., before a Qiskit release) when changes in Qiskit will break the current repository. This workflow runs for all code changes, as well as on a timer once per day. + +## Minimum version tests (`test_minimum_versions.yml`) + +This workflow first installs the minimum supported tox version (the `minversion` specified in [`tox.ini`](/tox.ini)) and then installs the _minimum_ compatible version of each package listed in `pyproject.toml`, using [extremal-python-dependencies](https://github.com/IBM/extremal-python-dependencies). The purpose of this workflow is to make sure the minimum version specifiers in these files are accurate, i.e., that the tests actually pass with these versions. This workflow uses a single Python version, typically the oldest supported version, as the minimum supported versions of each package may not be compatible with the most recent Python release. + +Under the hood, this workflow uses a regular expression to change each `>=` and `~=` specifier in the dependencies to instead be `==`, as pip [does not support](https://github.com/pypa/pip/issues/8085) resolving the minimum versions of packages directly. Unfortunately, this means that the workflow will only install the minimum version of a package if it is _explicitly_ listed in one of the requirements files with a minimum version. For instance, if the only listed dependency is `qiskit>=1.0`, this workflow will install `qiskit==1.0` along with the latest version of each transitive dependency, such as `rustworkx`. + +## Code coverage (`coverage.yml`) + +This workflow tests the [coverage environment](/tests/#coverage-environment) on a single version of Python by installing tox and running `tox -e coverage`. + +## Documentation (`docs.yml`) + +This workflow ensures that the [Sphinx](https://www.sphinx-doc.org/) documentation builds successfully. It also publishes the resulting build to [GitHub Pages](https://pages.github.com/) if it is from the appropriate branch (e.g., `main`). + +## Citation preview (`citation.yml`) + +This workflow is only triggered when the `CITATION.bib` file is changed. It ensures that the file contains only ASCII characters ([escaped codes](https://en.wikibooks.org/wiki/LaTeX/Special_Characters#Escaped_codes) are preferred, as then the `bib` file will work even when `inputenc` is not used). It also compiles a sample LaTeX document which includes the citation in its bibliography and uploads the resulting PDF as an artifact so it can be previewed (e.g., before merging a pull request). + +## Release (`release.yml`) + +This workflow is triggered by a maintainer pushing a tag that represents a release. It publishes the release to github.com and to [PyPI](https://pypi.org/). diff --git a/.github/workflows/citation.yml b/.github/workflows/citation.yml new file mode 100644 index 0000000..6a018f0 --- /dev/null +++ b/.github/workflows/citation.yml @@ -0,0 +1,68 @@ +name: Citation preview + +on: + push: + branches: [ main ] + paths: ['CITATION.bib', '.github/workflows/citation.yml'] + pull_request: + branches: [ main ] + paths: ['CITATION.bib', '.github/workflows/citation.yml'] + +jobs: + build-preview: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: Check for non-ASCII characters + run: | + # Fail immediately if there are any non-ASCII characters in + # the BibTeX source. We prefer "escaped codes" rather than + # UTF-8 characters in order to ensure the bibliography will + # display correctly even in documents that do not contain + # \usepackage[utf8]{inputenc}. + if [ -f "CITATION.bib" ]; then + python3 -c 'open("CITATION.bib", encoding="ascii").read()' + fi + - name: Install LaTeX + run: | + if [ -f "CITATION.bib" ]; then + sudo apt-get update + sudo apt-get install -y texlive-latex-base texlive-publishers + fi + - name: Run LaTeX + run: | + if [ -f "CITATION.bib" ]; then + arr=(${GITHUB_REPOSITORY//\// }) + export REPO=${arr[1]} + cat <<- EOF > citation-preview.tex + \documentclass[preprint,aps,physrev,notitlepage]{revtex4-2} + \usepackage{hyperref} + \begin{document} + \title{\texttt{$REPO} BibTeX test} + \maketitle + \noindent + \texttt{$REPO} + \cite{$REPO} + \bibliography{CITATION} + \end{document} + EOF + pdflatex citation-preview + fi + - name: Run BibTeX + run: | + if [ -f "CITATION.bib" ]; then + bibtex citation-preview + fi + - name: Re-run LaTeX + run: | + if [ -f "CITATION.bib" ]; then + pdflatex citation-preview + pdflatex citation-preview + fi + - name: Upload PDF + if: always() + uses: actions/upload-artifact@v4 + with: + name: citation-preview.pdf + path: citation-preview.pdf diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..a1c94a0 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,45 @@ +name: Coverage + +on: + push: + branches: + - main + - 'stable/**' + pull_request: + branches: + - main + - 'stable/**' + +jobs: + coverage: + name: code coverage (${{ matrix.os }}, ${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + max-parallel: 4 + matrix: + os: [ubuntu-latest] + python-version: ["3.10"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install tox + run: | + python -m pip install --upgrade pip + pip install tox coverage + - name: Run coverage + run: | + tox -e coverage + - name: Convert to lcov + if: always() + run: coverage3 lcov -o coveralls.lcov + - name: Upload report to Coveralls + if: always() + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + file: coveralls.lcov + format: lcov diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..9142e2d --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,76 @@ +name: Sphinx + +on: + workflow_dispatch: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + branches: + - main + - 'stable/**' + pull_request: + branches: + - main + - 'stable/**' + +jobs: + build: + name: build docs + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-python@v5 + with: + python-version: '3.9' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox + sudo apt-get update + sudo apt-get install -y pandoc + - name: Tell reno to name the upcoming release after the branch we are on + shell: bash + run: | + sed -i.bak -e '/unreleased_version_title:*/d' releasenotes/config.yaml + echo unreleased_version_title: \"Upcoming release \(\`\`${GITHUB_REF_NAME}\`\`\)\" >> releasenotes/config.yaml + - name: Build docs + run: | + tox -e docs + - name: Upload docs artifact for GitHub Pages + uses: actions/upload-pages-artifact@v3 + with: + path: docs/_build/html + + # Provide a nicely named artifact that extracts into an + # identically named subdirectory. + - name: Prepare nice docs artifact for humans + if: always() + shell: bash + run: | + mkdir artifact + cp -a docs/_build/html artifact/qiskit-addon-aqc-tensor-htmldocs + - name: Upload nice docs artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: qiskit-addon-aqc-tensor-htmldocs + path: ./artifact + + deploy: + name: deploy docs + if: ${{ github.ref == 'refs/heads/stable/0.1' }} + needs: build + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..43c31f1 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,32 @@ +name: Lint + +on: + push: + branches: + - main + - 'stable/**' + pull_request: + branches: + - main + - 'stable/**' + +jobs: + lint: + name: lint check + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Install tox + run: | + python -m pip install --upgrade pip + pip install tox + - name: Run lint check + run: | + tox -e lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..d33a354 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,49 @@ +name: Publish release + +on: + workflow_dispatch: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+" + +jobs: + + github: + name: github + runs-on: ubuntu-latest + steps: + - name: Checkout tag + uses: actions/checkout@v4 + with: + ref: ${{ github.ref_name }} + - name: Publish release + uses: ghalactic/github-release-from-tag@v5 + if: github.ref_type == 'tag' + with: + prerelease: false + token: ${{ secrets.GITHUB_TOKEN }} + generateReleaseNotes: "true" + + pypi: + name: pypi + runs-on: ubuntu-latest + needs: github + environment: + name: pypi + url: https://pypi.org/p/qiskit-addon-aqc-tensor + permissions: + id-token: write + steps: + - name: Checkout tag + uses: actions/checkout@v4 + with: + ref: ${{ github.ref_name }} + - name: Install `build` tool + run: | + python -m pip install --upgrade pip + pip install build + - name: Build distribution + run: | + python -m build + - name: Publish release to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml new file mode 100644 index 0000000..86c8e6d --- /dev/null +++ b/.github/workflows/test_development_versions.yml @@ -0,0 +1,55 @@ +name: Development version tests + +on: + push: + branches: + - main + - 'stable/**' + pull_request: + branches: + - main + - 'stable/**' + schedule: + - cron: '0 1 * * *' + +jobs: + tests: + name: development version tests (${{ matrix.os }}, ${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + max-parallel: 4 + matrix: + os: [ubuntu-latest] + python-version: [3.9, 3.12] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Upgrade pip + run: | + python -m pip install --upgrade pip + - name: Install tools from pypi + run: | + python -m pip install tox build extremal-python-dependencies==0.0.3 + - name: Build Qiskit SDK development wheel + run: | + git clone https://github.com/Qiskit/qiskit + cd qiskit + python -m build --wheel + - name: Build qiskit-ibm-runtime development wheel + run: | + git clone https://github.com/Qiskit/qiskit-ibm-runtime + cd qiskit-ibm-runtime + python -m build --wheel + - name: Pin development versions + shell: bash + run: >- + extremal-python-dependencies pin-dependencies --inplace + "qiskit @ file:$(echo qiskit/dist/*.whl)" + "qiskit-ibm-runtime @ file:$(echo qiskit-ibm-runtime/dist/*.whl)" + - name: Test using tox environment + run: | + tox -e py,notebook,quimb-only,aer-only --parallel --parallel-no-spinner diff --git a/.github/workflows/test_latest_versions.yml b/.github/workflows/test_latest_versions.yml new file mode 100644 index 0000000..1852b3e --- /dev/null +++ b/.github/workflows/test_latest_versions.yml @@ -0,0 +1,41 @@ +name: Tests + +on: + push: + branches: + - main + - 'stable/**' + pull_request: + branches: + - main + - 'stable/**' + schedule: + - cron: '0 1 * * *' + +jobs: + tests: + name: latest version tests (${{ matrix.os }}, ${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + max-parallel: 4 + matrix: + os: [ubuntu-latest] + python-version: ["3.9", "3.10", "3.11", "3.12"] + include: + - os: macos-latest + python-version: "3.12" + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox + - name: Test using tox environment + shell: bash + run: | + tox -e py,notebook,quimb-only,aer-only --parallel --parallel-no-spinner diff --git a/.github/workflows/test_minimum_versions.yml b/.github/workflows/test_minimum_versions.yml new file mode 100644 index 0000000..2ca72fe --- /dev/null +++ b/.github/workflows/test_minimum_versions.yml @@ -0,0 +1,38 @@ +name: Minimum version tests + +on: + push: + branches: + - main + - 'stable/**' + pull_request: + branches: + - main + - 'stable/**' + +jobs: + tests: + name: minimum version tests (${{ matrix.os }}, ${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + max-parallel: 4 + matrix: + os: [ubuntu-latest] + python-version: [3.9] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies (minimum versions) + shell: bash + run: | + python -m pip install --upgrade pip + python -m pip install extremal-python-dependencies==0.0.3 + pip install "tox==$(extremal-python-dependencies get-tox-minversion)" + extremal-python-dependencies pin-dependencies-to-minimum --inplace + - name: Test using tox environment + run: | + tox -e py,notebook,quimb-only,aer-only --parallel --parallel-no-spinner diff --git a/releasenotes/config.yaml b/releasenotes/config.yaml new file mode 100644 index 0000000..a27580d --- /dev/null +++ b/releasenotes/config.yaml @@ -0,0 +1,5 @@ +--- +encoding: utf8 +default_branch: main +unreleased_version_title: "Upcoming release" +#earliest_version: 0.1.0 diff --git a/releasenotes/notes/prepare-0.1.0-5f2edc5598ece00b.yaml b/releasenotes/notes/prepare-0.1.0-5f2edc5598ece00b.yaml new file mode 100644 index 0000000..9fd4dfd --- /dev/null +++ b/releasenotes/notes/prepare-0.1.0-5f2edc5598ece00b.yaml @@ -0,0 +1,3 @@ +--- +prelude: | + Initial release. diff --git a/tox.ini b/tox.ini index 97d44af..bdb74ca 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -minversion = 3.25 +minversion = 4.4.3 envlist = py{39,310,311,312}{,-notebook}, lint, coverage, docs isolated_build = True @@ -28,23 +28,23 @@ extras = extras = style commands = - ruff check --fix qiskit_addon_aqc_tensor docs/ test/ tools/ + ruff check --fix qiskit_addon_aqc_tensor docs/ test/ nbqa ruff --fix docs/ - autoflake --in-place --recursive qiskit_addon_aqc_tensor docs/ test/ tools/ - black qiskit_addon_aqc_tensor docs/ test/ tools/ + autoflake --in-place --recursive qiskit_addon_aqc_tensor docs/ test/ + black qiskit_addon_aqc_tensor docs/ test/ [testenv:lint] extras = lint commands = - ruff check qiskit_addon_aqc_tensor docs/ test/ tools/ + ruff check qiskit_addon_aqc_tensor docs/ test/ nbqa ruff docs/ - autoflake --check --quiet --recursive qiskit_addon_aqc_tensor docs/ test/ tools/ - black --check qiskit_addon_aqc_tensor docs/ test/ tools/ + autoflake --check --quiet --recursive qiskit_addon_aqc_tensor docs/ test/ + black --check qiskit_addon_aqc_tensor docs/ test/ pydocstyle qiskit_addon_aqc_tensor --ignore-decorators=dispatch mypy qiskit_addon_aqc_tensor --disable-error-code no-redef reno lint - pylint -rn qiskit_addon_aqc_tensor test/ tools/ + pylint -rn qiskit_addon_aqc_tensor test/ nbqa pylint -rn --disable=wrong-import-order,wrong-import-position docs/ [testenv:{,py-,py3-,py39-,py310-,py311-,py312-}notebook]