Docs Integration Tests workflow (griptape-ai/griptape)
The Docs Integration Tests workflow from griptape-ai/griptape, explained and optimized by Latchkey.
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.
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
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
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
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.