diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 000000000000..7179616d0138 --- /dev/null +++ b/.codespellrc @@ -0,0 +1,8 @@ +[codespell] +skip = .git,*.pdf,*.svg,versioneer.py,package-lock.json,_vendor,*.css,.codespellrc +# from https://github.com/PrefectHQ/prefect/pull/10813#issuecomment-1732676130 +ignore-regex = .*lazy=\"selectin\"|.*e import Bloc$|America/Nome + +ignore-words-list = selectin,aci,wqs,aks,ines,dependant,fsspec,automations,nmme + +check-hidden = true \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0b1b7688f1fc..bd2c83355cfb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,10 +2,10 @@ * @PrefectHQ/open-source # backend -/src/prefect/server @PrefectHQ/open-source @zangell44 +/src/prefect/server @PrefectHQ/open-source @zangell44 # ui -/ui @pleek91 +/ui @PrefectHQ/frontend # documentation /docs @PrefectHQ/docs @@ -13,7 +13,15 @@ mkdocs.yml @PrefectHQ/docs mkdocs.insiders.yml @PrefectHQ/docs # orchestration rules / policies -/src/prefect/server/orchestration @PrefectHQ/open-source +/src/prefect/server/orchestration @PrefectHQ/open-source # database configuration / models /src/prefect/server/database @PrefectHQ/open-source + +# the events subsystem, while it's being ported +/src/prefect/events @chrisguidry +/src/prefect/server/events @chrisguidry +/tests/events @chrisguidry + +# integrations +/src/integrations @desertaxle @zzstoatzz diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000000..83fed516accc --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,5 @@ +# Contributing + +Thanks for considering contributing to Prefect! + +To navigate our codebase with confidence, see our [contribution guidelines](https://docs.prefect.io/latest/contributing/overview/). diff --git a/.github/ISSUE_TEMPLATE/1_general_bug_report.yaml b/.github/ISSUE_TEMPLATE/1_general_bug_report.yaml index 606b245e77c6..108e96f59502 100644 --- a/.github/ISSUE_TEMPLATE/1_general_bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/1_general_bug_report.yaml @@ -1,6 +1,6 @@ name: 🐞 Report a bug description: Errors and regression reports with complete reproducing test cases and/or stack traces. -labels: ["status:triage", "bug"] +labels: ["needs:triage", "bug"] body: - type: markdown attributes: @@ -10,7 +10,11 @@ body: or [Discourse](https://discourse.prefect.io/) and ask there first. You are likely to get a response faster and learn more about the feature you're working with. If the issue is determined to be a bug, we will open an issue here. - + + GitHub issues raised against this repository will receive community support. If you have an + [active support agreement](https://www.prefect.io/pricing/), we recommend creating a case to ensure + a faster response. + - type: markdown attributes: value: > @@ -75,8 +79,8 @@ body: description: > Provide information about your Prefect version and environment. The easiest way to retrieve all of the information we require is the `prefect version` command. If using Prefect 1.x, it is useful to also include the output of `prefect diagnostics`. - Please do not just write "2.0". The command provides additional context such as your operating system, Prefect API type, Python version, etc. that we need to diagnose your problem. - placeholder: "# Copy output of the `prefect version` command here" + **Please do not just include your Prefect version number**. The command provides additional context such as your operating system, Prefect API type, Python version, etc. that we need to diagnose your problem. + placeholder: "# Copy output of the `prefect version` command here. Do not just include your Prefect version number." render: Text validations: required: true diff --git a/.github/ISSUE_TEMPLATE/2_ui_bug_report.yaml b/.github/ISSUE_TEMPLATE/2_ui_bug_report.yaml index 5b822209a63a..b41721ad8a11 100644 --- a/.github/ISSUE_TEMPLATE/2_ui_bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/2_ui_bug_report.yaml @@ -1,6 +1,6 @@ name: 🖼️ Report a bug with the Prefect UI description: Errors and display issues with the Prefect web interface. -labels: ["status:triage", "ui", "bug"] +labels: ["needs:triage", "ui", "bug"] body: - type: markdown attributes: @@ -21,6 +21,10 @@ body: 4. Additional details that may help us reproduce your issue. + GitHub issues raised against this repository will receive community support. If you have an + [active support agreement](https://www.prefect.io/pricing/), we recommend creating a case to ensure + a faster response. + - type: checkboxes id: checks attributes: @@ -62,7 +66,7 @@ body: - type: checkboxes attributes: - label: Browers + label: Browsers description: Which browsers was this bug reproduced on? Please check if your issue is specific to your browser by testing on another browser. options: - label: Chrome diff --git a/.github/ISSUE_TEMPLATE/3_feature_enhancement.yaml b/.github/ISSUE_TEMPLATE/3_feature_enhancement.yaml index 155a3569dd72..81bb5c687d4e 100644 --- a/.github/ISSUE_TEMPLATE/3_feature_enhancement.yaml +++ b/.github/ISSUE_TEMPLATE/3_feature_enhancement.yaml @@ -1,6 +1,6 @@ name: 🚀 Propose a feature enhancement description: Propose a new feature or an enhancement to an existing feature. -labels: ["status:triage", "enhancement"] +labels: ["needs:triage", "enhancement"] body: - type: checkboxes id: checks diff --git a/.github/ISSUE_TEMPLATE/4_docs_change.yaml b/.github/ISSUE_TEMPLATE/4_docs_change.yaml index 03fbb28bde4c..30650bf130ff 100644 --- a/.github/ISSUE_TEMPLATE/4_docs_change.yaml +++ b/.github/ISSUE_TEMPLATE/4_docs_change.yaml @@ -1,6 +1,6 @@ name: 📝 Suggest a change to documentation description: Propose edits, enhancements, or fixes to Prefect documentation -labels: ["docs", "status:triage"] +labels: ["docs", "needs:triage"] body: - type: checkboxes id: checks diff --git a/.github/ISSUE_TEMPLATE/5_maintenance_ticket.yaml b/.github/ISSUE_TEMPLATE/5_maintenance_ticket.yaml index dba85b54d530..df4507a5ded1 100644 --- a/.github/ISSUE_TEMPLATE/5_maintenance_ticket.yaml +++ b/.github/ISSUE_TEMPLATE/5_maintenance_ticket.yaml @@ -1,6 +1,6 @@ -name: 🛠️ Track a maintenence task +name: 🛠️ Track a maintenance task description: These are for changes that are not user or product related for maintenance of this repository. -labels: ["status:backlog", "maintenance"] +labels: ["maintenance"] body: - type: checkboxes id: checks diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e0719e12003e..c0cadef161f1 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -10,5 +10,8 @@ contact_links: url: https://www.prefect.io/slack about: Join thousands of Prefect experts, engineers, and users in our Slack community - name: 🦆 Book a rubber duck - url: https://calendly.com/prefect-experts/rubber-duck - about: Book time with a Prefect engineer! + url: https://calendly.com/prefect-experts/prefect-product-advocates?utm_campaign=prefect_docs_cloud&utm_content=prefect_docs&utm_medium=docs&utm_source=docs + about: Schedule a meeting with a Prefect Product Advocate! + - name: 🔒 Report a security issue + url: https://www.prefect.io/security/bug-bounty-program/ + about: Responsibly disclose a potential security issue. diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml index 8d27bfc50f5e..b60c9a89b004 100644 --- a/.github/codeql-config.yml +++ b/.github/codeql-config.yml @@ -1,23 +1,7 @@ query-filters: - - exclude: - # this creates many false positives with our code - id: py/unsafe-cyclic-import - - exclude: - id: py/cyclic-import - - exclude: - id: py/unreachable-statement - exclude: # catching base exceptions is required id: py/catch-base-exception - - exclude: - # too many false positives with prefect.runtime - id: py/undefined-export - - exclude: - # sometimes necessary for __init__ files - id: py/import-and-import-from - - exclude: - # we dont need CodeQL quality linting - id: py/mixed-returns paths-ignore: - tests/**/test_*.py diff --git a/.github/labeler.yml b/.github/labeler.yml index 0f155f83647a..7f39e8af16e6 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,2 +1,3 @@ migration: - - src/**/migrations/**/*.py + - changed-files: + - any-glob-to-any-file: src/**/migrations/**/*.py diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9bdf84a0ad8b..43542a6c1631 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -5,6 +5,7 @@ Thanks for opening a pull request to Prefect! We've got a few requests to help u - Provide a short overview of the change and the value it adds. - Share an example to help us understand the change in user experience. - Confirm that you've done common tasks so we can give a timely review. +- Review our contribution guidelines: https://docs.prefect.io/latest/contributing/overview/ Happy engineering! --> @@ -23,7 +24,16 @@ If changing documentation, a link to a preview of the page is great. - [ ] This pull request references any related issue by including "closes ``" - - If no issue exists and your change is not a small fix, please [create an issue](https://github.com/PrefectHQ/prefect/issues/new/choose) first. -- [ ] This pull request includes tests or only affects documentation. -- [ ] This pull request includes a label categorizing the change e.g. `fix`, `feature`, `enhancement`, `docs`. + - If no issue exists and your change is not a small fix, please [create an issue](https://github.com/PrefectHQ/prefect/issues/new/choose) first. +- [ ] If this pull request adds new functionality, it includes unit tests that cover the changes +- [ ] This pull request includes a label categorizing the change e.g. `maintenance`, `fix`, `feature`, `enhancement`, `docs`. + +For documentation changes: + +- [ ] This pull request includes redirect settings in `mint.json` for files that are removed or renamed. + +For new functions or classes in the Python SDK: + +- [ ] This pull request includes helpful docstrings. +- [ ] If a new Python file was added, this pull request contains a stub page in the Python SDK docs and an entry in `docs/mint.json` navigation. diff --git a/.github/workflows/api-compatibility-tests.yaml b/.github/workflows/api-compatibility-tests.yaml new file mode 100644 index 000000000000..6276a0f45ba3 --- /dev/null +++ b/.github/workflows/api-compatibility-tests.yaml @@ -0,0 +1,74 @@ +--- +name: Cloud API Compatibility +on: + pull_request: + paths: + - .github/workflows/api-compatibility-tests.yaml + - "**/*.py" + - requirements*.txt + - setup.cfg + - compat-tests + push: + branches: + - main + +# Limit concurrency by workflow/branch combination. +# +# For pull request builds, pushing additional changes to the +# branch will cancel prior in-progress and pending builds. +# +# For builds triggered on a branch push, additional changes +# will wait for prior builds to complete before starting. +# +# https://docs.github.com/en/actions/using-jobs/using-concurrency +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + compatibility-tests: + + timeout-minutes: 10 + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + # Versioneer only generates correct versions with a full fetch + fetch-depth: 0 + persist-credentials: false + submodules: true + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + id: setup_python + with: + python-version: 3.12 + + - name: UV Cache + # Manually cache the uv cache directory + # until setup-python supports it: + # https://github.com/actions/setup-python/issues/822 + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('requirements-client.txt', 'requirements.txt', 'requirements-dev.txt') }} + + - name: Install packages + run: | + python -m pip install -U uv + uv pip install --upgrade --system -e .[dev] 'pydantic>=2.4,<3' + + - name: Create Cloud OpenAPI JSON + working-directory: compat-tests + run: curl https://api.prefect.cloud/api/openapi.json > cloud_schema.json + + - name: Create OSS OpenAPI JSON + working-directory: compat-tests + run: python ../scripts/generate_oss_openapi_schema.py + + - name: Run API compatibility tests + working-directory: compat-tests + run: pytest -vv diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index de9beb022a1b..d0fd5080c6f0 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -6,8 +6,9 @@ env: on: pull_request: paths: + - .github/workflows/benchmarks.yaml - .github/workflows/python-tests.yaml - - "**/*.py" + - "src/prefect/**/*.py" - requirements.txt - requirements-dev.txt - setup.cfg @@ -28,36 +29,45 @@ jobs: name: Benchmark # Runs with ephemeral API and SQLite database right now - runs-on: ubuntu-latest + runs-on: + group: oss-larger-runners timeout-minutes: 20 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: persist-credentials: false fetch-depth: 0 - name: Set up Docker Buildx if: ${{ matrix.build-docker-images }} - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 + with: + driver-opts: image=moby/buildkit:v0.12.5 - name: Set up Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.10" - cache: "pip" - cache-dependency-path: "requirements*.txt" + + - name: UV Cache + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('requirements-client.txt', 'requirements.txt', 'requirements-dev.txt') }} + - name: Install packages run: | - python -m pip install --upgrade pip - pip install --upgrade --upgrade-strategy eager -e ".[dev]" + python -m pip install -U uv + uv pip install --upgrade --system -e .[dev] - name: Prepare benchmark comparisons # Note: We use a "cache" instead of artifacts because artifacts are not available # across workflow runs. id: bench-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ./.benchmarks # Pushes benchmark results for this branch and sha, this will always be a cache miss @@ -68,7 +78,6 @@ jobs: ${{ runner.os }}-${{ github.base_ref }}- ${{ runner.os }}-main- - - name: Start server run: | prefect server start& @@ -78,12 +87,25 @@ jobs: # https://github.com/PrefectHQ/prefect/issues/6990 - name: Run benchmarks + env: + HEAD_REF: ${{ github.head_ref }} + GITHUB_SHA: ${{ github.sha }} # Includes comparison to previous benchmarks if available - run: > - uniquename=${{ github.head_ref || 'main' }}-${{ github.sha }} + run: | + if [[ -z "$HEAD_REF" ]]; then + # HEAD_REF is unset or empty, use 'main' with the SHA + uniquename="main-$GITHUB_SHA" + else + # HEAD_REF is set, use the branch name directly + uniquename="$HEAD_REF" + fi + + # Allow alphanumeric, underscores, and dashes, and replace other + # characters with an underscore + sanitized_uniquename="${uniquename//[^a-zA-Z0-9_\-]/_}" PREFECT_API_URL="http://127.0.0.1:4200/api" - python benches - --benchmark-save="${uniquename//\//_}" - ${{ steps.bench-cache.outputs.cache-hit && '--benchmark-compare' || ''}} - + python benches \ + --timeout=180 \ + --benchmark-save="${sanitized_uniquename}" \ + ${{ steps.bench-cache.outputs.cache-hit && '--benchmark-compare' || '' }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index aafd2f7fd2fe..1a7fff3ad090 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ on: # # https://docs.github.com/en/actions/using-jobs/using-concurrency concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} # Do not grant jobs any permissions by default @@ -57,7 +57,7 @@ jobs: security-events: write strategy: - fail-fast: false + fail-fast: true matrix: language: - javascript @@ -65,15 +65,14 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql-config.yml - queries: security-and-quality - setup-python-dependencies: false + queries: security-extended - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/create-tags-for-changed-integrations.yaml b/.github/workflows/create-tags-for-changed-integrations.yaml new file mode 100644 index 000000000000..e24f862283f6 --- /dev/null +++ b/.github/workflows/create-tags-for-changed-integrations.yaml @@ -0,0 +1,38 @@ +name: Create tags for changed integrations + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + create-integrations-tags: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U packaging gh-util + + - name: Get previous tag + id: get-previous-tag + run: echo "tag=$(git tag --list '[0-9]*' --sort=-version:refname | grep -v '2.82' | head -n 2 | tail -n 1)" >> $GITHUB_OUTPUT + + - name: Push tags for changed integrations + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PREVIOUS_TAG: ${{ steps.get-previous-tag.outputs.tag }} + CURRENT_COMMIT: ${{ github.sha }} + + run: python scripts/create_tags_for_changed_collections.py \ No newline at end of file diff --git a/.github/workflows/docker-images.yaml b/.github/workflows/docker-images.yaml index 9ccc58097d77..a53b6662f357 100644 --- a/.github/workflows/docker-images.yaml +++ b/.github/workflows/docker-images.yaml @@ -1,7 +1,5 @@ name: Docker images -# Note: Conda support for 3.11 is pending. See https://github.com/ContinuumIO/anaconda-issues/issues/13082 - on: # On release events (also when a published release is converted from/to prerelease), push all patterns release: @@ -9,6 +7,22 @@ on: # On each commit merged into main, push sha and branch patterns to prefect-dev push: branches: main + paths: + - "Dockerfile" + - ".dockerignore" + - "setup.py" + - "src/**" + - "tests/**" + - "requirements.txt" + - "requirements-client.txt" + - "MANIFEST.in" + - "setup.cfg" + - "versioneer.py" + - ".gitingore" + - ".gitattributes" + - ".github/workflows/docker-images.yaml" + - "ui/**" + # On workflow_dispatch, push sha and branch patterns to prefect-dev workflow_dispatch: @@ -24,37 +38,34 @@ jobs: - "-conda" - "-kubernetes" python-version: - - "3.7" - - "3.8" - "3.9" - "3.10" - "3.11" - exclude: - # Not yet supported, see note at top - - flavor: "-conda" - python-version: "3.11" + - "3.12" steps: - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 + with: + driver-opts: image=moby/buildkit:v0.12.5 - name: Login to DockerHub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Generate tags for prefecthq/prefect-dev id: metadata-dev - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 # do not generate the development tags on release events if: ${{ github.event_name != 'release' }} with: @@ -77,7 +88,7 @@ jobs: - name: Generate tags for prefecthq/prefect id: metadata-prod - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 # only generate the production tags on release events if: ${{ github.event_name == 'release' }} with: @@ -88,14 +99,12 @@ jobs: type=pep440,pattern={{version}},suffix=-python${{ matrix.python-version }}${{ matrix.flavor }} type=pep440,pattern={{major}}.{{minor}},suffix=-python${{ matrix.python-version }}${{ matrix.flavor }},enable=${{ github.event.release.prerelease == false }} type=pep440,pattern={{major}},suffix=-python${{ matrix.python-version }}${{ matrix.flavor }},enable=${{ github.event.release.prerelease == false && github.ref_name == env.LATEST_TAG }} - type=raw,value=2-latest${{ matrix.flavor }},enable=${{ matrix.python-version == '3.10' && github.event.release.prerelease == false && github.ref_name == env.LATEST_TAG }} + type=raw,value=3-latest${{ matrix.flavor }},enable=${{ matrix.python-version == '3.10' && github.event.release.prerelease == false && github.ref_name == env.LATEST_TAG }} flavor: | latest=false - name: Build and push image - uses: docker/build-push-action@v4 - env: - CACHE_TO_STRING: type=registry,ref=prefecthq/prefect-dev:buildcache-python${{ matrix.python-version }}${{ matrix.flavor }},mode=max + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -108,6 +117,3 @@ jobs: push: true pull: true provenance: false - # multi-stage cache manifests (mode=max) need a separate tag because they are not usable for runtime ref https://github.com/moby/buildkit#export-cache - cache-from: type=registry,ref=prefecthq/prefect-dev:buildcache-python${{ matrix.python-version }}${{ matrix.flavor }} - cache-to: ${{ ( github.event_name == 'push' && env.CACHE_TO_STRING ) || '' }} diff --git a/.github/workflows/helm-chart-release.yaml b/.github/workflows/helm-chart-release.yaml index b9ef327e9603..3e90af85f77a 100644 --- a/.github/workflows/helm-chart-release.yaml +++ b/.github/workflows/helm-chart-release.yaml @@ -10,15 +10,10 @@ jobs: create_helm_release: runs-on: ubuntu-latest steps: - - name: Get today's formatted date - id: get_date - run: echo "value=$(date +'%Y.%m.%d')" >> $GITHUB_OUTPUT - name: Create prefect-helm release run: | - gh release create ${{ steps.get_date.outputs.value }} \ + gh workflow run helm-release.yaml \ --repo PrefectHQ/prefect-helm \ - --generate-notes \ - --notes "Packaged with Prefect version \ - [${{ github.ref_name }}](https://github.com/PrefectHQ/prefect/releases/tag/${{ github.ref_name }})" + --ref main env: - GH_TOKEN: ${{ secrets.PREFECT_HELM_CONTENTS_RW }} + GH_TOKEN: ${{ secrets.PREFECT_HELM_ACTIONS_RW }} diff --git a/.github/workflows/integration-package-release.yaml b/.github/workflows/integration-package-release.yaml new file mode 100644 index 000000000000..4fe8845c4d61 --- /dev/null +++ b/.github/workflows/integration-package-release.yaml @@ -0,0 +1,71 @@ +name: Publish integration package to PyPI + +on: + push: + tags: + - "prefect-\\w+-[0-9]+.*" + +jobs: + build-pypi-dists: + name: Build Python package + runs-on: ubuntu-latest + outputs: + PACKAGE_NAME: ${{ steps.package_name.outputs.PACKAGE_NAME }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit }} + fetch-depth: 0 + persist-credentials: false + + - name: Extract package name + id: package_name + run: | + TAG_NAME=${{ github.ref_name }} + PACKAGE_NAME=$(echo $TAG_NAME | sed 's/-[0-9][.0-9]*rc.*$//') + echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_OUTPUT + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + cache: "pip" + cache-dependency-path: "requirements*.txt" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install --upgrade build + working-directory: src/integrations/${{ steps.package_name.outputs.PACKAGE_NAME }} + + - name: Build a binary wheel and a source tarball + run: | + python -m build --wheel + python -m build --sdist + working-directory: src/integrations/${{ steps.package_name.outputs.PACKAGE_NAME }} + + - name: Publish build artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.package_name.outputs.PACKAGE_NAME }}-pypi-dists + path: "./src/integrations/${{ steps.package_name.outputs.PACKAGE_NAME }}/dist" + + publish-pypi-dists: + name: Publish to PyPI + environment: "prod" + needs: build-pypi-dists + runs-on: ubuntu-latest + permissions: + # this permission is mandatory for trusted publishing + id-token: write + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ needs.build-pypi-dists.outputs.PACKAGE_NAME}}-pypi-dists + path: "./dist" + + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/integration-package-tests.yaml b/.github/workflows/integration-package-tests.yaml new file mode 100644 index 000000000000..9baf1ba082b3 --- /dev/null +++ b/.github/workflows/integration-package-tests.yaml @@ -0,0 +1,107 @@ +name: Integrations Packages Tests + +on: + pull_request: + paths: + - .github/workflows/integration-package-tests.yaml + - "src/**/*.py" + types: [opened, reopened, synchronize, labeled, unlabeled] + push: + branches: + - main + paths: + - "src/integrations/*/**.py" + +jobs: + prepare-matrix: + # These tests will only run if the integration paths are affected, or someone has + # added the `integrations` label to the PR + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + - name: Generate matrix + id: set-matrix + run: | + if [[ "${{ contains(github.event.pull_request.labels.*.name, 'test-all-integrations') }}" == 'true' ]]; then + # All of the integration packages were changed since 2.19.2, so this is a + # standin for saying "all integrations" + COMMIT_RANGE="2.19.2..${{ github.event.pull_request.head.sha }}" + elif [[ $GITHUB_EVENT_NAME == 'pull_request' ]]; then + COMMIT_RANGE="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}" + else + COMMIT_RANGE="${{ github.event.before }}..${{ github.event.after }}" + fi + python scripts/generate_integration_package_tests_matrix.py "$COMMIT_RANGE" > matrix.json + cat matrix.json + echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + + run-tests: + timeout-minutes: 20 + + name: Run Tests for ${{ matrix.package }} on Python ${{ matrix.python-version }} + needs: prepare-matrix + runs-on: ubuntu-latest + strategy: + matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} + fail-fast: false + steps: + - name: Display current test matrix + run: echo '${{ toJSON(matrix) }}' + + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + id: setup_python + with: + python-version: ${{ matrix.python-version }} + + - name: UV Cache + # Manually cache the uv cache directory + # until setup-python supports it: + # https://github.com/actions/setup-python/issues/822 + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles(format('src/integrations/{0}/pyproject.toml', matrix.package)) }} + + - name: Install dependencies + working-directory: src/integrations/${{ matrix.package }} + # install uv, the package, and bleeding edge prefect + run: | + python -m pip install -U uv + uv pip install --upgrade --system -e .[dev] + uv pip install --upgrade --system ../../../ + + + - name: Run tests + if: matrix.package != 'prefect-ray' + env: + PREFECT_API_DATABASE_CONNECTION_URL: "sqlite+aiosqlite:///./orion-tests.db" + working-directory: src/integrations/${{ matrix.package }} + run: > + pytest tests + --numprocesses auto + --maxprocesses 6 + --dist worksteal + + # Run prefect-ray tests sequentially to avoid Ray cluster issues + - name: Run tests for prefect-ray + if: matrix.package == 'prefect-ray' + env: + PREFECT_API_DATABASE_CONNECTION_URL: "sqlite+aiosqlite:///./orion-tests.db" + working-directory: src/integrations/${{ matrix.package }} + run: > + pytest tests diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index 11fe5fad515a..e53d2180ec65 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -3,199 +3,115 @@ on: pull_request: paths: - .github/workflows/integration-tests.yaml - - "**/*.py" + - "src/prefect/**/*.py" - requirements.txt + - requirements-client.txt - requirements-dev.txt - ui/** - .nvmrc - Dockerfile + - flows/ push: branches: - main + paths: + - .github/workflows/integration-tests.yaml + - "**/*.py" + - requirements.txt + - requirements-client.txt + - requirements-dev.txt + - ui/** + - .nvmrc + - Dockerfile jobs: - playwright-tests: - # disabling these tests for now since they are broken because of pixi-viewport - if: ${{ false }} - name: "Test UI" - timeout-minutes: 20 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Set up Python 3.10 - uses: actions/setup-python@v4 - with: - python-version: "3.10" - cache: "pip" - cache-dependency-path: "requirements*.txt" - - - name: Install python packages - run: | - python -m pip install --upgrade pip - pip install --upgrade --upgrade-strategy eager -e .[dev] - - - name: Build UI - run: | - prefect dev build-ui - - - name: Run server in background - run: | - prefect server start& - - - name: Set up node - uses: actions/setup-node@v3 - with: - node-version-file: ".nvmrc" - cache-dependency-path: "**/package-lock.json" - - - name: Retrieve Playwright version - id: playwright-cache-key - run: | - echo "version=$(npx playwright -V)" >> $GITHUB_OUTPUT - - - name: Retrieve cached Playwright browsers - id: cache-playwright-browsers - uses: actions/cache@v3 - with: - path: ~/.cache/ms-playwright - key: ${{ steps.playwright-cache-key.outputs.version }}-playwright-browsers - - - name: Install Playwright browsers - working-directory: ./ui - run: npx playwright install --with-deps - - - name: Run Playwright tests - working-directory: ./ui - run: npx playwright test - - - uses: actions/upload-artifact@v3 - if: always() - with: - name: playwright-report - path: ./ui/playwright-report/ - retention-days: 30 - compatibility-tests: - name: "Check compatibility with Prefect ${{ matrix.prefect-version }}" + name: Integration tests @${{ matrix.server-version.version }} timeout-minutes: 10 + runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - prefect-version: + server-version: [ # These versions correspond to Prefect image tags, the patch version is - # excluded to always pull the latest patch of each minor version. - - "2.0" - - "2.1" - - "2.2" - - "2.3" - - "2.4" - - "2.5" - - "2.6" - - "2.7" - - "2.8" - - "2.9" - - "2.10" - - # We can include the following to always test against the last release - # but the value is not particularly clear and we can just append the - # last minor version at each release time - # - "2" - - include: - # While old clients should always be supported by new servers, a new - # client may send data that an old server does not support. These - # incompatibilities are allowed. - - # All servers prior to 2.6.0 will not accept 2.6.0+ result types - - prefect-version: "2.0" - server-incompatible: true - - prefect-version: "2.1" - server-incompatible: true - - prefect-version: "2.2" - server-incompatible: true - - prefect-version: "2.3" - server-incompatible: true - - prefect-version: "2.4" - server-incompatible: true - - prefect-version: "2.5" - server-incompatible: true - - # 2.6 containers have a bad version of httpcore installed - - prefect-version: "2.6" - extra_docker_run_options: '--env EXTRA_PIP_PACKAGES="httpcore>=0.16.2"' - server_command: "prefect orion start" - - # 2.6/2.7 require `prefect orion start` instead of prefect server start - - prefect-version: "2.7" - server_command: "prefect orion start" + # excluded to always pull the latest patch of each minor version. The ref + # should generally be set to the latest patch release for that version. + {version: "2.19", ref: "2.19.2", image: "prefecthq/prefect:2.19-python3.10"}, + {version: "main", ref: "main"}, + ] - fail-fast: false - - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: persist-credentials: false fetch-depth: 0 - name: Set up Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 + id: setup_python with: python-version: "3.10" - cache: "pip" - cache-dependency-path: "requirements*.txt" + + - name: UV Cache + # Manually cache the uv cache directory + # until setup-python supports it: + # https://github.com/actions/setup-python/issues/822 + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('requirements-client.txt', 'requirements.txt', 'requirements-dev.txt') }} - name: Install python packages run: | - python -m pip install --upgrade pip - pip install --upgrade --upgrade-strategy eager -e .[dev] - - - name: Start server@${{ matrix.prefect-version }} - if: ${{ ! matrix.server-incompatible }} + python -m pip install -U uv + uv pip install --upgrade --system . + + - name: Start server@${{ matrix.server-version.version }} + if: ${{ matrix.server-version.version != 'main' }} + env: + PREFECT_API_URL: http://127.0.0.1:4200/api + PREFECT_LOGGING_SERVER_LEVEL: DEBUG + PREFECT_EXPERIMENTAL_EVENTS: "true" run: > - docker run - --name "prefect-server-${{ matrix.prefect-version }}" - --detach - --publish 4200:4200 - ${{ matrix.extra_docker_run_options }} - prefecthq/prefect:${{ matrix.prefect-version }}-python3.10 - ${{ matrix.server_command || 'prefect server start' }} --host 0.0.0.0 + docker run \ + --name "prefect-server" \ + -d \ + -p 4200:4200 \ + -e PREFECT_API_URL=${{ env.PREFECT_API_URL }} \ + -e PREFECT_LOGGING_SERVER_LEVEL=${{ env.PREFECT_LOGGING_SERVER_LEVEL }} \ + -e PREFECT_EXPERIMENTAL_EVENTS=${{ env.PREFECT_EXPERIMENTAL_EVENTS }} \ + ${{ matrix.server-version.image }} \ + prefect server start --analytics-off --host 0.0.0.0 - PREFECT_API_URL="http://127.0.0.1:4200/api" ./scripts/wait-for-server.py # TODO: Replace `wait-for-server` with dedicated command # https://github.com/PrefectHQ/prefect/issues/6990 - - name: Run integration flows with client@dev, server@${{ matrix.prefect-version }} - if: ${{ ! matrix.server-incompatible }} + - name: Start server + if: ${{ matrix.server-version.version == 'main' }} + env: + PREFECT_API_URL: http://127.0.0.1:4200/api + PREFECT_LOGGING_SERVER_LEVEL: DEBUG run: > - TEST_SERVER_VERSION=${{ matrix.prefect-version }} - PREFECT_API_URL="http://127.0.0.1:4200/api" - TEST_CLIENT_VERSION=$(python -c 'import prefect; print(prefect.__version__)') - ./scripts/run-integration-flows.py + prefect server start --analytics-off --host 0.0.0.0 2>&1 > server.log & - - name: Start server@dev - run: | - # First, we must stop the server container if it exists - # TODO: Once we have `prefect server stop` we can run these tests first and the - # optional tests above second - # https://github.com/PrefectHQ/prefect/issues/6989 - docker stop "prefect-server-${{ matrix.prefect-version }}" || echo "That's okay!" + ./scripts/wait-for-server.py - prefect server start& - PREFECT_API_URL="http://127.0.0.1:4200/api" ./scripts/wait-for-server.py + # TODO: Replace `wait-for-server` with dedicated command + # https://github.com/PrefectHQ/prefect/issues/6990 - - name: Run integration flows with client@${{ matrix.prefect-version }}, server@dev + - name: Run integration flows + env: + PREFECT_API_URL: http://127.0.0.1:4200/api + SERVER_VERSION: ${{ matrix.server-version.version }} run: > - docker run - --env PREFECT_API_URL="http://127.0.0.1:4200/api" - --env TEST_SERVER_VERSION=$(python -c 'import prefect; print(prefect.__version__)') - --env TEST_CLIENT_VERSION=${{ matrix.client_version }} - --volume $(pwd)/flows:/opt/prefect/integration/flows - --volume $(pwd)/scripts:/opt/prefect/integration/scripts - --network host - ${{ matrix.extra_docker_run_options }} - prefecthq/prefect:${{ matrix.prefect-version }}-python3.10 - /opt/prefect/integration/scripts/run-integration-flows.py /opt/prefect/integration/flows + ./scripts/run-integration-flows.py flows/ + + - name: Show server logs + if: always() + run: | + cat server.log || echo "No logs available" + docker logs prefect-server || echo "No logs available" diff --git a/.github/workflows/issue-bot.yaml b/.github/workflows/issue-bot.yaml index 5568383612bf..2a3edfa577c9 100644 --- a/.github/workflows/issue-bot.yaml +++ b/.github/workflows/issue-bot.yaml @@ -10,24 +10,6 @@ jobs: steps: - name: Remove status labels on close if: github.event.action == 'closed' - run: gh issue edit --repo prefecthq/prefect ${{ github.event.issue.number }} --remove-label "status:triage" --remove-label "status:in-progress" --remove-label "status:accepted" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Update issue status when assigned - if: github.event.action == 'assigned' - run: gh issue edit --repo prefecthq/prefect ${{ github.event.issue.number }} --add-label "status:in-progress" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Update issue status when unassigned - if: github.event.action == 'unassigned' - run: gh issue edit --repo prefecthq/prefect ${{ github.event.issue.number }} --remove-label "status:in-progress" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Remove triage label on status change - if: github.event.action == 'labeled' && startsWith(github.event.label.name, 'status:') && github.event.label.name != 'status:triage' - run: gh issue edit --repo prefecthq/prefect ${{ github.event.issue.number }} --remove-label "status:triage" + run: gh issue edit --repo prefecthq/prefect ${{ github.event.issue.number }} --remove-label "needs:triage" --remove-label "needs:attention" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 3633380ec31b..a011e431245e 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -12,6 +12,6 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/labeler@v4 + - uses: actions/labeler@v5 with: repo-token: "${{ github.token }}" diff --git a/.github/workflows/npm_update_latest_prefect.yaml b/.github/workflows/npm_update_latest_prefect.yaml new file mode 100644 index 000000000000..7fca41747bc1 --- /dev/null +++ b/.github/workflows/npm_update_latest_prefect.yaml @@ -0,0 +1,66 @@ +--- + name: Update to latest Prefect Packages + on: + workflow_dispatch: + inputs: + package_name: + description: The name of the Prefect package to update + required: true + package_version: + description: The version of the Prefect package to update + required: true + permissions: {} + + jobs: + update_prefect_packages: + runs-on: ubuntu-latest + permissions: + # required to write to the repo + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Create Branch For Dependency Version Updates + run: git checkout -b "prefect-package-${{ inputs.package_name }}-${{ inputs.package_version }}-update" + + - name: Setup NodeJS + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache-dependency-path: "**/package-lock.json" + + - name: Install Dependencies + run: npm ci + working-directory: ./ui + + - name: Upgrade Package + run: | + npm i @${{ inputs.package_name }}@${{ inputs.package_version }} --save-exact + working-directory: ./ui + + - name: Commit Package Changes + run: | + git add . + git commit -m "Update @${{ inputs.package_name }} to version ${{ inputs.package_version }}" + git push --set-upstream origin "prefect-package-${{ inputs.package_name }}-${{ inputs.package_version }}-update" + env: + GITHUB_TOKEN: ${{ github.token }} + + - name: Create Pull Request + run: | + git checkout "prefect-package-${{ inputs.package_name }}-${{ inputs.package_version }}-update" + gh pr create \ + --base main \ + --title "Update @${{ inputs.package_name }} to version ${{ inputs.package_version }}" \ + --body "Update @${{ inputs.package_name }} to version ${{ inputs.package_version }}. + Release information can be found at https://github.com/${{ inputs.package_name }}/releases/tag/${{ inputs.package_version }}." \ + --label maintenance \ + --label ui + env: + GITHUB_TOKEN: ${{ secrets.PREFECT_CONTENTS_PR_RW }} + \ No newline at end of file diff --git a/.github/workflows/prefect-client-publish.yaml b/.github/workflows/prefect-client-publish.yaml new file mode 100644 index 000000000000..df3d30730f98 --- /dev/null +++ b/.github/workflows/prefect-client-publish.yaml @@ -0,0 +1,33 @@ + +name: Build and publish the prefect-client + +on: + release: + types: [released, prereleased] + +jobs: + verify-prefect-client-build: + uses: ./.github/workflows/prefect-client.yaml + with: + upload-artifacts: true + artifact-name: "prefect-client-pypi-dists" + secrets: inherit + + publish-prefect-client-pypi-dists: + name: Publish to PyPI + environment: "prod" + needs: [verify-prefect-client-build] + runs-on: ubuntu-latest + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: "prefect-client-pypi-dists" + path: "./dist" + + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PREFECT_CLIENT_PYPI_API_TOKEN }} + name: ci diff --git a/.github/workflows/prefect-client.yaml b/.github/workflows/prefect-client.yaml new file mode 100644 index 000000000000..fbeda01bd71f --- /dev/null +++ b/.github/workflows/prefect-client.yaml @@ -0,0 +1,92 @@ +name: Verify prefect-client build + +on: + pull_request: + branches: + - main + paths: + - client/* + - src/prefect/**/*.py + - requirements.txt + - requirements-client.txt + - setup.cfg + push: + branches: + - main + paths: + - client/* + - src/prefect/**/*.py + - requirements.txt + - requirements-client.txt + - setup.cfg + workflow_call: + inputs: + upload-artifacts: + description: "Whether or not to upload artifacts created in this workflow" + default: false + type: boolean + artifact-name: + description: "The name for the build prefect-client artifact" + default: "prefect-client-pypi-dists" + type: string + +jobs: + prefect-client-smoke-test: + name: Build and run prefect-client + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + # Versioneer only generates correct versions with a full fetch + fetch-depth: 0 + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + cache: "pip" + cache-dependency-path: "requirements-client.txt" + + - name: Create a temp dir to stage our build + run: echo "TMPDIR=$(mktemp -d)" >> $GITHUB_ENV + + - name: Prepare files for prefect-client build (omit the local build) + run: sh client/build_client.sh + env: + TMPDIR: ${{ env.TMPDIR }} + + - name: Build a binary wheel and a source tarball + run: pip install wheel && python setup.py sdist bdist_wheel + working-directory: ${{ env.TMPDIR }} + + - name: Install the built client from the locally built package + run: pip install dist/*.tar.gz + working-directory: ${{ env.TMPDIR }} + + - name: Run the smoke test flow using the built client + run: python client/client_flow.py + working-directory: ${{ env.TMPDIR }} + env: + PREFECT_API_KEY: ${{ secrets.PREFECT_CLIENT_SA_API_KEY }} + PREFECT_API_URL: "https://api.prefect.cloud/api/accounts/9b649228-0419-40e1-9e0d-44954b5c0ab6/workspaces/96bd3cf8-85c9-4545-9713-b4e3c3e03466" # sandbox, prefect-client workspace + + - name: Install prefect from source + run: pip install . + + - name: (DEBUG) Check that prefect and prefect-client are installed + run: pip list | grep prefect + + - name: Run the smoke test flow again with prefect and prefect-client installed + run: python client/client_flow.py + working-directory: ${{ env.TMPDIR }} + env: + PREFECT_API_KEY: ${{ secrets.PREFECT_CLIENT_SA_API_KEY }} + PREFECT_API_URL: "https://api.prefect.cloud/api/accounts/9b649228-0419-40e1-9e0d-44954b5c0ab6/workspaces/96bd3cf8-85c9-4545-9713-b4e3c3e03466" # sandbox, prefect-client workspace + + - name: Publish build artifacts + if: ${{ inputs.upload-artifacts }} + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.artifact-name }} + path: "${{ env.TMPDIR }}/dist" diff --git a/.github/workflows/python-package.yaml b/.github/workflows/python-package.yaml index 33e15dff6e64..25e1d9146428 100644 --- a/.github/workflows/python-package.yaml +++ b/.github/workflows/python-package.yaml @@ -3,6 +3,12 @@ name: Publish Python package on: release: types: [released, prereleased] + workflow_dispatch: + inputs: + commit: + description: "Commit to build from" + required: true + default: "main" jobs: build-pypi-dists: @@ -11,27 +17,28 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: + ref: ${{ github.event.inputs.commit }} # Versioneer only generates correct versions with a full fetch fetch-depth: 0 persist-credentials: false - - name: Set up Python 3.8 - uses: actions/setup-python@v4 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.9" cache: "pip" cache-dependency-path: "requirements*.txt" - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache-dependency-path: "**/package-lock.json" - name: Install python packages run: | - python -m pip install --upgrade pip + python -m pip install --upgrade pip wheel pip install --upgrade --upgrade-strategy eager -e .[dev] - name: Build UI @@ -43,7 +50,7 @@ jobs: python setup.py sdist bdist_wheel - name: Publish build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: pypi-dists path: "./dist" @@ -56,7 +63,7 @@ jobs: steps: - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: pypi-dists path: "./dist" diff --git a/.github/workflows/python-tests.yaml b/.github/workflows/python-tests.yaml index ae5552327a11..59a22dba1c22 100644 --- a/.github/workflows/python-tests.yaml +++ b/.github/workflows/python-tests.yaml @@ -1,7 +1,5 @@ name: Unit tests -# Note: Conda support for 3.11 is pending. See https://github.com/ContinuumIO/anaconda-issues/issues/13082 - env: # enable colored output # https://github.com/pytest-dev/pytest/issues/7443 @@ -11,14 +9,25 @@ on: pull_request: paths: - .github/workflows/python-tests.yaml - - "**/*.py" + - "src/prefect/**/*.py" + - "tests/**/*.py" - requirements.txt + - requirements-client.txt - requirements-dev.txt - setup.cfg - Dockerfile push: branches: - main + paths: + - .github/workflows/python-tests.yaml + - "src/prefect/**/*.py" + - "tests/**/*.py" + - requirements.txt + - requirements-client.txt + - requirements-dev.txt + - setup.cfg + - Dockerfile permissions: contents: read @@ -33,135 +42,358 @@ permissions: # # https://docs.github.com/en/actions/using-jobs/using-concurrency concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: run-tests: - name: python:${{ matrix.python-version }}, ${{ matrix.database }}, ${{ matrix.pytest-options }} - + runs-on: + group: oss-larger-runners + name: python:${{ matrix.python-version }}, ${{ matrix.database }} strategy: matrix: database: - - "postgres:13" - "postgres:14" - "sqlite" - os: - - ubuntu-latest python-version: - - "3.7" - - "3.8" - "3.9" - "3.10" - "3.11" - pytest-options: - - "--exclude-services" - - "--only-services" + - "3.12" + + fail-fast: true + + timeout-minutes: 45 + + steps: + - name: Display current test matrix + run: echo '${{ toJSON(matrix) }}' + + - uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + id: setup_python + with: + python-version: ${{ matrix.python-version }} + + - name: UV Cache + # Manually cache the uv cache directory + # until setup-python supports it: + # https://github.com/actions/setup-python/issues/822 + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('requirements-client.txt', 'requirements.txt', 'requirements-dev.txt') }} + + - name: Install packages + run: | + python -m pip install -U uv + uv pip install --upgrade --system -e .[dev] + + - name: Start database container + if: ${{ startsWith(matrix.database, 'postgres') }} + run: > + docker run + --name "postgres" + --detach + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + --publish 5432:5432 + --tmpfs /var/lib/postgresql/data + --env POSTGRES_USER="prefect" + --env POSTGRES_PASSWORD="prefect" + --env POSTGRES_DB="prefect" + --env LANG="C.UTF-8" + --env LANGUAGE="C.UTF-8" + --env LC_ALL="C.UTF-8" + --env LC_COLLATE="C.UTF-8" + --env LC_CTYPE="C.UTF-8" + ${{ matrix.database }} + -c max_connections=250 - include: - # Run 3.7 tests with lower bound pins - - python-version: "3.7" - lower-bound-requirements: true + ./scripts/wait-for-healthy-container.sh postgres 30 - # Include Docker image builds on the service test run, and disallow the test - # suite from building images automaticlly in fixtures - - pytest-options: "--only-services" - build-docker-images: true + echo "PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://prefect:prefect@localhost/prefect" >> $GITHUB_ENV - exclude: - # Do not run service tests with postgres - - database: "postgres:13" - pytest-options: "--only-services" + # Parallelize tests by scope to reduce expensive service fixture duplication + # Do not allow the test suite to build images, as we want the prebuilt images to be tested + # Do not run Kubernetes service tests, we do not have a cluster available + # maxprocesses 6 is based on empirical testing; higher than 6 sees diminishing returns + - name: Run tests + env: + PREFECT_EXPERIMENTAL_ENABLE_PYDANTIC_V2_INTERNALS: "1" + run: > + pytest tests + --numprocesses auto + --maxprocesses 6 + --dist worksteal + --disable-docker-image-builds + --exclude-service kubernetes + --exclude-service docker + --durations 26 + --no-cov - # Do not run service tests with postgres - - database: "postgres:14" - pytest-options: "--only-services" + - name: Create and Upload failure flag + if: ${{ failure() }} + id: create_failure_flag + run: | + sanitized_name="${{ matrix.python-version }}-${{ matrix.database }}" + sanitized_name="${sanitized_name//:/-}" + echo "Failure in $sanitized_name" > "${sanitized_name}-failure.txt" + echo "artifact_name=${sanitized_name}-failure" >> $GITHUB_OUTPUT + - name: Upload failure flag + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.create_failure_flag.outputs.artifact_name }} + path: "${{ steps.create_failure_flag.outputs.artifact_name }}.txt" - fail-fast: false + - name: Check database container + # Only applicable for Postgres, but we want this to run even when tests fail + if: always() + run: > + docker container inspect postgres + && docker container logs postgres + || echo "Ignoring bad exit code" + + notify-tests-failing-on-main: + needs: run-tests + if: github.ref == 'refs/heads/main' && failure() + runs-on: ubuntu-latest + env: + FAILURE_THRESHOLD: 1 + steps: + - name: Download all failure flags + uses: actions/download-artifact@v4 + with: + path: failure-flags/ + + - name: Check for failure flags + id: check_failure + run: | + failure_count=$(ls -1q failure-flags/*/*.txt | wc -l) + + if [ $failure_count -gt $FAILURE_THRESHOLD ]; then + too_many_tests_failed="true" + else + too_many_tests_failed="false" + fi + echo "failure_count=$failure_count" >> $GITHUB_OUTPUT + echo "too_many_tests_failed=$too_many_tests_failed" >> $GITHUB_OUTPUT + + - name: Send Slack Notification + if: ${{ steps.check_failure.outputs.too_many_tests_failed == 'true' }} + uses: 8398a7/action-slack@v3 + with: + author_name: Prefect OSS Tests Failing on Main + channel: CBH18KG8G # This is #engineering + fields: message,commit,author,workflowRun + status: failure + text: ":warning: Unit tests are failing in Prefect's main branch. Commit author: please either fix or remove the failing tests. If you remove the failing tests create a GitHub issue with the details." + env: + SLACK_WEBHOOK_URL: ${{ secrets.ENGINEERING_REVIEW_SLACK_WEBHOOK_URL }} + + run-tests-for-datadog: + name: DataDog CI Visibility + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: + group: oss-larger-runners + strategy: + matrix: + database: + - "postgres:14" + python-version: + - "3.12" + + fail-fast: true - runs-on: ${{ matrix.os }} timeout-minutes: 45 steps: - name: Display current test matrix run: echo '${{ toJSON(matrix) }}' - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: persist-credentials: false fetch-depth: 0 - name: Set up Docker Buildx - if: ${{ matrix.build-docker-images }} - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 + with: + driver-opts: image=moby/buildkit:v0.12.5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 + id: setup_python with: python-version: ${{ matrix.python-version }} - cache: "pip" - cache-dependency-path: "requirements*.txt" - - name: Pin requirements to lower bounds - if: ${{ matrix.lower-bound-requirements }} - # Creates lower bound files then replaces the input files so we can do a normal install + - name: UV Cache + # Manually cache the uv cache directory + # until setup-python supports it: + # https://github.com/actions/setup-python/issues/822 + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('requirements-client.txt', 'requirements.txt', 'requirements-dev.txt') }} + + - name: Get image tag + id: get_image_tag run: | - ./scripts/generate-lower-bounds.py requirements.txt > requirements-lower.txt - ./scripts/generate-lower-bounds.py requirements-dev.txt > requirements-dev-lower.txt - mv requirements-lower.txt requirements.txt - mv requirements-dev-lower.txt requirements-dev.txt + SHORT_SHA=$(git rev-parse --short=7 HEAD) + tmp="sha-$SHORT_SHA-python${{ matrix.python-version }}" + echo "image_tag=${tmp}" >> $GITHUB_OUTPUT - name: Build test image - if: ${{ matrix.build-docker-images }} - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . - # TODO: We do not need the UI in these tests and we may want to add a build-arg to disable building it - # so that CI test runs are faster build-args: | PYTHON_VERSION=${{ matrix.python-version }} PREFECT_EXTRAS=[dev] - tags: prefecthq/prefect:dev-python${{ matrix.python-version }} + tags: prefecthq/prefect-dev:${{ steps.get_image_tag.outputs.image_tag }} outputs: type=docker,dest=/tmp/image.tar - cache-from: type=gha - cache-to: type=gha,mode=max - name: Test Docker image - if: ${{ matrix.build-docker-images }} run: | docker load --input /tmp/image.tar - docker run --rm prefecthq/prefect:dev-python${{ matrix.python-version }} prefect version + docker run --rm prefecthq/prefect-dev:${{ steps.get_image_tag.outputs.image_tag }} prefect version + + - name: Install packages + run: | + python -m pip install -U uv + uv pip install --upgrade --system -e .[dev] - - name: Build Conda flavored test image - # Not yet supported for 3.11, see note at top - if: ${{ matrix.build-docker-images && matrix.python-version != '3.11' }} - uses: docker/build-push-action@v4 + - name: Start database container + run: > + docker run + --name "postgres" + --detach + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + --publish 5432:5432 + --tmpfs /var/lib/postgresql/data + --env POSTGRES_USER="prefect" + --env POSTGRES_PASSWORD="prefect" + --env POSTGRES_DB="prefect" + --env LANG="C.UTF-8" + --env LANGUAGE="C.UTF-8" + --env LC_ALL="C.UTF-8" + --env LC_COLLATE="C.UTF-8" + --env LC_CTYPE="C.UTF-8" + ${{ matrix.database }} + -c max_connections=250 + + ./scripts/wait-for-healthy-container.sh postgres 30 + + echo "PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://prefect:prefect@localhost/prefect" >> $GITHUB_ENV + + - name: Run tests + env: + PREFECT_EXPERIMENTAL_ENABLE_PYDANTIC_V2_INTERNALS: "1" + DD_CIVISIBILITY_AGENTLESS_ENABLED: true + DD_API_KEY: ${{ secrets.DD_API_KEY_CI_VISIBILITY }} + DD_SITE: datadoghq.com + DD_ENV: ci + DD_SERVICE: prefect + run: > + pytest tests + --numprocesses auto + --maxprocesses 6 + --ddtrace + --dist worksteal + --disable-docker-image-builds + --exclude-service kubernetes + --durations 26 + --cov + --cov-config setup.cfg + + run-docker-tests: + runs-on: + group: oss-larger-runners + name: docker, python:${{ matrix.python-version }} + strategy: + matrix: + database: + - "postgres:14" + python-version: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + + fail-fast: true + + timeout-minutes: 45 + + steps: + - name: Display current test matrix + run: echo '${{ toJSON(matrix) }}' + + - uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: image=moby/buildkit:v0.12.5 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + id: setup_python + with: + python-version: ${{ matrix.python-version }} + + - name: UV Cache + # Manually cache the uv cache directory + # until setup-python supports it: + # https://github.com/actions/setup-python/issues/822 + uses: actions/cache@v4 + id: cache-uv + with: + path: ~/.cache/uv + key: uvcache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('requirements-client.txt', 'requirements.txt', 'requirements-dev.txt') }} + + - name: Get image tag + id: get_image_tag + run: | + SHORT_SHA=$(git rev-parse --short=7 HEAD) + tmp="sha-$SHORT_SHA-python${{ matrix.python-version }}" + echo "image_tag=${tmp}" >> $GITHUB_OUTPUT + + - name: Build test image + uses: docker/build-push-action@v5 with: context: . build-args: | PYTHON_VERSION=${{ matrix.python-version }} - BASE_IMAGE=prefect-conda PREFECT_EXTRAS=[dev] - tags: prefecthq/prefect:dev-python${{ matrix.python-version }}-conda - outputs: type=docker,dest=/tmp/image-conda.tar - cache-from: type=gha - # We do not cache Conda image layers because they very big and slow to upload - # cache-to: type=gha,mode=max - - - name: Test Conda flavored Docker image - # Not yet supported for 3.11, see note at top - if: ${{ matrix.build-docker-images && matrix.python-version != '3.11' }} + tags: prefecthq/prefect-dev:${{ steps.get_image_tag.outputs.image_tag }} + outputs: type=docker,dest=/tmp/image.tar + + - name: Test Docker image run: | - docker load --input /tmp/image-conda.tar - docker run --rm prefecthq/prefect:dev-python${{ matrix.python-version }}-conda prefect version - docker run --rm prefecthq/prefect:dev-python${{ matrix.python-version }}-conda conda --version + docker load --input /tmp/image.tar + docker run --rm prefecthq/prefect-dev:${{ steps.get_image_tag.outputs.image_tag }} prefect version - name: Install packages run: | - python -m pip install pip==23.0.1 - # If using not using lower bounds, upgrade eagerly to get the latest versions despite caching - pip install ${{ ! matrix.lower-bound-requirements && '--upgrade --upgrade-strategy eager' || ''}} -e .[dev] + python -m pip install -U uv + uv pip install --upgrade --system -e .[dev] - name: Start database container if: ${{ startsWith(matrix.database, 'postgres') }} @@ -184,17 +416,52 @@ jobs: --env LC_COLLATE="C.UTF-8" --env LC_CTYPE="C.UTF-8" ${{ matrix.database }} + -c max_connections=250 ./scripts/wait-for-healthy-container.sh postgres 30 echo "PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://prefect:prefect@localhost/prefect" >> $GITHUB_ENV + - name: Start docker registry + run: > + docker run + --name "prefect-test-registry" + --detach + --publish 5555:5000 + registry:2 + + # Parallelize tests by scope to reduce expensive service fixture duplication + # Do not allow the test suite to build images, as we want the prebuilt images to be tested + # Do not run Kubernetes service tests, we do not have a cluster available + # maxprocesses 6 is based on empirical testing; higher than 6 sees diminishing returns - name: Run tests + env: + PREFECT_EXPERIMENTAL_ENABLE_PYDANTIC_V2_INTERNALS: "1" + run: > + pytest tests + --numprocesses auto + --maxprocesses 6 + --dist worksteal + --disable-docker-image-builds + --only-service docker + --durations 26 + --no-cov + + - name: Create and Upload failure flag + if: ${{ failure() }} + id: create_failure_flag run: | - # Parallelize tests by scope to reduce expensive service fixture duplication - # Do not allow the test suite to build images, as we want the prebuilt images to be tested - # Do not run Kubernetes service tests, we do not have a cluster available - pytest tests -vvv --numprocesses auto --dist loadscope --disable-docker-image-builds --exclude-service kubernetes --durations=25 --cov=src/ --cov=tests/ --no-cov-on-fail --cov-report=term --cov-config=setup.cfg ${{ matrix.pytest-options }} + sanitized_name="${{ matrix.python-version }}-${{ matrix.database }}" + sanitized_name="${sanitized_name//:/-}" + echo "Failure in $sanitized_name" > "${sanitized_name}-failure.txt" + echo "artifact_name=${sanitized_name}-failure" >> $GITHUB_OUTPUT + + - name: Upload failure flag + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.create_failure_flag.outputs.artifact_name }} + path: "${{ steps.create_failure_flag.outputs.artifact_name }}.txt" - name: Check database container # Only applicable for Postgres, but we want this to run even when tests fail @@ -202,4 +469,4 @@ jobs: run: > docker container inspect postgres && docker container logs postgres - || echo "Ignoring bad exit code" \ No newline at end of file + || echo "Ignoring bad exit code" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index dc16de73b9e2..52745a4ee7f0 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,4 +1,4 @@ -name: "Close stale issues and PRs" +name: "Close stale PRs" on: schedule: - cron: "0 * * * *" @@ -7,17 +7,15 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: - stale-issue-message: "This issue is stale because it has been open 30 days with no activity. To keep this issue open remove stale label or comment." - stale-issue-label: "status:stale" - close-issue-message: "This issue was closed because it has been stale for 14 days with no activity. If this issue is important or you have more to add feel free to re-open it." - days-before-stale: 30 - stale-pr-message: "This pull request is stale because it has been open 60 days with no activity. To keep this pull request open remove stale label or comment." + days-before-stale: -1 + days-before-close: -1 + stale-pr-message: "This pull request is stale because it has been open 14 days with no activity. To keep this pull request open remove stale label or comment." stale-pr-label: "status:stale" close-pr-message: "This pull request was closed because it has been stale for 14 days with no activity. If this pull request is important or you have more to add feel free to re-open it." - days-before-pr-stale: 60 - days-before-close: 14 - exempt-issue-labels: "status:in-progress,status:roadmap,status:accepted" + days-before-pr-stale: 14 + days-before-pr-close: 14 + exempt-issue-labels: "needs:attention,needs:triage,blocked" ascending: true # https://github.com/actions/stale#ascending operations-per-run: 500 diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index bb0cbc1c37d8..e91a12f721e4 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -15,7 +15,7 @@ permissions: # # https://docs.github.com/en/actions/using-jobs/using-concurrency concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: @@ -24,12 +24,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: persist-credentials: false - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.9 diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index 4c903abd3fb1..0fc03802812d 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -23,7 +23,7 @@ permissions: # # https://docs.github.com/en/actions/using-jobs/using-concurrency concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: @@ -32,9 +32,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache-dependency-path: '**/package-lock.json' diff --git a/.github/workflows/validate_worker_metadata.yaml b/.github/workflows/validate_worker_metadata.yaml new file mode 100644 index 000000000000..7ac18ef25573 --- /dev/null +++ b/.github/workflows/validate_worker_metadata.yaml @@ -0,0 +1,28 @@ +name: Ensure JSON views are valid on PR +on: + pull_request: + branches: + - main + paths: + - "src/prefect/server/api/collections_data/views/*.json" +jobs: + submit-update-pr: + name: Run JSON schema validation against all views + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install fastjsonschema==2.19.1 + + - name: Run JSON schema validation + run: | + python scripts/validate_collection_view_content.py diff --git a/.github/workflows/windows-pull-request.yaml b/.github/workflows/windows-pull-request.yaml new file mode 100644 index 000000000000..1871328bc009 --- /dev/null +++ b/.github/workflows/windows-pull-request.yaml @@ -0,0 +1,76 @@ +name: Windows tests (Pull Request) + +on: + pull_request: + branches: + - main + types: + - opened + - reopened + - synchronize + - labeled + - unlabeled + +permissions: {} + +# Limit concurrency by workflow/branch combination. +# +# For pull request builds, pushing additional changes to the +# branch will cancel prior in-progress and pending builds. +# +# For builds triggered on a branch push, additional changes +# will wait for prior builds to complete before starting. +# +# https://docs.github.com/en/actions/using-jobs/using-concurrency +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + run-tests-sqlite: + name: Test with SQLite + if: contains(github.event.pull_request.labels.*.name, 'arch:windows') + + strategy: + matrix: + python-version: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + + fail-fast: true + + permissions: + contents: read + + runs-on: windows-latest + timeout-minutes: 45 + + env: + # enable colored output + # https://github.com/pytest-dev/pytest/issues/7443 + PY_COLORS: 1 + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + cache-dependency-path: "requirements*.txt" + + - name: Install packages + run: | + python -m pip install --upgrade pip + pip install --upgrade --upgrade-strategy eager -e .[dev] + + - name: Run tests + run: | + # Parallelize tests by scope to reduce expensive service fixture duplication + pytest tests -vv --numprocesses auto --dist worksteal --exclude-services --durations=25 diff --git a/.github/workflows/windows-tests.yaml b/.github/workflows/windows-tests.yaml index dc37dd4fd5ea..6b2375c0c1e7 100644 --- a/.github/workflows/windows-tests.yaml +++ b/.github/workflows/windows-tests.yaml @@ -1,16 +1,11 @@ name: Windows tests -env: - # enable colored output - # https://github.com/pytest-dev/pytest/issues/7443 - PY_COLORS: 1 - on: + workflow_dispatch: {} schedule: - cron: '0 16 * * *' # every day at 4 p.m. UTC / 9 a.m. PDT -permissions: - contents: read +permissions: {} jobs: run-tests-sqlite: @@ -18,30 +13,33 @@ jobs: strategy: matrix: - # We only test Windows against 3.9 currently. python-version: - "3.9" + - "3.10" + - "3.11" + - "3.12" + + fail-fast: true - fail-fast: false + permissions: + contents: read runs-on: windows-latest timeout-minutes: 45 - steps: - - name: Display current test matrix - run: echo '${{ toJSON(matrix) }}' + env: + # enable colored output + # https://github.com/pytest-dev/pytest/issues/7443 + PY_COLORS: 1 - - uses: actions/checkout@v3 + steps: + - uses: actions/checkout@v4 with: persist-credentials: false fetch-depth: 0 - - name: Set up Docker Buildx - if: ${{ matrix.build-docker-images }} - uses: docker/setup-buildx-action@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" @@ -50,9 +48,9 @@ jobs: - name: Install packages run: | python -m pip install --upgrade pip - pip install--upgrade --upgrade-strategy eager -e .[dev] + pip install --upgrade --upgrade-strategy eager -e .[dev] - name: Run tests run: | # Parallelize tests by scope to reduce expensive service fixture duplication - pytest tests -vv --numprocesses auto --dist loadscope --exclude-services --durations=25 + pytest tests -vv --numprocesses auto --dist worksteal --exclude-services --durations=25 diff --git a/.gitignore b/.gitignore index d59e631cd674..3cd4730f4f31 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ dist/ sdist/ # Test artifacts +.benchmarks/ .coverage .coverage.*.* .prefect-results @@ -36,12 +37,14 @@ env/ venv/ # Documentation artifacts -schema.json +# gschema.json site/ .cache/ +src/mkdocs-material # UI artifacts src/prefect/server/ui/* +src/prefect/server/ui_build/* **/node_modules # Databases @@ -60,3 +63,16 @@ dask-worker-space/ .idea/ .vscode/ !ui/.vscode/ + +# Prefect files +prefect.yaml + +# Deployment recipes +!src/prefect/deployments/recipes/*/** + +# For development doc server if link +libcairo.2.dylib + +# setuptools-scm generated files +src/integrations/*/**/_version.py +*.log \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..14b509f0c4d5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "compat-tests"] + path = compat-tests + url = https://github.com/PrefectHQ/compat-tests.git diff --git a/.nvmrc b/.nvmrc index 97dcb79e026a..6aab9b43fa34 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16.5.0 +v18.18.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8170a6e46ebc..124a79752928 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,21 +1,26 @@ repos: - - repo: https://github.com/fsouza/autoflake8 - rev: v0.4.0 - hooks: - - id: autoflake8 - language_version: python3 - args: [ - '--in-place', - '--exclude','*/utilities/compat.py,*/utilities/slugify.py,**__init__.py', - ] - - repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - language_version: python3 - - repo: https://github.com/psf/black - rev: 23.1.0 - hooks: - - id: black - language_version: python3 - args: ['--preview'] + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.2.1" + hooks: + - id: ruff + language_version: python3 + args: [--fix, --exit-non-zero-on-fix, --show-fixes] + - id: ruff-format + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + exclude: package-lock.json|_vendor/.*|docs/.* + - repo: https://github.com/netromdk/vermin + rev: v1.6.0 + hooks: + - id: vermin + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.9.0 + hooks: + - id: mypy + additional_dependencies: + - pydantic>=1.10.0,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0 + - types-cachetools==5.3.0.5 + - types-pyyaml==6.0.12.9 + files: ^(src/prefect/server/models/agents\.py|src/prefect/server/models/flows\.py|src/prefect/concurrency/.*|src/prefect/events/.*|src/prefect/input/.*)$ diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 000000000000..acdf7c1b764d --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,26 @@ +src = ["src"] + +# Use Ruff for sorting imports +lint.extend-select = ["I"] + +# Do not enforce line length; black does this for code and we do not care about comments / docs +lint.ignore = ["E501"] + +[lint.per-file-ignores] +# Do not enforce usage and import order rules in init files +"__init__.py" = ["E402", "F401", "I"] + +# Do not fix import in compatibility module +"src/prefect/utilities/compat.py" = ["F401", "I"] + +# Allow wild imports in conftest +"tests/conftest.py" = ["F405", "E402", "F403"] + +# Allow fake items in __all__ for runtime +"src/prefect/runtime/*" = ["F822"] + +# Do not enforce line length limits in migrations +"src/prefect/server/database/migrations/**/*" = ["E501"] + +[lint.isort] +known-third-party = [] diff --git a/Dockerfile b/Dockerfile index 6072ce9612d1..4d58f910030d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # The version of Python in the final image -ARG PYTHON_VERSION=3.8 +ARG PYTHON_VERSION=3.9 # The base image to use for the final image; Prefect and its Python requirements will # be installed in this image. The default is the official Python slim image. # The following images are also available in this file: @@ -7,7 +7,7 @@ ARG PYTHON_VERSION=3.8 # Any image tag can be used, but it must have apt and pip. ARG BASE_IMAGE=python:${PYTHON_VERSION}-slim # The version used to build the Python distributable. -ARG BUILD_PYTHON_VERSION=3.8 +ARG BUILD_PYTHON_VERSION=3.9 # THe version used to build the UI distributable. ARG NODE_VERSION=16.15 # Any extra Python requirements to install @@ -20,8 +20,8 @@ WORKDIR /opt/ui RUN apt-get update && \ apt-get install --no-install-recommends -y \ - # Required for arm64 builds - chromium \ + # Required for arm64 builds + chromium \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Install a newer npm to avoid esbuild errors @@ -29,11 +29,10 @@ RUN npm install -g npm@8 # Install dependencies separately so they cache COPY ./ui/package*.json ./ -RUN npm ci install +RUN npm ci # Build static UI files COPY ./ui . -ENV PREFECT_UI_SERVE_BASE="/" RUN npm run build @@ -46,8 +45,8 @@ WORKDIR /opt/prefect RUN apt-get update && \ apt-get install --no-install-recommends -y \ - gpg \ - git=1:2.* \ + gpg \ + git=1:2.* \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Copy the repository in; requires full git history for versions to generate correctly @@ -96,17 +95,17 @@ WORKDIR /opt/prefect # - git: Required for retrieving workflows from git sources RUN apt-get update && \ apt-get install --no-install-recommends -y \ - tini=0.19.* \ - build-essential \ - git=1:2.* \ + tini=0.19.* \ + build-essential \ + git=1:2.* \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Pin the pip version -RUN python -m pip install --no-cache-dir pip==22.3.1 +RUN python -m pip install --no-cache-dir pip==23.3.1 # Install the base requirements separately so they cache -COPY requirements.txt ./ -RUN pip install --upgrade --no-cache-dir -r requirements.txt +COPY requirements-client.txt requirements.txt ./ +RUN pip install --upgrade --upgrade-strategy eager --no-cache-dir -r requirements.txt # Install prefect from the sdist COPY --from=python-builder /opt/prefect/dist ./dist diff --git a/MANIFEST.in b/MANIFEST.in index 3b243569c550..9aced7c33df8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,15 +11,17 @@ include setup.cfg include versioneer.py include requirements.txt include requirements-dev.txt +include requirements-client.txt include src/prefect/_version.py include src/prefect/py.typed include src/prefect/profiles.toml -include src/prefect/projects/recipes/*/*.yaml -include src/prefect/projects/templates/*.yaml +include src/prefect/deployments/recipes/*/*.yaml +include src/prefect/deployments/templates/*.yaml include src/prefect/.prefectignore include src/prefect/logging/logging.yml include src/prefect/cli/templates/*.yaml include src/prefect/server/collection_blocks_data.json +include src/prefect/server/api/collections_data/views/*.json # Migrations include src/prefect/server/database/alembic.ini diff --git a/Makefile b/Makefile new file mode 100644 index 000000000000..aa76b509654e --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +.PHONY: docs + +docs: + @if [ ! -x "./scripts/serve_docs" ]; then \ + echo "Error: The 'serve_docs' script is not executable."; \ + echo "Please make it executable by running:"; \ + echo " chmod +x \"./scripts/serve_docs\""; \ + echo "Then, run 'make docs' again."; \ + exit 1; \ + fi + @./scripts/serve_docs \ No newline at end of file diff --git a/README.md b/README.md index d97c03e80790..c6e0e415b361 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -
+
@@ -10,7 +10,7 @@
+
+
+
+
+
+
+
+
+
+
-
+
@@ -20,7 +20,26 @@
# Prefect
-Prefect is an orchestrator for data-intensive workflows. It's the simplest way to transform any Python function into a unit of work that can be observed and orchestrated. With Prefect, you can build resilient, dynamic workflows that react to the world around them and recover from unexpected changes. With just a few decorators, Prefect supercharges your code with features like automatic retries, distributed execution, scheduling, caching, and much more. Every activity is tracked and can be monitored with the Prefect server or Prefect Cloud dashboard.
+Prefect is an orchestration and observability platform for building, observing, and triaging workflows.
+It's the simplest way to transform Python code into an interactive workflow application.
+
+Prefect allows you to expose your workflows through an API so teams dependent on you can programmatically access your pipelines, business logic, and more.
+Prefect also allows you to standardize workflow development and deployment across your organization.
+
+With Prefect, you can build resilient, dynamic workflows that react to the world around them and recover from unexpected changes.
+With just a few decorators, Prefect supercharges your code with features like automatic retries, distributed execution, scheduling, caching, and much more.
+
+Every activity is tracked and can be monitored with a self-hosted [Prefect server](https://docs.prefect.io/latest/guides/host/) instance or managed [Prefect Cloud](https://www.prefect.io/cloud-vs-oss?utm_source=oss&utm_medium=oss&utm_campaign=oss_gh_repo&utm_term=none&utm_content=none) dashboard.
+
+## Getting started
+
+Prefect requires Python 3.9 or later. To [install Prefect](https://docs.prefect.io/getting-started/installation/), run the following command:
+
+```bash
+pip install prefect
+```
+
+Then create and run a Python file that uses Prefect `flow` and `task` decorators to orchestrate and observe your workflow - in this case, a simple script that fetches the number of GitHub stars from a repository:
```python
from prefect import flow, task
@@ -28,7 +47,7 @@ from typing import List
import httpx
-@task(retries=3)
+@task(log_prints=True)
def get_stars(repo: str):
url = f"https://api.github.com/repos/{repo}"
count = httpx.get(url).json()["stargazers_count"]
@@ -42,35 +61,56 @@ def github_stars(repos: List[str]):
# run the flow!
-github_stars(["PrefectHQ/Prefect"])
+if __name__=="__main__":
+ github_stars(["PrefectHQ/Prefect"])
```
-After running some flows, fire up the Prefect UI to see what happened:
+Fire up the Prefect UI to see what happened:
```bash
prefect server start
```
-![](/docs/img/ui/flow-run-page.png)
+![Prefect UI dashboard](https://github.com/PrefectHQ/prefect/blob/main/docs/images/cloud-overview1.png?raw=true)
+
+To run your workflow on a schedule, turn it into a deployment and schedule it to run every minute by changing the last line of your script to the following:
+
+```python
+ github_stars.serve(name="first-deployment", cron="* * * * *")
+```
+
+You now have a server running locally that is looking for scheduled deployments!
+Additionally you can run your workflow manually from the UI or CLI - and if you're using Prefect Cloud, you can even run deployments in response to [events](https://docs.prefect.io/latest/concepts/automations/).
-From here, you can continue to use Prefect interactively or [deploy your flows](https://docs.prefect.io/concepts/deployments) to remote envirnments, running on a scheduled or event-driven basis.
+## Prefect Cloud
-## Getting Started
+Stop worrying about your workflows.
+Prefect Cloud allows you to centrally deploy, monitor, and manage the data workflows you support. With managed orchestration, automations, and webhooks, all backed by enterprise-class security, build production-ready code quickly and reliably.
-Prefect requires Python 3.7 or later. To [install Prefect](https://docs.prefect.io/getting-started/installation/), run the following command in a shell or terminal session:
+Read more about Prefect Cloud [here](https://www.prefect.io/cloud-vs-oss?utm_source=oss&utm_medium=oss&utm_campaign=oss_gh_repo&utm_term=none&utm_content=none) or sign up to [try it for yourself](https://app.prefect.cloud?utm_source=oss&utm_medium=oss&utm_campaign=oss_gh_repo&utm_term=none&utm_content=none).
-```bash
-pip install prefect
-```
+![Prefect Automations](https://github.com/PrefectHQ/prefect/blob/main/docs/images/automations-1.png?raw=true)
+![Prefect Automations](https://github.com/PrefectHQ/prefect/blob/main/docs/images/automations-2.png?raw=true)
+![Prefect Automations](https://github.com/PrefectHQ/prefect/blob/main/docs/images/automations-4.png?raw=true)
+
+
+## prefect-client
+
+If your use case is geared towards communicating with Prefect Cloud or a remote Prefect server, check out our
+[prefect-client](https://pypi.org/project/prefect-client/). It was designed to be a lighter-weight option for accessing
+client-side functionality in the Prefect SDK and is ideal for use in ephemeral execution environments.
+
+## Next steps
-Start by then exploring the [core concepts of Prefect workflows](https://docs.prefect.io/concepts/), then follow one of our [friendly tutorials](https://docs.prefect.io/tutorials/first-steps) to learn by example.
+There's lots more you can do to orchestrate and observe your workflows with Prefect!
+Start with our [friendly tutorial](https://docs.prefect.io/tutorials) or explore the [core concepts of Prefect workflows](https://docs.prefect.io/concepts/).
## Join the community
-Prefect is made possible by the fastest growing community of thousands of friendly data engineers. Join us in building a new kind of workflow system. The [Prefect Slack community](https://prefect.io/slack) is a fantastic place to learn more abou Prefect, ask questions, or get help with workflow design. The [Prefect Discourse](https://discourse.prefect.io/) is an community-driven knowledge base to find answers to your Prefect-related questions. All community forums, including code contributions, issue discussions, and slack messages are subject to our [Code of Conduct](https://discourse.prefect.io/faq).
+Prefect is made possible by the fastest growing community of thousands of friendly data engineers. Join us in building a new kind of workflow system. The [Prefect Slack community](https://prefect.io/slack) is a fantastic place to learn more about Prefect, ask questions, or get help with workflow design. All community forums, including code contributions, issue discussions, and slack messages are subject to our [Code of Conduct](https://discourse.prefect.io/faq).
## Contribute
See our [documentation on contributing to Prefect](https://docs.prefect.io/contributing/overview/).
-Thanks for being part of the mission to build a new kind of workflow system and, of course, **happy engineering!**
+Thanks for being part of the mission to build a new kind of workflow system and, of course, **happy engineering!**
\ No newline at end of file
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index de5c7038e92a..82f2d9b9a3e1 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -1,87 +1,4870 @@
# Prefect Release Notes
+## Release 3.0.0rc1
+
+We're excited to announce the release candidate of Prefect 3.0. It's the most flexible, powerful, fastest version of Prefect yet. Prefect 3.0 includes several exciting new features. Install it by running `pip install prefect==3.0.0rc1` and check out the docs [here](https://docs-3.prefect.io/3.0rc/getting-started/index).
+
+### Run tasks independently of flows
+
+You can now run and serve tasks outside of flows and inside of other tasks.
+
+```python
+from prefect import task
+
+@task
+def my_background_task(name: str):
+ print(f"Hello, {name}!")
+
+if __name__ == "__main__":
+ my_background_task.delay("ford")
+```
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13695
+- https://github.com/PrefectHQ/prefect/pull/13692
+- https://github.com/PrefectHQ/prefect/pull/13681
+- https://github.com/PrefectHQ/prefect/pull/13662
+- https://github.com/PrefectHQ/prefect/pull/13653
+- https://github.com/PrefectHQ/prefect/pull/13643
+- https://github.com/PrefectHQ/prefect/pull/13589
+- https://github.com/PrefectHQ/prefect/pull/13684
+- https://github.com/PrefectHQ/prefect/pull/13676
+- https://github.com/PrefectHQ/prefect/pull/13276
+- https://github.com/PrefectHQ/prefect/pull/13611
+- https://github.com/PrefectHQ/prefect/pull/13547
+- https://github.com/PrefectHQ/prefect/pull/13706
+
+### Transactional semantics
+
+Use rollback and commit hooks to facilitate idempotent python code.
+
+```python
+from prefect import flow, task
+from prefect.transactions import transaction
+@task
+def first_task():
+ print('first')
+
+@first_task.on_rollback
+def roll(txn):
+ print('rolling back')
+
+@task
+def second_task():
+ raise RuntimeError("oopsie")
+
+@flow
+def txn_flow():
+ with transaction():
+ first_task()
+ second_task()
+if __name__ == "__main__":
+ txn_flow()
+```
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13559
+- https://github.com/PrefectHQ/prefect/pull/13534
+- https://github.com/PrefectHQ/prefect/pull/13535
+- https://github.com/PrefectHQ/prefect/pull/13480
+- https://github.com/PrefectHQ/prefect/pull/13452
+- https://github.com/PrefectHQ/prefect/pull/13450
+- https://github.com/PrefectHQ/prefect/pull/13484
+- https://github.com/PrefectHQ/prefect/pull/13454
+- https://github.com/PrefectHQ/prefect/pull/13477
+- https://github.com/PrefectHQ/prefect/pull/13431
+- https://github.com/PrefectHQ/prefect/pull/13264
+- https://github.com/PrefectHQ/prefect/pull/13337
+- https://github.com/PrefectHQ/prefect/pull/13456
+- https://github.com/PrefectHQ/prefect/pull/13572
+- https://github.com/PrefectHQ/prefect/pull/13582
+- https://github.com/PrefectHQ/prefect/pull/13627
+- https://github.com/PrefectHQ/prefect/pull/13568
+- https://github.com/PrefectHQ/prefect/pull/13438
+- https://github.com/PrefectHQ/prefect/pull/13573
+- https://github.com/PrefectHQ/prefect/pull/13578
+- https://github.com/PrefectHQ/prefect/pull/13414
+
+### Open source Events and Automations
+Trigger actions, such as sending notifications, pausing schedules, starting flow runs and more in response to Prefect events.
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13293
+- https://github.com/PrefectHQ/prefect/pull/13521
+- https://github.com/PrefectHQ/prefect/pull/13335
+
+### More flexible variables and new artifact types
+Variables can now be any JSON compatible type including dicts, lists, and integers. Progress and Image artifacts make it easy to add visual annotations to your flow run graph.
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13500
+- https://github.com/PrefectHQ/prefect/pull/13520
+- https://github.com/PrefectHQ/prefect/pull/13469
+- https://github.com/PrefectHQ/prefect/pull/13641
+- https://github.com/PrefectHQ/prefect/pull/13605
+
+### Faster and richer CLI
+
+Improved CLI speed and several added commands and conveniences.
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13292
+- https://github.com/PrefectHQ/prefect/pull/13596
+- https://github.com/PrefectHQ/prefect/pull/13606
+- https://github.com/PrefectHQ/prefect/pull/13533
+
+### Updated navigation, styling, and interaction design
+The new Runs page displays both flow and task run information, and an improved sidebar and switcher makes navigating Prefect simpler than ever.
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13395
+- https://github.com/PrefectHQ/prefect/pull/13280
+- https://github.com/PrefectHQ/prefect/pull/13696
+- https://github.com/PrefectHQ/prefect/pull/13668
+- https://github.com/PrefectHQ/prefect/pull/13670
+- https://github.com/PrefectHQ/prefect/pull/13723
+
+
+
+### Enhancements
+- Create artifact for unsuccessful dbt task runs — https://github.com/PrefectHQ/prefect/pull/13348
+- Add filter on `task_run.expected_start_time` — https://github.com/PrefectHQ/prefect/pull/13491
+- Add utilities to serialize context to a dictionary and hydrate context from a dictionary — https://github.com/PrefectHQ/prefect/pull/13529
+- Add API endpoints for deployment count and next flow run — https://github.com/PrefectHQ/prefect/pull/13544
+- Allow flow parameter schema generation when dependencies are missing — https://github.com/PrefectHQ/prefect/pull/13315
+- Change the default value for `enforce_parameter_schema` from `False` to `True` — https://github.com/PrefectHQ/prefect/pull/13594
+- Migrate schemas to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13574
+- Removes block auto-instrumentation — https://github.com/PrefectHQ/prefect/pull/13407
+- Migrate all uses of the banned characters validation to a self-validator — https://github.com/PrefectHQ/prefect/pull/13370
+- Ignore and warn on unrecognized settings - https://github.com/PrefectHQ/prefect/pull/13624
+
+### Fixes
+- Remove unnecessary flow run infrastructure override access checks — https://github.com/PrefectHQ/prefect/pull/13401
+- Enforce False case when flow run id is null — https://github.com/PrefectHQ/prefect/pull/13464
+- Fix workspace variable hydration to allow for JSON data — https://github.com/PrefectHQ/prefect/pull/13548
+- Remove unused settings/experimental work pool flags: `PREFECT_EXPERIMENTAL_ENABLE_WORK_POOLS` and `PREFECT_EXPERIMENTAL_WARN_WORK_POOLS` — https://github.com/PrefectHQ/prefect/pull/13144
+- Pin `pydantic>=2.7` for `Secret` — https://github.com/PrefectHQ/prefect/pull/13613
+- Skip on cancellation hooks if runner can't load flow — https://github.com/PrefectHQ/prefect/pull/13660
+- Refactor lazy imports to avoid accidental eager imports — https://github.com/PrefectHQ/prefect/pull/13296
+- Allow block registration to use client schemas for server model creation — https://github.com/PrefectHQ/prefect/pull/13602
+- Replace our customized `Duration` types with plain `timedelta`s — https://github.com/PrefectHQ/prefect/pull/13603
+
+### Experimental
+- Add `prefect.yaml` and cli support for new schedule fields — https://github.com/PrefectHQ/prefect/pull/13318
+
+### Documentation
+- Transition documentation hosting from Netlify to Mintlify — https://github.com/PrefectHQ/prefect/pull/13634
+- Add Python 3.12 to list of Docker images — https://github.com/PrefectHQ/prefect/pull/13321
+- Update `index.md` — https://github.com/PrefectHQ/prefect/pull/13353
+- Improve tutorial section — https://github.com/PrefectHQ/prefect/pull/13297
+- Fix jinja template in automations doc — https://github.com/PrefectHQ/prefect/pull/13422
+- Update development section docs — https://github.com/PrefectHQ/prefect/pull/13247
+- Update Ray integration docs — https://github.com/PrefectHQ/prefect/pull/13467
+- Update Variables docs to include JSON types — https://github.com/PrefectHQ/prefect/pull/13493
+- Update quickstart guide for usability — https://github.com/PrefectHQ/prefect/pull/13562
+- Remove `deployments-block-based` concept page and refs for 3.0 — https://github.com/PrefectHQ/prefect/pull/13626
+- Remove `infrastructure` concept page and refs for 3.0 — https://github.com/PrefectHQ/prefect/pull/13629
+- Update docs image paths and remove outdated images — https://github.com/PrefectHQ/prefect/pull/13666
+- Remove references to `prefect.software` from docs — https://github.com/PrefectHQ/prefect/pull/13382
+- Update `host.md` — https://github.com/PrefectHQ/prefect/pull/13351
+- Simplify rate limits page — https://github.com/PrefectHQ/prefect/pull/13689
+- Removing references to deprecated block types and add disclaimer — https://github.com/PrefectHQ/prefect/pull/13651
+- Update guides — https://github.com/PrefectHQ/prefect/pull/13253
+- Remove `storage` concept page and refs - https://github.com/PrefectHQ/prefect/pull/13630
+
+### Integrations
+- Migrate `prefect-dbt` to pydantic v2 - https://github.com/PrefectHQ/prefect/pull/13718
+- Migrate `prefect-email` to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13654
+- Migrate `prefect-slack` to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13673
+- Migrate `prefect-shell` to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13675
+- Migrate `prefect-gcp` to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13650
+- Migrate `prefect-github` to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13655
+- Migrate `prefect-gitlab` to pydantic v2 — https://github.com/PrefectHQ/prefect/pull/13656
+- Migrate `prefect-docker` to pydantic v2 - https://github.com/PrefectHQ/prefect/pull/13697
+- Migrate `prefect-sqlalchemy` to pydantic v2 - https://github.com/PrefectHQ/prefect/pull/13700
+- Add `PrefectDistributedClient` to `prefect-dask` — https://github.com/PrefectHQ/prefect/pull/13537
+- Update `RayTaskRunner` for compatibility with new engine — https://github.com/PrefectHQ/prefect/pull/13575
+- Update `DaskTaskRunner` for compatibility with the updated engine — https://github.com/PrefectHQ/prefect/pull/13555
+- prefect-dbt artifact consolidation and markdown fixes — https://github.com/PrefectHQ/prefect/pull/13379
+- prefect-dbt - Cause unsuccessful dbt tasks to fail — https://github.com/PrefectHQ/prefect/pull/13405
+- DBT Tasks extra_command_args Fix — https://github.com/PrefectHQ/prefect/pull/13308
+- Update dbt-core dependency — https://github.com/PrefectHQ/prefect/pull/13394
+
+### Breaking Changes
+- Remove `prefect deployment build` CLI from `main` — https://github.com/PrefectHQ/prefect/pull/13366
+- Remove `prefect agent` CLI from `main` — https://github.com/PrefectHQ/prefect/pull/13365
+- Remove `prefect deployment apply` CLI from `main` — https://github.com/PrefectHQ/prefect/pull/13367
+- Remove `PrefectAgent` class — https://github.com/PrefectHQ/prefect/pull/13374
+- Remove `prefect.software` — https://github.com/PrefectHQ/prefect/pull/13375
+- Remove `deployments` module — https://github.com/PrefectHQ/prefect/pull/13373
+- Remove `EcsTask` from `main` — https://github.com/PrefectHQ/prefect/pull/13417
+- Remove `AzureContainerInstanceJob` from `main` — https://github.com/PrefectHQ/prefect/pull/13418
+- Remove `VertexAICustomTrainingJob` from `main` — https://github.com/PrefectHQ/prefect/pull/13419
+- Remove `CloudRunJob` from `main` — https://github.com/PrefectHQ/prefect/pull/13420
+- Remove infrastructure blocks from `main` — https://github.com/PrefectHQ/prefect/pull/13424
+- Remove `Infrastructure`, `BlockWorker` from `main` — https://github.com/PrefectHQ/prefect/pull/13430
+- Remove deprecated storage blocks from `main` — https://github.com/PrefectHQ/prefect/pull/13410
+- Remove `prefect-agent` as a possible work pool type — https://github.com/PrefectHQ/prefect/pull/13444
+- Remove old engine — https://github.com/PrefectHQ/prefect/pull/13542
+- Remove Python 3.8 support — https://github.com/PrefectHQ/prefect/pull/13331
+- Remove `deprecated` module and its references — https://github.com/PrefectHQ/prefect/pull/13345
+- Remove old task runners and futures modules — https://github.com/PrefectHQ/prefect/pull/13593
+- Remove `is_state` — https://github.com/PrefectHQ/prefect/pull/13569
+- Remove deprecated options from `prefect work-queue` and refs to agents - https://github.com/PrefectHQ/prefect/pull/13638
+
+### Contributors
+- @bsignoret
+* @jaraics made their first contribution in https://github.com/PrefectHQ/prefect/pull/13144
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.19.0...3.0rc1
+
+## Release 2.19.3
+
+### New method for generating parameter schemas without dependencies
+
+`prefect deploy` now works even when dependencies are missing from the current environment. This can speed up deployment via CI by removing the need to install dependencies before deploying your flows.
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13620
+- https://github.com/PrefectHQ/prefect/pull/13315
+
+### Enhancements
+- Provide URL in CLI output upon work pool creation — https://github.com/PrefectHQ/prefect/pull/13597
+
+### Fixes
+- Ensure graceful cancellation of flow runs corresponding to deleted deployments — https://github.com/PrefectHQ/prefect/pull/13669
+
+### Integrations
+- Add loading state to concurrency limits table in the Prefect UI — https://github.com/PrefectHQ/prefect-ui-library/pull/2483
+- Remove old schema properties from deployments in the Prefect UI — https://github.com/PrefectHQ/prefect-ui-library/pull/2482
+- Add handling for multi-word dbt CLI commands — https://github.com/PrefectHQ/prefect/pull/13616
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.19.2...2.19.3
+
+
+## Release 2.19.0
+
+### Support for major infrastructure and distributed task integrations
+As `prefect-dask` and other integrations have been added to the `prefect` codebase, this release adds these integrations as `extra` requirements of the `prefect` package, making it easier to install support for everything in your Prefect stack.
+
+```bash
+pip install prefect[dask]
+```
+
+We loved this community contribution so much, we did it for all our first-party integrations.
+
+```bash
+pip install prefect[aws,kubernetes,dask,dbt,sqlalchemy,slack]
+```
+
+You can see the full list of Prefect's `extra` requirements in [our `setup.py`](https://github.com/PrefectHQ/prefect/blob/main/setup.py#L43).
+
+See the following pull requests for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13289
+- https://github.com/PrefectHQ/prefect/pull/13310
+- https://github.com/PrefectHQ/prefect/pull/13320
+
+### Support for timeout seconds in global concurrency context manager
+You may want to fail immediately if a global concurrency slot is unavailable. Rather than block and wait, you can now specify a `timeout_seconds` argument in the global concurrency context manager and catch a `TimeoutError` if a slot is not available within the specified time.
+
+```python
+@flow
+def fail_immediately_flow():
+ try:
+ with concurrency("there-can-be-only-one", occupy=1, timeout_seconds=0.1):
+ do_something_resource_intensive()
+ except TimeoutError:
+ return Cancelled(message="Another flow run is already running")
+```
+
+See the following pull request for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13262
+
+### Manage global concurrency limits via the CLI
+Global concurrency limits let you control how many operations can run simultaneously-- now you can create, read, edit, and delete global concurrency limits via the Prefect CLI!
+
+To create a new concurrency limit, use the `prefect gcl create` command. You must specify a `--limit` argument, and can optionally specify a `--slot-decay-per-second` and `--disable` argument.
+
+```bash
+prefect gcl create my-concurrency-limit --limit 5 --slot-decay-per-second 1.0
+```
+
+You can inspect the details of a concurrency limit using the `prefect gcl inspect` command:
+
+```bash
+prefect gcl inspect my-concurrency-limit
+```
+
+To update a concurrency limit, use the `prefect gcl update` command. You can update the `--limit`, `--slot-decay-per-second`, `--enable`, and `--disable` arguments:
+
+```bash
+prefect gcl update my-concurrency-limit --limit 10
+```
+
+See all available commands and options by running `prefect gcl --help` or read our [docs](/docs/guides/global-concurrency-limits.md#managing-global-concurrency-limits-and-rate-limits).
+
+For implementation details, see the following pull requests:
+- https://github.com/PrefectHQ/prefect/pull/13194
+- https://github.com/PrefectHQ/prefect/pull/13196
+- https://github.com/PrefectHQ/prefect/pull/13214
+- https://github.com/PrefectHQ/prefect/pull/13218
+- https://github.com/PrefectHQ/prefect/pull/13233
+- https://github.com/PrefectHQ/prefect/pull/13238
+
+### Enhancements
+- Remove registry conflict warning — https://github.com/PrefectHQ/prefect/pull/13155
+- Remove top-level Artifacts tab from Prefect UI:
+ - https://github.com/PrefectHQ/prefect/pull/13226
+ - https://github.com/PrefectHQ/prefect/pull/13261
+
+### Fixes
+- Fix work pool base job template generation for `ECSTask` block — https://github.com/PrefectHQ/prefect/pull/13256
+- Fix selecting correct files when using ignore file in `GcsBucket`'s `put_directory` — https://github.com/PrefectHQ/prefect/pull/13290
+- Add `Resuming` flow runs to `BypassCancellingFlowRunsWithNoInfra` orchestration policy — https://github.com/PrefectHQ/prefect/pull/13299
+- Fix `apprise 1.8.0` imports — https://github.com/PrefectHQ/prefect/pull/13311
+- Remove `dataclass` from custom constrained types - https://github.com/PrefectHQ/prefect/pull/13257
+
+### Experimental
+#### Engine
+- Add crash detection for flow runs — https://github.com/PrefectHQ/prefect/pull/13266
+- Consolidate run creation logic on Task — https://github.com/PrefectHQ/prefect/pull/13271
+- Skip timeout context if not needed — https://github.com/PrefectHQ/prefect/pull/13306
+- Add parent task tracking — https://github.com/PrefectHQ/prefect/pull/12915
+- Syncify task engine — https://github.com/PrefectHQ/prefect/pull/13234
+- Syncify flow engine — https://github.com/PrefectHQ/prefect/pull/13246
+- Use Prefect-specific `TestClient` for sync calls — https://github.com/PrefectHQ/prefect/pull/13265
+- Add new sync compatibility setting — https://github.com/PrefectHQ/prefect/pull/13224
+
+#### Deployment Schedule Behavior
+- Add new fields to `DeploymentSchedule` schemas — https://github.com/PrefectHQ/prefect/pull/13204
+- Allow both `active` and `schedule` parameters in `update_deployment_schedule` method — https://github.com/PrefectHQ/prefect/pull/13259
+- Update JSON schema validation for job varariables — https://github.com/PrefectHQ/prefect/pull/13182
+
+### Documentation
+- Update block concept page to reflect product updates — https://github.com/PrefectHQ/prefect/pull/13193
+- Update example repo links to `prefecthq` repos — https://github.com/PrefectHQ/prefect/pull/13258
+- Update storage guide — https://github.com/PrefectHQ/prefect/pull/13294
+- Update integration libraries — https://github.com/PrefectHQ/prefect/pull/13277
+- Update `Hosting a Prefect server instance` page — https://github.com/PrefectHQ/prefect/pull/13225
+- Simplify `prefect-aws` and `prefect-dbt` docs index pages — https://github.com/PrefectHQ/prefect/pull/13232
+- Expand discussion of resolution order for cloud-provider service auth — https://github.com/PrefectHQ/prefect/pull/13239
+- Fix repo url typo in storage guide — https://github.com/PrefectHQ/prefect/pull/13304
+
+### Integrations
+- Add pre-built Prefect DBT tasks — https://github.com/PrefectHQ/prefect/pull/12964
+
+### Contributors
+- @Andrew-S-Rosen
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.18.3...2.19.0
+
+## Release 2.18.3
+
+### Experimental
+#### Engine
+- Wire up new engine to deployment runs — https://github.com/PrefectHQ/prefect/pull/12914
+
+### Fixes
+- Fix parameters becoming unresponsive and disappearing in Prefect UI — https://github.com/PrefectHQ/prefect-ui-library/pull/2355
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.18.2...2.18.3
+
+## Release 2.18.2
+
+### Providing a deployment name to `flow.serve` is now optional
+
+When running `flow.serve`, you can now omit the deployment name. If you do not provide a deployment name, the deployment name will default to the name of the flow. This change makes it easier to run flows without needing to specify a deployment name each time:
+
+```python
+@flow
+def etl_flow():
+ pass
+
+if __name__ == "__main__":
+ etl_flow.serve()
+```
+results in:
+```bash
+Your flow 'etl-flow' is being served and polling for scheduled runs!
+
+To trigger a run for this flow, use the following command:
+
+ $ prefect deployment run 'etl-flow/etl-flow'
+```
+
+See the following PR for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/13069
+
+### Enhancements
+- Add `PREFECT_SERVER_CSRF_PROTECTION_ENABLED` setting to UI settings — https://github.com/PrefectHQ/prefect/pull/13168
+- Allow case-insensitive state and state type handling when listing flow runs via CLI — https://github.com/PrefectHQ/prefect/pull/13152
+
+### Fixes
+- Fix deployment parameter defaults on Deployments page in the UI - https://github.com/PrefectHQ/prefect-ui-library/pull/2344
+- Sync value between form and JSON when entering flow parameters on the Deployments page in the UI - https://github.com/PrefectHQ/prefect-ui-library/pull/2342
+- Revert console setup changes to fix interactivity — https://github.com/PrefectHQ/prefect/pull/13145
+- Warn when work queues paused when starting a worker or agent — https://github.com/PrefectHQ/prefect/pull/13159
+- Standardize work pool type as `Process` — https://github.com/PrefectHQ/prefect/pull/13176
+- Raise a clearer error when deleting and inspecting blocks — https://github.com/PrefectHQ/prefect/pull/13136
+- Fix csrf race condition that caused some pages to not render content when refreshing — https://github.com/PrefectHQ/prefect/pull/13172
+
+### Experimental
+#### Events and Automations
+- Add work queue status events — https://github.com/PrefectHQ/prefect/pull/12900
+- Add work pool status events — https://github.com/PrefectHQ/prefect/pull/13158
+- Add support for negative label values in `ResourceSpecification` and filters — https://github.com/PrefectHQ/prefect/pull/13192
+- Add automations SDK methods — https://github.com/PrefectHQ/prefect/pull/12830
+- Add a retention policy for events — https://github.com/PrefectHQ/prefect/pull/13160
+- Allow streaming OSS events via `prefect event stream` — https://github.com/PrefectHQ/prefect/pull/13161
+- Update `prefect automation inspect` to handle automations with same name — https://github.com/PrefectHQ/prefect/pull/12904
+- Update `automation pause` and `automation resume` to handle automations with same name — https://github.com/PrefectHQ/prefect/pull/13131
+- Rename `prefect.work-pool.not_ready` to `prefect.work-pool.not-ready` — https://github.com/PrefectHQ/prefect/pull/13202
+- Correct an issue that would cause the `work-queue.ready` event to overfire — https://github.com/PrefectHQ/prefect/pull/13117
+
+#### Engine
+- Add dedicated synchronous function handling — https://github.com/PrefectHQ/prefect/pull/12889
+- Add async `task.submit` support with new task engine — https://github.com/PrefectHQ/prefect/pull/13153
+- Fix subflow handling in new engine — https://github.com/PrefectHQ/prefect/pull/12913
+- Handle *args / **kwargs correctly — https://github.com/PrefectHQ/prefect/pull/13142
+
+#### Deployment schedule behavior
+- Add columns to ORM `DeploymentSchedule` and add migrations — https://github.com/PrefectHQ/prefect/pull/13186
+- Add server default for non-nullable deployment schedule column - https://github.com/PrefectHQ/prefect/pull/13206
+
+### Integrations
+- Add `keep_container_group` to ACI worker — https://github.com/PrefectHQ/prefect/pull/13143
+- Improve Vertex AI worker performance — https://github.com/PrefectHQ/prefect/pull/13139
+- Migrate `prefect-ray` to core — https://github.com/PrefectHQ/prefect/pull/12869
+- Log full output of databricks job — https://github.com/PrefectHQ/prefect/pull/13151
+- Update Snowflake Connector example in UI — https://github.com/PrefectHQ/prefect/pull/12903
+- Fix pydantic v1 prefect-databricks — https://github.com/PrefectHQ/prefect/pull/13166
+- Fix inclusion of commas in tag scrubbing — https://github.com/PrefectHQ/prefect/pull/13190
+- Handle empty `service_account_info` for cached Vertex client — https://github.com/PrefectHQ/prefect/pull/13175
+- Add `dlt-prefect` recipe — https://github.com/PrefectHQ/prefect/pull/13203
+
+### Documentation
+- Add third-party secrets guide — https://github.com/PrefectHQ/prefect/pull/13173
+- Update documentation on nested / autonomous tasks — https://github.com/PrefectHQ/prefect/pull/13154
+- Update Prefect Snowflake docs — https://github.com/PrefectHQ/prefect/pull/13171
+- Update prefect-dbt index page — https://github.com/PrefectHQ/prefect/pull/13187
+- Fix `az acr create` command in ACI worker guide — https://github.com/PrefectHQ/prefect/pull/12909
+- Update prefect-dbt index page - https://github.com/PrefectHQ/prefect/pull/13187
+
+### Contributors
+- @h2oa made their first contribution in https://github.com/PrefectHQ/prefect/pull/13157
+- @ConstantinoSchillebeeckx
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.18.1...2.18.2
+
+## Release 2.18.1
+
+### Fixes
+- Fix improper context access for nested async task outside of flow — https://github.com/PrefectHQ/prefect/pull/12810
+- Fix using default interval schedule in `prefect deploy` — https://github.com/PrefectHQ/prefect/pull/12833
+- Handle case in `validationUpdate` schema where definitions are falsy — https://github.com/PrefectHQ/prefect/pull/12880
+- Allow `prefect cloud login` to override current workspace — https://github.com/PrefectHQ/prefect/pull/12867
+- Remove extra quotes in `prefect deployment run --watch` — https://github.com/PrefectHQ/prefect/pull/12894
+
+### Experimental
+
+#### Events and Automations
+- Support filtering by automation name:
+ - https://github.com/PrefectHQ/prefect/pull/12850
+ - https://github.com/PrefectHQ/prefect/pull/12884
+ - https://github.com/PrefectHQ/prefect/pull/12887
+- Add support for using the "normal" Trigger classes for `flow.serve` and `.deploy` — https://github.com/PrefectHQ/prefect/pull/12789
+- Add an account-level event subscriber — https://github.com/PrefectHQ/prefect/pull/12808
+- Emit flow run state change events — https://github.com/PrefectHQ/prefect/pull/12825
+- Emit deployment status persistence and events — https://github.com/PrefectHQ/prefect/pull/12853
+- Enable event streaming from `PrefectCloudEventSubscriber` via CLI — https://github.com/PrefectHQ/prefect/pull/12796
+- Update the `prefect automation delete` CLI — https://github.com/PrefectHQ/prefect/pull/12876
+
+#### Engine
+- Add new experimental engine for tasks and flows with improved readability and extensibility — https://github.com/PrefectHQ/prefect/pull/12856
+
+### Documentation
+- Improve installation instructions — https://github.com/PrefectHQ/prefect/pull/12783
+- Improve quickstart — https://github.com/PrefectHQ/prefect/pull/12798
+- Migrate `prefect-azure` docs to Integrations section of the Prefect docs — https://github.com/PrefectHQ/prefect/pull/12794
+- Update storage guide credentials blocks — https://github.com/PrefectHQ/prefect/pull/12819
+- Remove `server` import recommendations — https://github.com/PrefectHQ/prefect/pull/12823
+- Remove link to removed API page — https://github.com/PrefectHQ/prefect/pull/12824
+- Add Azure Container Instances worker guide — https://github.com/PrefectHQ/prefect/pull/12846
+- Improve wording on integrations index page — https://github.com/PrefectHQ/prefect/pull/12852
+
+#### Prefect UI Library
+- Add `FormattedDate` component to display accessible, long-form timestamps consistently
+- Update modal buttons and add auto-close to the parameters and job variable modals — https://github.com/PrefectHQ/prefect-ui-library/pull/2320
+- Add flow run list information density — https://github.com/PrefectHQ/prefect-ui-library/pull/2321
+- Fix "Run a deployment" action not populating the default parameters from the deployment — https://github.com/PrefectHQ/prefect-ui-library/pull/2322
+- Fix schema form properties with no default value from defaulting to `null` (`None`) — https://github.com/PrefectHQ/prefect-ui-library/pull/2323
+- Update date-fns and date-fns-tz — https://github.com/PrefectHQ/prefect-ui-library/pull/2319
+- Use correct icon colors for non-destructive actions in the UI — https://github.com/PrefectHQ/prefect-ui-library/pull/2328
+
+### Integrations
+#### Prefect CGP
+- Remove API ref to nonexistent Google Cloud Run V2 page — https://github.com/PrefectHQ/prefect-gcp/pull/260
+- Fix VPC access for Cloud v2 worker — https://github.com/PrefectHQ/prefect-gcp/pull/266
+- Handle case where `vpc` isn't in job template — https://github.com/PrefectHQ/prefect-gcp/pull/267
+
+## New Contributors
+* @keizobabybear made their first contribution in https://github.com/PrefectHQ/prefect/pull/12852
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.18.0...2.18.1
+
+## Release 2.18.0
+
+### Breaking Changes
+- Deployment configuration update: The `prefect deploy` command now only supports the `prefect.yaml` file. The `deployment.yaml` file is no longer supported
+following its deprecation last June. Users should update their deployment configurations to use `prefect.yaml` instead. Running `prefect deploy` on a version prior to 2.18.0 will migrate your `deployment.yaml` file to a `prefect.yaml` file. - https://github.com/PrefectHQ/prefect/pull/12731
+- `prefect deploy` options update: The `-f/--flow` option has been removed from `prefect deploy` following its deprecation last June. Please deploy
+using the flow entrypoint instead. - https://github.com/PrefectHQ/prefect/pull/12732
+- `prefect project` removal: The `projects` command group has been removed following its deprecation last June. For instance, instead of using `prefect project init`, use `prefect init` instead. — https://github.com/PrefectHQ/prefect/pull/12737
+- `--ci` option removal: The `--ci` option in `prefect deploy` has been removed to unify the deployment experience across different environments. This removal follows its scheduled deprecation. Please use the `--no-prompt` option instead, e.g. `prefect --no-prompt deploy`. — https://github.com/PrefectHQ/prefect/pull/12740
+
+### Enhancements
+- Improve account selection in `prefect cloud login` and `workspace set` — https://github.com/PrefectHQ/prefect/pull/12717
+
+### Fixes
+- Raise clearer flow validation error — https://github.com/PrefectHQ/prefect/pull/12715
+- Exclude job_variables when exclude=None — https://github.com/PrefectHQ/prefect/pull/12712
+- Remove experimental flags on infrastructure overrides — https://github.com/PrefectHQ/prefect/pull/12742
+
+### Experimental
+
+#### Pydantic V2 Compatibility
+- Introduce self-validating types — https://github.com/PrefectHQ/prefect/pull/12707
+- Refactor `field_validator` and `model_validator` to map Pydantic kwargs between versions — https://github.com/PrefectHQ/prefect/pull/12676
+- Fix type-hinting for self-validating fields — https://github.com/PrefectHQ/prefect/pull/12710
+- Fix types NonNegativeDuration / PositiveDuration — https://github.com/PrefectHQ/prefect/pull/12711
+
+
+#### Events and Automations
+- Implement the `run-deployment` automation action — https://github.com/PrefectHQ/prefect/pull/12677
+- Implement the `send-notification` action — https://github.com/PrefectHQ/prefect/pull/12693
+- Make `TriggeredAction.firing` required — https://github.com/PrefectHQ/prefect/pull/12697
+- Add an Actions service — https://github.com/PrefectHQ/prefect/pull/12699
+- Implement the `call-webhook` action and adds all Action client-side schemata — https://github.com/PrefectHQ/prefect/pull/12728
+- Implement `change-flow-run-state`, `cancel-flow-run`, and `suspend-flow-run` — https://github.com/PrefectHQ/prefect/pull/12730
+- Add functions for querying and counting events — https://github.com/PrefectHQ/prefect/pull/12696
+- Implement the `pause-deployment` and `resume-deployment` actions — https://github.com/PrefectHQ/prefect/pull/12733
+- Add `/events/filter` and `/events/count-by` route trees — https://github.com/PrefectHQ/prefect/pull/12736
+- Allow for creating automations via deployments when experimental events is on — https://github.com/PrefectHQ/prefect/pull/12701
+- Add ability to stream out events via websocket — https://github.com/PrefectHQ/prefect/pull/12744
+- Implement the `pause-automation` and `resume-automation` actions — https://github.com/PrefectHQ/prefect/pull/12738
+- Add automations CLI — https://github.com/PrefectHQ/prefect/pull/12754
+- Rename `prefect-cloud.*` events and labels to `prefect.*` — https://github.com/PrefectHQ/prefect/pull/12755
+- Add ability to emit events to an ephemeral Prefect server — https://github.com/PrefectHQ/prefect/pull/12762
+- Disable `events` and `automations` API routes when experimental events setting is not enabled — https://github.com/PrefectHQ/prefect/pull/12777
+- Add compatibility tests for client and server triggers and actions — https://github.com/PrefectHQ/prefect/pull/12778
+- Disable the automations integration flows for Prefect Cloud — https://github.com/PrefectHQ/prefect/pull/12784
+- Add pause and resume the work pool and work queue actions — https://github.com/PrefectHQ/prefect/pull/12735
+- Add helper functions for creating an events client or subscriber — https://github.com/PrefectHQ/prefect/pull/12759
+- Add default posture to `EventTrigger` schema — https://github.com/PrefectHQ/prefect/pull/12764
+ - Fix writing events for SQLite + SQLAlchemy<2 — https://github.com/PrefectHQ/prefect/pull/12679
+
+### Documentation
+- Update `prefect.yaml` example in work pools concepts page — https://github.com/PrefectHQ/prefect/pull/12695
+- Fix typo in Quickstart — https://github.com/PrefectHQ/prefect/pull/12729
+- Simplify quickstart — https://github.com/PrefectHQ/prefect/pull/12725
+- Add `.serve`, `.deploy`, and composite trigger examples to deployment triggers docs — https://github.com/PrefectHQ/prefect/pull/12743
+- Update automations images — https://github.com/PrefectHQ/prefect/pull/12752
+- Simplify tutorial — https://github.com/PrefectHQ/prefect/pull/12765
+- Remove disclaimer for Python 3.12 experimental support — https://github.com/PrefectHQ/prefect/pull/12771
+- Clarify deployment trigger examples — https://github.com/PrefectHQ/prefect/pull/12782
+- Remove Prefect-managed integration libraries to be archived from the integrations catalog — https://github.com/PrefectHQ/prefect/pull/12781
+- Fix broken link to push work pool guide — https://github.com/PrefectHQ/prefect/pull/12748
+- Fix minor restructure to improve legibility of work pools tutorial — https://github.com/PrefectHQ/prefect/pull/12747
+- Fix `typing` import and typos in tasks tutorial — https://github.com/PrefectHQ/prefect/pull/12746
+- Simplify installation — https://github.com/PrefectHQ/prefect/pull/12772
+- Fix import syntax in `variables.Variable` example — https://github.com/PrefectHQ/prefect/pull/12727
+- Fix typo in How-to Guide document — https://github.com/PrefectHQ/prefect/pull/12761
+
+
+## New Contributors
+* @hboehmer-IW made their first contribution in https://github.com/PrefectHQ/prefect/pull/12721
+* @avriiil made their first contribution in https://github.com/PrefectHQ/prefect/pull/12748
+* @takashimakazuki made their first contribution in https://github.com/PrefectHQ/prefect/pull/12761
+
+### Integrations
+- Add support for a capacity provider — https://github.com/PrefectHQ/prefect-aws/pull/407
+- Improve error handling for task creation — https://github.com/PrefectHQ/prefect-aws/pull/406
+
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.17.1...2.18.0
+
+## Release 2.17.1
+
+### Fixes
+- Fix events storage import — https://github.com/PrefectHQ/prefect/pull/12681
+- Remove `opentelemetry` import — https://github.com/PrefectHQ/prefect/pull/12684
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.17.0...2.17.1
+
+## Release 2.17.0
+
+### Manage Prefect variables via the Python SDK
+
+Prefect variables are useful for storing and reusing data and configuration between and across workflows; and previously you could only create and update variables via the Prefect UI. With this release, you can now get and set Prefect variables directly in your Python code with the new `Variable.set` and `Variable.get` methods!
+
+For an example of reading and writing variable values in Python see the following example:
+
+```python
+from prefect.variables import Variable
+
+# set a variable
+variable = Variable.set(name="the_answer", value="42")
+
+# get a variable
+answer = Variable.get('the_answer')
+print(answer.value)
+# 42
+
+# get a variable with a default value
+answer = Variable.get('not_the_answer', default='42')
+print(answer.value)
+# 42
+
+# update a variable
+answer = Variable.set(name="the_answer", value="43", overwrite=True)
+print(answer.value)
+#43
+```
+
+Refer to the [docs](https://docs.prefect.io/latest/guides/variables/#accessing-variables) for more information and see the PR for implementation details: https://github.com/PrefectHQ/prefect/pull/12596
+
+### Enhancements
+- Allow flows inside tasks
+ — https://github.com/PrefectHQ/prefect/pull/12559
+ — https://github.com/PrefectHQ/prefect/pull/12607
+- Add `User-Agent` header containing the running Prefect version — https://github.com/PrefectHQ/prefect/pull/12601
+- Adds deployment version to the flow run object — https://github.com/PrefectHQ/prefect/pull/12591
+
+### Fixes
+- Transition flow runs without active infrastructure directly to cancelled — https://github.com/PrefectHQ/prefect/pull/12582
+- Remove duplicate CLI output when reauthorizing with `prefect cloud login` — https://github.com/PrefectHQ/prefect/pull/12664
+- Add `blob_storage` extra as requirement for Azure `prefect.yaml` recipes — https://github.com/PrefectHQ/prefect/pull/12333
+- Exclude Typer 0.12.2 from solver — https://github.com/PrefectHQ/prefect/pull/12618
+- Correct `schedules`/`is_schedule_active` deprecation windows — https://github.com/PrefectHQ/prefect/pull/12616
+
+### Experimental / In-Flight Features
+
+#### Pydantic V2 Compatibility
+- Add `pydantic` V2 compatible `field_validator` — https://github.com/PrefectHQ/prefect/pull/12576
+- Add `pydantic` V2 `model_validator` — https://github.com/PrefectHQ/prefect/pull/12635
+- Expose `field_validator` in `pydantic` compatibility layer — https://github.com/PrefectHQ/prefect/pull/12608
+- Add `ConfigDict` to `pydantic` compatibility layer — https://github.com/PrefectHQ/prefect/pull/12629
+- Add `model_fields_set` to `pydantic` compatibility layer — https://github.com/PrefectHQ/prefect/pull/12654
+- Map `copy_on_model_validation` to `revalidate_instances` in `pydantic` compatibility layer — https://github.com/PrefectHQ/prefect/pull/12644
+
+#### Events and Automations
+- Enable `EventsWorker` to emit events to Prefect servers — https://github.com/PrefectHQ/prefect/pull/12637
+- Add ORM models and database migrations for events storage — https://github.com/PrefectHQ/prefect/pull/12651
+- Add automations API — https://github.com/PrefectHQ/prefect/pull/12620
+- Add reactive and composite triggers — https://github.com/PrefectHQ/prefect/pull/12650
+- Add proactive triggers — https://github.com/PrefectHQ/prefect/pull/12660
+- Add `EventPersister` service to store received events - https://github.com/PrefectHQ/prefect/pull/12662
+
+### Deprecations
+- Remove expired deprecations from `prefect/__init__.py` — https://github.com/PrefectHQ/prefect/pull/12613
+
+### Documentation
+- Update references to deployment schedules — https://github.com/PrefectHQ/prefect/pull/12595
+- Add missing navigation items for `prefect shell` CLI command — https://github.com/PrefectHQ/prefect/pull/12598
+- Update formatting for `prefect shell` CLI command — https://github.com/PrefectHQ/prefect/pull/12606
+- Add comment to blocks concept page when using `SecretStr` with `pydantic` V2 — https://github.com/PrefectHQ/prefect/pull/12632
+- Fix name format in `run_deployment` docstring — https://github.com/PrefectHQ/prefect/pull/12628
+- Add documentation for flow run job variables — https://github.com/PrefectHQ/prefect/pull/12490
+- Add example of retrieving an artifact in Python code — https://github.com/PrefectHQ/prefect/pull/12666
+
+### Contributors
+- @hainenber
+
+**All changes**: https://github.com/PrefectHQ/prefect/compare/2.16.9...2.17.0
+
+## Release 2.16.9
+
+### `prefect deploy` with `-jv/--job-variable` option
+
+In a prior release, we added a `-jv/--job-variable` option for providing job variables when running a deployment using `prefect deployment run`. We want to be consistent in our CLI by allowing you to use this option while creating deployments during `prefect deploy`! Thus, we have added a `-jv/--job-variable` option to `prefect deploy` to replace the `-v/--variables` option, which we have now deprecated.
+
+See the following pull request for implementation details:
+- https://github.com/PrefectHQ/prefect/pull/12410
+
+### Enhancements
+- Remove nested task constraint that prevented tasks called from other tasks — https://github.com/PrefectHQ/prefect/pull/12548
+- Stop creating artifacts for unpersisted results - https://github.com/PrefectHQ/prefect/pull/12454
+- Allow for deletion of work pool workers via API — https://github.com/PrefectHQ/prefect/pull/12330
+- Raise more informative error on `prefect worker start -t bad-type` - https://github.com/PrefectHQ/prefect/pull/12586
+- Add tooltip and increase width to support better displaying long Prefect variable names in the UI https://github.com/PrefectHQ/prefect-ui-library/pull/2275
+
+### Fixes
+- Raise lower bound on `typer` dependency — https://github.com/PrefectHQ/prefect/pull/12512
+- Skip flow run cancellation if no associated deployment — https://github.com/PrefectHQ/prefect/pull/12001
+- Handle referenced blocks in base templates during `job_variable` validation — https://github.com/PrefectHQ/prefect/pull/12329
+- Select correct `AsyncWaiter` for successively awaited flow and task calls — https://github.com/PrefectHQ/prefect/pull/12510
+- Handle flow run creation for runner-managed deployments — https://github.com/PrefectHQ/prefect/pull/12319
+- Expose `ignore_warnings` in `Flow.deploy` — https://github.com/PrefectHQ/prefect/pull/12569
+- Allow `prefect cloud login` re-authentication in non-interactive mode — https://github.com/PrefectHQ/prefect/pull/12575
+- Update ECS provisioner IAM policy to include `ecs:TagResource` permission — https://github.com/PrefectHQ/prefect/pull/12551
+- Correctly populate custom default parameters in the flow submission form in the UI - https://github.com/PrefectHQ/prefect-ui-library/pull/2280
+
+### Experimental / In-Flight Features
+#### Flow Run Infrastructure Overrides
+- Add support for adding job variables to trigger definitions via CLI - https://github.com/PrefectHQ/prefect/pull/12276
+
+#### Pydantic V2 Compatibility
+- Add dynamic importing of Pydantic modules
+ - https://github.com/PrefectHQ/prefect/pull/12498
+ - https://github.com/PrefectHQ/prefect/pull/12503
+- Refactor Pydantic V2 compatibility layer into submodules — https://github.com/PrefectHQ/prefect/pull/12522
+- Enable support for `mode="json"` in `model_dump` function by default — https://github.com/PrefectHQ/prefect/pull/12540
+
+#### Events and Automations
+- Add message publisher and consumer abstractions, with in-memory implementation — https://github.com/PrefectHQ/prefect/pull/12485
+- Add events HTTP and websocket endpoints — https://github.com/PrefectHQ/prefect/pull/12499
+- Add a diagnostic service which consumes events and prints a summary of them — https://github.com/PrefectHQ/prefect/pull/12501
+- Add internal events client for publishing events from other server-side areas — https://github.com/PrefectHQ/prefect/pull/12520
+- Add an internal orchestration API client for use in events — https://github.com/PrefectHQ/prefect/pull/12534
+- Add server-side automations schema models — https://github.com/PrefectHQ/prefect/pull/12549
+- Add ORM classes and model modules for automations and its state tables — https://github.com/PrefectHQ/prefect/pull/12581
+
+### Integrations - Prefect AWS
+- Fix `S3Bucket.copy_object` target path resolution — https://github.com/PrefectHQ/prefect-aws/pull/385
+- Add Python 3.12 support and remove 3.7 support — https://github.com/PrefectHQ/prefect-aws/pull/405
+- Change logging prefix to avoid unnecessary task definition registrations — https://github.com/PrefectHQ/prefect-aws/pull/400
+
+### Deprecations
+- Deprecate `KubernetesCusterConfig` block — https://github.com/PrefectHQ/prefect/pull/12571
+- Remove use of PartialModel — Click for an example
+
+```python
+import time
+
+from pydantic import BaseModel
+
+from prefect import flow, serve, task
+from prefect.runner import submit_to_runner, wait_for_submitted_runs
+
+
+class Foo(BaseModel):
+ bar: str
+ baz: int
+
+
+class ParentFoo(BaseModel):
+ foo: Foo
+ x: int = 42
+
+@task
+def noop():
+ pass
+
+@flow(log_prints=True)
+async def child(foo: Foo = Foo(bar="hello", baz=42)):
+ print(f"received {foo.bar} and {foo.baz}")
+ print("going to sleep")
+ noop()
+ time.sleep(20)
+
+
+@task
+def foo():
+ time.sleep(2)
+
+@flow(log_prints=True)
+def parent(parent_foo: ParentFoo = ParentFoo(foo=Foo(bar="hello", baz=42))):
+ print(f"I'm a parent and I received {parent_foo=}")
+
+ submit_to_runner(
+ child, [{"foo": Foo(bar="hello", baz=i)} for i in range(9)]
+ )
+
+ foo.submit()
+
+ wait_for_submitted_runs() # optionally block until all submitted runs are complete
+
+
+if __name__ == "__main__":
+ # either enable the webserver via `webserver=True` or via
+ # `prefect config set PREFECT_RUNNER_SERVER_ENABLE=True`
+ serve(parent.to_deployment(__file__), limit=10, webserver=True)
+```
+
+