Skip to content
Latchkey

Docs Integration Tests workflow (griptape-ai/griptape)

The Docs Integration Tests workflow from griptape-ai/griptape, explained and optimized by Latchkey.

B

CI health: B - good

Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: griptape-ai/griptape.github/workflows/docs-integration-tests.ymlLicense Apache-2.0View source

What it does

This is the Docs Integration Tests workflow from the griptape-ai/griptape repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Docs Integration Tests

on:
  push:
    branches: [ "main" ]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10"]
    env:
      AMAZON_OPENSEARCH_HOST: ${{ secrets.INTEG_AMAZON_OPENSEARCH_HOST }}
      AMAZON_OPENSEARCH_INDEX_NAME: ${{ secrets.INTEG_AMAZON_OPENSEARCH_INDEX_NAME }}
      AMAZON_S3_BUCKET: ${{ secrets.INTEG_AMAZON_S3_BUCKET }}
      AMAZON_S3_KEY: ${{ secrets.INTEG_AMAZON_S3_KEY }}
      AMAZON_SQS_QUEUE_URL: ${{ secrets.INTEG_AMAZON_SQS_QUEUE_URL }}
      ANTHROPIC_API_KEY: ${{ secrets.INTEG_ANTHROPIC_API_KEY }}
      ASTRA_DB_API_ENDPOINT: ${{ secrets.INTEG_ASTRA_DB_API_ENDPOINT }}
      ASTRA_DB_APPLICATION_TOKEN: ${{ secrets.INTEG_ASTRA_DB_APPLICATION_TOKEN }}
      AWS_ACCESS_KEY_ID: ${{ secrets.INTEG_AWS_ACCESS_KEY_ID }}
      AWS_DEFAULT_REGION: ${{ secrets.INTEG_AWS_DEFAULT_REGION }}
      AWS_IOT_CORE_ENDPOINT: ${{ secrets.INTEG_AWS_IOT_CORE_ENDPOINT }}
      AWS_IOT_CORE_TOPIC: ${{ secrets.INTEG_AWS_IOT_CORE_TOPIC }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.INTEG_AWS_SECRET_ACCESS_KEY }}
      AZURE_MONGODB_COLLECTION_NAME: ${{ secrets.INTEG_AZURE_MONGODB_COLLECTION_NAME }}
      AZURE_MONGODB_DATABASE_NAME: ${{ secrets.INTEG_AZURE_MONGODB_DATABASE_NAME }}
      AZURE_MONGODB_HOST: ${{ secrets.INTEG_AZURE_MONGODB_HOST }}
      AZURE_MONGODB_INDEX_NAME: ${{ secrets.INTEG_AZURE_MONGODB_INDEX_NAME }}
      AZURE_MONGODB_PASSWORD: ${{ secrets.INTEG_AZURE_MONGODB_PASSWORD }}
      AZURE_MONGODB_USERNAME: ${{ secrets.INTEG_AZURE_MONGODB_USERNAME }}
      AZURE_MONGODB_VECTOR_PATH: ${{ secrets.INTEG_AZURE_MONGODB_VECTOR_PATH }}
      AZURE_OPENAI_35_TURBO_16K_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_35_TURBO_16K_DEPLOYMENT_ID }}
      AZURE_OPENAI_35_TURBO_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_35_TURBO_DEPLOYMENT_ID }}
      AZURE_OPENAI_4_32K_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_4_32K_DEPLOYMENT_ID }}
      AZURE_OPENAI_4_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_4_DEPLOYMENT_ID }}
      AZURE_OPENAI_API_BASE: ${{ secrets.INTEG_AZURE_OPENAI_API_BASE }}
      AZURE_OPENAI_API_KEY_1: ${{ secrets.INTEG_AZURE_OPENAI_API_KEY_1 }}
      AZURE_OPENAI_API_KEY_2: ${{ secrets.INTEG_AZURE_OPENAI_API_KEY_2 }}
      AZURE_OPENAI_API_KEY_4: ${{ secrets.INTEG_AZURE_OPENAI_API_KEY_4 }}
      AZURE_OPENAI_ENDPOINT_1: ${{ vars.INTEG_AZURE_OPENAI_ENDPOINT_1 }}
      AZURE_OPENAI_ENDPOINT_2: ${{ vars.INTEG_AZURE_OPENAI_ENDPOINT_2 }}
      AZURE_OPENAI_ENDPOINT_4: ${{ vars.INTEG_AZURE_OPENAI_ENDPOINT_4 }}
      AZURE_OPENAI_DALL_E_3_DEPLOYMENT_ID: ${{ secrets.INTEG_AZURE_OPENAI_DALL_E_3_DEPLOYMENT_ID }}
      AZURE_OPENAI_DEV_2_API_BASE: ${{ secrets.INTEG_AZURE_OPENAI_DEV_2_API_BASE }}
      AZURE_OPENAI_DEV_2_API_KEY: ${{ secrets.INTEG_AZURE_OPENAI_DEV_2_API_KEY }}
      COHERE_API_KEY: ${{ secrets.INTEG_COHERE_API_KEY }}
      DYNAMODB_TABLE_NAME: ${{ secrets.INTEG_DYNAMODB_TABLE_NAME }}
      ELEVEN_LABS_API_KEY: ${{ secrets.INTEG_ELEVEN_LABS_API_KEY }}
      EXA_API_KEY: ${{ secrets.INTEG_EXA_API_KEY }}
      GOOGLE_API_KEY: ${{ secrets.INTEG_GOOGLE_API_KEY }}
      GOOGLE_API_SEARCH_ID: ${{ secrets.INTEG_GOOGLE_API_SEARCH_ID }}
      GOOGLE_OWNER_EMAIL: ${{ secrets.INTEG_GOOGLE_OWNER_EMAIL }}
      GROK_API_KEY: ${{ secrets.INTEG_GROK_API_KEY }}
      GROQ_API_KEY: ${{ secrets.INTEG_GROQ_API_KEY }}
      GT_CLOUD_API_KEY: ${{ secrets.INTEG_GT_CLOUD_API_KEY }}
      GT_CLOUD_ASSET_NAME: ${{ vars.INTEG_GT_CLOUD_ASSET_NAME }}
      GT_CLOUD_ASSISTANT_ID: ${{ vars.INTEG_GT_CLOUD_ASSISTANT_ID }}
      GT_CLOUD_BASE_URL: ${{ vars.INTEG_GT_CLOUD_BASE_URL }}
      GT_CLOUD_BUCKET_ID: ${{ vars.INTEG_GT_CLOUD_BUCKET_ID }}
      GT_CLOUD_KB_ID: ${{ vars.INTEG_GT_CLOUD_KB_ID }}
      GT_CLOUD_STRUCTURE_ID: ${{ vars.INTEG_GT_CLOUD_STRUCTURE_ID }}
      GT_CLOUD_STRUCTURE_RUN_ID: ${{ vars.INTEG_GT_CLOUD_STRUCTURE_RUN_ID }}
      GT_CLOUD_THREAD_ID: ${{ vars.INTEG_GT_CLOUD_THREAD_ID }}
      GT_CLOUD_TOOL_ID: ${{ vars.INTEG_GT_CLOUD_TOOL_ID }}
      HUGGINGFACE_HUB_ACCESS_TOKEN: ${{ secrets.INTEG_HUGGINGFACE_HUB_ACCESS_TOKEN }}
      LEONARDO_API_KEY: ${{ secrets.INTEG_LEONARDO_API_KEY }}
      LEONARDO_MODEL_ID: ${{ secrets.INTEG_LEONARDO_MODEL_ID }}
      MONGODB_COLLECTION_NAME: ${{ secrets.INTEG_MONGODB_COLLECTION_NAME }}
      MONGODB_DATABASE_NAME: ${{ secrets.INTEG_MONGODB_DATABASE_NAME }}
      MONGODB_HOST: ${{ secrets.INTEG_MONGODB_HOST }}
      MONGODB_INDEX_NAME: ${{ secrets.INTEG_MONGODB_INDEX_NAME }}
      MONGODB_PASSWORD: ${{ secrets.INTEG_MONGODB_PASSWORD }}
      MONGODB_USERNAME: ${{ secrets.INTEG_MONGODB_USERNAME }}
      MONGODB_VECTOR_PATH: ${{ secrets.INTEG_MONGODB_VECTOR_PATH }}
      MARQO_API_KEY: ${{ secrets.INTEG_MARQO_API_KEY }}
      MARQO_INDEX_NAME: ${{ secrets.INTEG_MARQO_INDEX_NAME }}
      MARQO_URL: ${{ secrets.INTEG_MARQO_URL }}
      OPENAI_API_KEY: ${{ secrets.INTEG_OPENAI_API_KEY}}
      OPENAI_ASSISTANT_ID: ${{ vars.INTEG_OPENAI_ASSISTANT_ID }}
      OPENAI_THREAD_ID: ${{ vars.INTEG_OPENAI_THREAD_ID }}
      OPENWEATHER_API_KEY: ${{ secrets.INTEG_OPENWEATHER_API_KEY }}
      PERPLEXITY_API_KEY: ${{ secrets.INTEG_PERPLEXITY_API_KEY }}
      PINECONE_API_KEY: ${{ secrets.INTEG_PINECONE_API_KEY }}
      PINECONE_ENVIRONMENT: ${{ secrets.INTEG_PINECONE_ENVIRONMENT }}
      PINECONE_INDEX_NAME: ${{ secrets.INTEG_PINECONE_INDEX_NAME }}
      POSTGRES_DB: ${{ secrets.INTEG_POSTGRES_DB }}
      POSTGRES_HOST: ${{ secrets.INTEG_POSTGRES_HOST }}
      POSTGRES_PASSWORD: ${{ secrets.INTEG_POSTGRES_PASSWORD }}
      POSTGRES_PORT: ${{ secrets.INTEG_POSTGRES_PORT }}
      POSTGRES_USER: ${{ secrets.INTEG_POSTGRES_USER }}
      PUSHER_APP_ID: ${{ secrets.INTEG_PUSHER_APP_ID }}
      PUSHER_CLUSTER: ${{ secrets.INTEG_PUSHER_CLUSTER }}
      PUSHER_KEY: ${{ secrets.INTEG_PUSHER_KEY }}
      PUSHER_SECRET: ${{ secrets.INTEG_PUSHER_SECRET }}
      QDRANT_CLUSTER_API_KEY: ${{ secrets.INTEG_QDRANT_CLUSTER_API_KEY }}
      QDRANT_CLUSTER_ENDPOINT: ${{ secrets.INTEG_QDRANT_CLUSTER_ENDPOINT }}
      REDIS_HOST: ${{ secrets.INTEG_REDIS_HOST }}
      REDIS_USERNAME: ${{ secrets.INTEG_REDIS_USERNAME }}
      REDIS_INDEX: ${{ secrets.INTEG_REDIS_INDEX }}
      REDIS_PASSWORD: ${{ secrets.INTEG_REDIS_PASSWORD }}
      REDIS_PORT: ${{ secrets.INTEG_REDIS_PORT }}
      REDSHIFT_CLUSTER_IDENTIFIER: ${{ secrets.INTEG_REDSHIFT_CLUSTER_IDENTIFIER }}
      REDSHIFT_DATABASE: ${{ secrets.INTEG_REDSHIFT_DATABASE }}
      SAGEMAKER_FALCON_ENDPOINT_NAME: ${{ secrets.INTEG_FALCON_ENDPOINT_NAME }}
      SAGEMAKER_FALCON_INFERENCE_COMPONENT_NAME: ${{ secrets.INTEG_FALCON_INFERENCE_COMPONENT_NAME }}
      SAGEMAKER_HUGGINGFACE_MODEL: ${{ secrets.INTEG_SAGEMAKER_HUGGINGFACE_MODEL }}
      SAGEMAKER_LLAMA_3_INSTRUCT_ENDPOINT_NAME: ${{ secrets.SAGEMAKER_LLAMA_3_INSTRUCT_ENDPOINT_NAME }}
      SAGEMAKER_LLAMA_3_INSTRUCT_INFERENCE_COMPONENT_NAME: ${{ secrets.SAGEMAKER_LLAMA_3_INSTRUCT_INFERENCE_COMPONENT_NAME }}
      SAGEMAKER_TENSORFLOW_HUB_MODEL: ${{ secrets.INTEG_SAGEMAKER_TENSORFLOW_HUB_MODEL }}
      SNOWFLAKE_ACCOUNT: ${{ secrets.INTEG_SNOWFLAKE_ACCOUNT }}
      SNOWFLAKE_DATABASE: ${{ secrets.INTEG_SNOWFLAKE_DATABASE }}
      SNOWFLAKE_PASSWORD: ${{ secrets.INTEG_SNOWFLAKE_PASSWORD }}
      SNOWFLAKE_SCHEMA: ${{ secrets.INTEG_SNOWFLAKE_SCHEMA }}
      SNOWFLAKE_USER: ${{ secrets.INTEG_SNOWFLAKE_USER }}
      SNOWFLAKE_WAREHOUSE: ${{ secrets.INTEG_SNOWFLAKE_WAREHOUSE }}
      TAVILY_API_KEY: ${{ secrets.INTEG_TAVILY_API_KEY }}
      VOYAGE_API_KEY: ${{ secrets.INTEG_VOYAGE_API_KEY }}
      WEBHOOK_URL: ${{ secrets.INTEG_WEBHOOK_URL }}
      ZENROWS_API_KEY: ${{ secrets.INTEG_ZENROWS_API_KEY }}
      
    services:
      postgres:
        image: ankane/pgvector:v0.5.0
        env:
          POSTGRES_USER: ${{ secrets.INTEG_POSTGRES_USER }}
          POSTGRES_PASSWORD: ${{ secrets.INTEG_POSTGRES_PASSWORD }}
          POSTGRES_DB: ${{ secrets.INTEG_POSTGRES_DB }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - name: Checkout actions
        uses: actions/checkout@v7
      - name: Init environment
        uses: ./.github/actions/init-environment
      # Integration tests will run on all code snippets, outputting their logs to /tmp/logs
      - name: Run integration tests
        run: uv run pytest -n auto tests/integration/test_code_blocks.py
      # If any code snippets have changed, we want to copy the logs to display in the docs
      - name: Get Changed Files
        id: changed-files
        uses: tj-actions/changed-files@v47
        with:
          files: docs/**/*.py
      - name: Run Snippet Logs 
        run: uv run python .github/scripts/gen_snippet_logs.py docs/griptape-framework ${{ steps.changed-files.outputs.all_changed_files }}
      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v8
        with:
          branch: "docs/snippet-logs-update"
          title: "chore(docs): update code snippets logs"
          body: "This PR was automatically generated to update the code snippets logs in the documentation."
          commit-message: "chore(docs): update code snippets logs"
          base: "main"
          labels: "docs"
          add-paths: |
            docs/**/*
          token: ${{ secrets.GH_RELEASE_PAT }}

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Docs Integration Tests
 
on:
  push:
    branches: [ "main" ]
 
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
 
jobs:
  test:
    timeout-minutes: 30
    runs-on: latchkey-small
    permissions:
      contents: write
      pull-requests: write
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10"]
    env:
      AMAZON_OPENSEARCH_HOST: ${{ secrets.INTEG_AMAZON_OPENSEARCH_HOST }}
      AMAZON_OPENSEARCH_INDEX_NAME: ${{ secrets.INTEG_AMAZON_OPENSEARCH_INDEX_NAME }}
      AMAZON_S3_BUCKET: ${{ secrets.INTEG_AMAZON_S3_BUCKET }}
      AMAZON_S3_KEY: ${{ secrets.INTEG_AMAZON_S3_KEY }}
      AMAZON_SQS_QUEUE_URL: ${{ secrets.INTEG_AMAZON_SQS_QUEUE_URL }}
      ANTHROPIC_API_KEY: ${{ secrets.INTEG_ANTHROPIC_API_KEY }}
      ASTRA_DB_API_ENDPOINT: ${{ secrets.INTEG_ASTRA_DB_API_ENDPOINT }}
      ASTRA_DB_APPLICATION_TOKEN: ${{ secrets.INTEG_ASTRA_DB_APPLICATION_TOKEN }}
      AWS_ACCESS_KEY_ID: ${{ secrets.INTEG_AWS_ACCESS_KEY_ID }}
      AWS_DEFAULT_REGION: ${{ secrets.INTEG_AWS_DEFAULT_REGION }}
      AWS_IOT_CORE_ENDPOINT: ${{ secrets.INTEG_AWS_IOT_CORE_ENDPOINT }}
      AWS_IOT_CORE_TOPIC: ${{ secrets.INTEG_AWS_IOT_CORE_TOPIC }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.INTEG_AWS_SECRET_ACCESS_KEY }}
      AZURE_MONGODB_COLLECTION_NAME: ${{ secrets.INTEG_AZURE_MONGODB_COLLECTION_NAME }}
      AZURE_MONGODB_DATABASE_NAME: ${{ secrets.INTEG_AZURE_MONGODB_DATABASE_NAME }}
      AZURE_MONGODB_HOST: ${{ secrets.INTEG_AZURE_MONGODB_HOST }}
      AZURE_MONGODB_INDEX_NAME: ${{ secrets.INTEG_AZURE_MONGODB_INDEX_NAME }}
      AZURE_MONGODB_PASSWORD: ${{ secrets.INTEG_AZURE_MONGODB_PASSWORD }}
      AZURE_MONGODB_USERNAME: ${{ secrets.INTEG_AZURE_MONGODB_USERNAME }}
      AZURE_MONGODB_VECTOR_PATH: ${{ secrets.INTEG_AZURE_MONGODB_VECTOR_PATH }}
      AZURE_OPENAI_35_TURBO_16K_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_35_TURBO_16K_DEPLOYMENT_ID }}
      AZURE_OPENAI_35_TURBO_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_35_TURBO_DEPLOYMENT_ID }}
      AZURE_OPENAI_4_32K_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_4_32K_DEPLOYMENT_ID }}
      AZURE_OPENAI_4_DEPLOYMENT_ID: ${{ secrets.INTEG_OPENAI_4_DEPLOYMENT_ID }}
      AZURE_OPENAI_API_BASE: ${{ secrets.INTEG_AZURE_OPENAI_API_BASE }}
      AZURE_OPENAI_API_KEY_1: ${{ secrets.INTEG_AZURE_OPENAI_API_KEY_1 }}
      AZURE_OPENAI_API_KEY_2: ${{ secrets.INTEG_AZURE_OPENAI_API_KEY_2 }}
      AZURE_OPENAI_API_KEY_4: ${{ secrets.INTEG_AZURE_OPENAI_API_KEY_4 }}
      AZURE_OPENAI_ENDPOINT_1: ${{ vars.INTEG_AZURE_OPENAI_ENDPOINT_1 }}
      AZURE_OPENAI_ENDPOINT_2: ${{ vars.INTEG_AZURE_OPENAI_ENDPOINT_2 }}
      AZURE_OPENAI_ENDPOINT_4: ${{ vars.INTEG_AZURE_OPENAI_ENDPOINT_4 }}
      AZURE_OPENAI_DALL_E_3_DEPLOYMENT_ID: ${{ secrets.INTEG_AZURE_OPENAI_DALL_E_3_DEPLOYMENT_ID }}
      AZURE_OPENAI_DEV_2_API_BASE: ${{ secrets.INTEG_AZURE_OPENAI_DEV_2_API_BASE }}
      AZURE_OPENAI_DEV_2_API_KEY: ${{ secrets.INTEG_AZURE_OPENAI_DEV_2_API_KEY }}
      COHERE_API_KEY: ${{ secrets.INTEG_COHERE_API_KEY }}
      DYNAMODB_TABLE_NAME: ${{ secrets.INTEG_DYNAMODB_TABLE_NAME }}
      ELEVEN_LABS_API_KEY: ${{ secrets.INTEG_ELEVEN_LABS_API_KEY }}
      EXA_API_KEY: ${{ secrets.INTEG_EXA_API_KEY }}
      GOOGLE_API_KEY: ${{ secrets.INTEG_GOOGLE_API_KEY }}
      GOOGLE_API_SEARCH_ID: ${{ secrets.INTEG_GOOGLE_API_SEARCH_ID }}
      GOOGLE_OWNER_EMAIL: ${{ secrets.INTEG_GOOGLE_OWNER_EMAIL }}
      GROK_API_KEY: ${{ secrets.INTEG_GROK_API_KEY }}
      GROQ_API_KEY: ${{ secrets.INTEG_GROQ_API_KEY }}
      GT_CLOUD_API_KEY: ${{ secrets.INTEG_GT_CLOUD_API_KEY }}
      GT_CLOUD_ASSET_NAME: ${{ vars.INTEG_GT_CLOUD_ASSET_NAME }}
      GT_CLOUD_ASSISTANT_ID: ${{ vars.INTEG_GT_CLOUD_ASSISTANT_ID }}
      GT_CLOUD_BASE_URL: ${{ vars.INTEG_GT_CLOUD_BASE_URL }}
      GT_CLOUD_BUCKET_ID: ${{ vars.INTEG_GT_CLOUD_BUCKET_ID }}
      GT_CLOUD_KB_ID: ${{ vars.INTEG_GT_CLOUD_KB_ID }}
      GT_CLOUD_STRUCTURE_ID: ${{ vars.INTEG_GT_CLOUD_STRUCTURE_ID }}
      GT_CLOUD_STRUCTURE_RUN_ID: ${{ vars.INTEG_GT_CLOUD_STRUCTURE_RUN_ID }}
      GT_CLOUD_THREAD_ID: ${{ vars.INTEG_GT_CLOUD_THREAD_ID }}
      GT_CLOUD_TOOL_ID: ${{ vars.INTEG_GT_CLOUD_TOOL_ID }}
      HUGGINGFACE_HUB_ACCESS_TOKEN: ${{ secrets.INTEG_HUGGINGFACE_HUB_ACCESS_TOKEN }}
      LEONARDO_API_KEY: ${{ secrets.INTEG_LEONARDO_API_KEY }}
      LEONARDO_MODEL_ID: ${{ secrets.INTEG_LEONARDO_MODEL_ID }}
      MONGODB_COLLECTION_NAME: ${{ secrets.INTEG_MONGODB_COLLECTION_NAME }}
      MONGODB_DATABASE_NAME: ${{ secrets.INTEG_MONGODB_DATABASE_NAME }}
      MONGODB_HOST: ${{ secrets.INTEG_MONGODB_HOST }}
      MONGODB_INDEX_NAME: ${{ secrets.INTEG_MONGODB_INDEX_NAME }}
      MONGODB_PASSWORD: ${{ secrets.INTEG_MONGODB_PASSWORD }}
      MONGODB_USERNAME: ${{ secrets.INTEG_MONGODB_USERNAME }}
      MONGODB_VECTOR_PATH: ${{ secrets.INTEG_MONGODB_VECTOR_PATH }}
      MARQO_API_KEY: ${{ secrets.INTEG_MARQO_API_KEY }}
      MARQO_INDEX_NAME: ${{ secrets.INTEG_MARQO_INDEX_NAME }}
      MARQO_URL: ${{ secrets.INTEG_MARQO_URL }}
      OPENAI_API_KEY: ${{ secrets.INTEG_OPENAI_API_KEY}}
      OPENAI_ASSISTANT_ID: ${{ vars.INTEG_OPENAI_ASSISTANT_ID }}
      OPENAI_THREAD_ID: ${{ vars.INTEG_OPENAI_THREAD_ID }}
      OPENWEATHER_API_KEY: ${{ secrets.INTEG_OPENWEATHER_API_KEY }}
      PERPLEXITY_API_KEY: ${{ secrets.INTEG_PERPLEXITY_API_KEY }}
      PINECONE_API_KEY: ${{ secrets.INTEG_PINECONE_API_KEY }}
      PINECONE_ENVIRONMENT: ${{ secrets.INTEG_PINECONE_ENVIRONMENT }}
      PINECONE_INDEX_NAME: ${{ secrets.INTEG_PINECONE_INDEX_NAME }}
      POSTGRES_DB: ${{ secrets.INTEG_POSTGRES_DB }}
      POSTGRES_HOST: ${{ secrets.INTEG_POSTGRES_HOST }}
      POSTGRES_PASSWORD: ${{ secrets.INTEG_POSTGRES_PASSWORD }}
      POSTGRES_PORT: ${{ secrets.INTEG_POSTGRES_PORT }}
      POSTGRES_USER: ${{ secrets.INTEG_POSTGRES_USER }}
      PUSHER_APP_ID: ${{ secrets.INTEG_PUSHER_APP_ID }}
      PUSHER_CLUSTER: ${{ secrets.INTEG_PUSHER_CLUSTER }}
      PUSHER_KEY: ${{ secrets.INTEG_PUSHER_KEY }}
      PUSHER_SECRET: ${{ secrets.INTEG_PUSHER_SECRET }}
      QDRANT_CLUSTER_API_KEY: ${{ secrets.INTEG_QDRANT_CLUSTER_API_KEY }}
      QDRANT_CLUSTER_ENDPOINT: ${{ secrets.INTEG_QDRANT_CLUSTER_ENDPOINT }}
      REDIS_HOST: ${{ secrets.INTEG_REDIS_HOST }}
      REDIS_USERNAME: ${{ secrets.INTEG_REDIS_USERNAME }}
      REDIS_INDEX: ${{ secrets.INTEG_REDIS_INDEX }}
      REDIS_PASSWORD: ${{ secrets.INTEG_REDIS_PASSWORD }}
      REDIS_PORT: ${{ secrets.INTEG_REDIS_PORT }}
      REDSHIFT_CLUSTER_IDENTIFIER: ${{ secrets.INTEG_REDSHIFT_CLUSTER_IDENTIFIER }}
      REDSHIFT_DATABASE: ${{ secrets.INTEG_REDSHIFT_DATABASE }}
      SAGEMAKER_FALCON_ENDPOINT_NAME: ${{ secrets.INTEG_FALCON_ENDPOINT_NAME }}
      SAGEMAKER_FALCON_INFERENCE_COMPONENT_NAME: ${{ secrets.INTEG_FALCON_INFERENCE_COMPONENT_NAME }}
      SAGEMAKER_HUGGINGFACE_MODEL: ${{ secrets.INTEG_SAGEMAKER_HUGGINGFACE_MODEL }}
      SAGEMAKER_LLAMA_3_INSTRUCT_ENDPOINT_NAME: ${{ secrets.SAGEMAKER_LLAMA_3_INSTRUCT_ENDPOINT_NAME }}
      SAGEMAKER_LLAMA_3_INSTRUCT_INFERENCE_COMPONENT_NAME: ${{ secrets.SAGEMAKER_LLAMA_3_INSTRUCT_INFERENCE_COMPONENT_NAME }}
      SAGEMAKER_TENSORFLOW_HUB_MODEL: ${{ secrets.INTEG_SAGEMAKER_TENSORFLOW_HUB_MODEL }}
      SNOWFLAKE_ACCOUNT: ${{ secrets.INTEG_SNOWFLAKE_ACCOUNT }}
      SNOWFLAKE_DATABASE: ${{ secrets.INTEG_SNOWFLAKE_DATABASE }}
      SNOWFLAKE_PASSWORD: ${{ secrets.INTEG_SNOWFLAKE_PASSWORD }}
      SNOWFLAKE_SCHEMA: ${{ secrets.INTEG_SNOWFLAKE_SCHEMA }}
      SNOWFLAKE_USER: ${{ secrets.INTEG_SNOWFLAKE_USER }}
      SNOWFLAKE_WAREHOUSE: ${{ secrets.INTEG_SNOWFLAKE_WAREHOUSE }}
      TAVILY_API_KEY: ${{ secrets.INTEG_TAVILY_API_KEY }}
      VOYAGE_API_KEY: ${{ secrets.INTEG_VOYAGE_API_KEY }}
      WEBHOOK_URL: ${{ secrets.INTEG_WEBHOOK_URL }}
      ZENROWS_API_KEY: ${{ secrets.INTEG_ZENROWS_API_KEY }}
      
    services:
      postgres:
        image: ankane/pgvector:v0.5.0
        env:
          POSTGRES_USER: ${{ secrets.INTEG_POSTGRES_USER }}
          POSTGRES_PASSWORD: ${{ secrets.INTEG_POSTGRES_PASSWORD }}
          POSTGRES_DB: ${{ secrets.INTEG_POSTGRES_DB }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - name: Checkout actions
        uses: actions/checkout@v7
      - name: Init environment
        uses: ./.github/actions/init-environment
      # Integration tests will run on all code snippets, outputting their logs to /tmp/logs
      - name: Run integration tests
        run: uv run pytest -n auto tests/integration/test_code_blocks.py
      # If any code snippets have changed, we want to copy the logs to display in the docs
      - name: Get Changed Files
        id: changed-files
        uses: tj-actions/changed-files@v47
        with:
          files: docs/**/*.py
      - name: Run Snippet Logs 
        run: uv run python .github/scripts/gen_snippet_logs.py docs/griptape-framework ${{ steps.changed-files.outputs.all_changed_files }}
      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v8
        with:
          branch: "docs/snippet-logs-update"
          title: "chore(docs): update code snippets logs"
          body: "This PR was automatically generated to update the code snippets logs in the documentation."
          commit-message: "chore(docs): update code snippets logs"
          base: "main"
          labels: "docs"
          add-paths: |
            docs/**/*
          token: ${{ secrets.GH_RELEASE_PAT }}
 

What changed

2 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow