redis-iris 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- redis_iris-0.1.0a1/.autorc +90 -0
- redis_iris-0.1.0a1/.github/dependabot.yml +20 -0
- redis_iris-0.1.0a1/.github/workflows/auto-release.yml +257 -0
- redis_iris-0.1.0a1/.github/workflows/ci.yml +107 -0
- redis_iris-0.1.0a1/.github/workflows/docs.yml +49 -0
- redis_iris-0.1.0a1/.github/workflows/integration.yml +60 -0
- redis_iris-0.1.0a1/.github/workflows/publish.yml +82 -0
- redis_iris-0.1.0a1/.gitignore +36 -0
- redis_iris-0.1.0a1/AGENTS.md +53 -0
- redis_iris-0.1.0a1/CONTRIBUTING.md +148 -0
- redis_iris-0.1.0a1/Formula/redis-iris.rb +22 -0
- redis_iris-0.1.0a1/LICENSE +21 -0
- redis_iris-0.1.0a1/PACKAGE_EVOLUTION_PLAN.md +122 -0
- redis_iris-0.1.0a1/PKG-INFO +154 -0
- redis_iris-0.1.0a1/README.md +129 -0
- redis_iris-0.1.0a1/RELEASE_PIPELINE_PLAN.md +181 -0
- redis_iris-0.1.0a1/Taskfile.yml +49 -0
- redis_iris-0.1.0a1/config.example.toml +14 -0
- redis_iris-0.1.0a1/docs/assets/favicon.png +0 -0
- redis_iris-0.1.0a1/docs/assets/redis-logo-script-red.svg +11 -0
- redis_iris-0.1.0a1/docs/assets/redis-logo-script.svg +11 -0
- redis_iris-0.1.0a1/docs/core/agent-memory.md +204 -0
- redis_iris-0.1.0a1/docs/core/context-retriever.md +137 -0
- redis_iris-0.1.0a1/docs/core/errors.md +27 -0
- redis_iris-0.1.0a1/docs/core/index.md +40 -0
- redis_iris-0.1.0a1/docs/core/iris.md +24 -0
- redis_iris-0.1.0a1/docs/core/playbook.md +175 -0
- redis_iris-0.1.0a1/docs/index.md +48 -0
- redis_iris-0.1.0a1/docs/skills/add-agent-memory/SKILL.md +132 -0
- redis_iris-0.1.0a1/docs/skills/add-context-retriever/SKILL.md +98 -0
- redis_iris-0.1.0a1/docs/skills/add-playbook/SKILL.md +169 -0
- redis_iris-0.1.0a1/docs/skills/add-redis-iris/SKILL.md +60 -0
- redis_iris-0.1.0a1/docs/skills/index.md +61 -0
- redis_iris-0.1.0a1/docs/stylesheets/redis-brand.css +91 -0
- redis_iris-0.1.0a1/docs/user_guides/answer-from-approved-policy.md +136 -0
- redis_iris-0.1.0a1/docs/user_guides/configuration.md +97 -0
- redis_iris-0.1.0a1/docs/user_guides/index.md +20 -0
- redis_iris-0.1.0a1/docs/user_guides/live-account-data.md +133 -0
- redis_iris-0.1.0a1/docs/user_guides/one-support-turn.md +126 -0
- redis_iris-0.1.0a1/docs/user_guides/playbook-cli.md +613 -0
- redis_iris-0.1.0a1/docs/user_guides/remember-customers.md +143 -0
- redis_iris-0.1.0a1/docs/user_guides/set-up-agent-memory.md +88 -0
- redis_iris-0.1.0a1/docs/user_guides/set-up-playbook.md +94 -0
- redis_iris-0.1.0a1/examples/.env.example +32 -0
- redis_iris-0.1.0a1/examples/01_plug_in_agent_memory.md +260 -0
- redis_iris-0.1.0a1/examples/01_plug_in_agent_memory.py +261 -0
- redis_iris-0.1.0a1/examples/02_publish_policy_with_playbook.md +223 -0
- redis_iris-0.1.0a1/examples/02_publish_policy_with_playbook.py +221 -0
- redis_iris-0.1.0a1/examples/03_live_accounts_with_context_retriever.md +188 -0
- redis_iris-0.1.0a1/examples/03_live_accounts_with_context_retriever.py +188 -0
- redis_iris-0.1.0a1/examples/04_one_support_turn.md +147 -0
- redis_iris-0.1.0a1/examples/04_one_support_turn.py +149 -0
- redis_iris-0.1.0a1/examples/README.md +144 -0
- redis_iris-0.1.0a1/examples/example/__init__.py +63 -0
- redis_iris-0.1.0a1/examples/example/data/accounts.jsonl +4 -0
- redis_iris-0.1.0a1/examples/example/data/customers.jsonl +3 -0
- redis_iris-0.1.0a1/examples/example/data/faqs/card-replacement.json +8 -0
- redis_iris-0.1.0a1/examples/example/data/faqs/dispute-charge.json +8 -0
- redis_iris-0.1.0a1/examples/example/data/faqs/overdraft-fee-refund.json +8 -0
- redis_iris-0.1.0a1/examples/example/data/faqs/overdraft-fee.json +8 -0
- redis_iris-0.1.0a1/examples/example/data/faqs/routing-number.json +8 -0
- redis_iris-0.1.0a1/examples/example/data/memories.jsonl +4 -0
- redis_iris-0.1.0a1/examples/example/data/skills/dispute-intake/.iris-playbook.json +5 -0
- redis_iris-0.1.0a1/examples/example/data/skills/dispute-intake/SKILL.md +13 -0
- redis_iris-0.1.0a1/examples/example/data/transactions.jsonl +11 -0
- redis_iris-0.1.0a1/examples/example/langgraph_glue.py +245 -0
- redis_iris-0.1.0a1/examples/example/models.py +68 -0
- redis_iris-0.1.0a1/examples/example/turn.py +119 -0
- redis_iris-0.1.0a1/examples/local/context-retriever.ports.yaml +30 -0
- redis_iris-0.1.0a1/examples/local/memory.env.yaml +15 -0
- redis_iris-0.1.0a1/examples/local/playbook.openai.yaml +20 -0
- redis_iris-0.1.0a1/examples/maintain.py +853 -0
- redis_iris-0.1.0a1/examples/playbook_cli.sh +23 -0
- redis_iris-0.1.0a1/examples/setup_meridian.py +188 -0
- redis_iris-0.1.0a1/examples/spec.md +209 -0
- redis_iris-0.1.0a1/examples/ui/.gitignore +3 -0
- redis_iris-0.1.0a1/examples/ui/.oxfmtrc.json +13 -0
- redis_iris-0.1.0a1/examples/ui/.oxlintrc.json +43 -0
- redis_iris-0.1.0a1/examples/ui/index.html +12 -0
- redis_iris-0.1.0a1/examples/ui/package-lock.json +4853 -0
- redis_iris-0.1.0a1/examples/ui/package.json +45 -0
- redis_iris-0.1.0a1/examples/ui/server.py +208 -0
- redis_iris-0.1.0a1/examples/ui/src/App.tsx +5 -0
- redis_iris-0.1.0a1/examples/ui/src/api/client.ts +79 -0
- redis_iris-0.1.0a1/examples/ui/src/api/queryKeys.ts +12 -0
- redis_iris-0.1.0a1/examples/ui/src/api/types.ts +84 -0
- redis_iris-0.1.0a1/examples/ui/src/main.tsx +24 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/MeridianScreen/MeridianScreen.style.ts +30 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/MeridianScreen/MeridianScreen.tsx +43 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/OperatorPanel.style.ts +9 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/OperatorPanel.tsx +25 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/MemoryOwnerCard/MemoryOwnerCard.style.ts +37 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/MemoryOwnerCard/MemoryOwnerCard.tsx +92 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/PlaybookEntriesCard/PlaybookEntriesCard.style.ts +41 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/PlaybookEntriesCard/PlaybookEntriesCard.tsx +130 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/PlaybookEntriesCard/PlaybookEntriesCard.types.ts +6 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/RetrieverStatusCard/RetrieverStatusCard.style.ts +13 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/RetrieverStatusCard/RetrieverStatusCard.tsx +36 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/StackStatusCard/StackStatusCard.style.ts +13 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/OperatorPanel/components/StackStatusCard/StackStatusCard.tsx +39 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/SupportChatPanel.style.ts +17 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/SupportChatPanel.tsx +56 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/SupportChatPanel.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatComposer/ChatComposer.style.ts +12 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatComposer/ChatComposer.tsx +48 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatComposer/ChatComposer.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.style.ts +24 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.test.tsx +37 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.tsx +25 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/SupportChatPanel/components/ChatTranscript/ChatTranscript.types.ts +6 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/TurnEvidencePanel.style.ts +9 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/TurnEvidencePanel.tsx +43 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/TurnEvidencePanel.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/MemoryEvidenceList/MemoryEvidenceList.style.ts +19 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/MemoryEvidenceList/MemoryEvidenceList.tsx +28 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/MemoryEvidenceList/MemoryEvidenceList.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/PolicyEvidenceList/PolicyEvidenceList.style.ts +19 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/PolicyEvidenceList/PolicyEvidenceList.tsx +29 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/PolicyEvidenceList/PolicyEvidenceList.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/TransactionsTable/TransactionsTable.style.ts +27 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/TransactionsTable/TransactionsTable.tsx +38 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/components/TurnEvidencePanel/components/TransactionsTable/TransactionsTable.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useConfigQuery/useConfigQuery.ts +7 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useEraseMemoryMutation/useEraseMemoryMutation.ts +20 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useMemoryOwnerQuery/useMemoryOwnerQuery.ts +8 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/usePlaybookEntriesQuery/usePlaybookEntriesQuery.ts +8 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/usePlaybookVersionsQuery/usePlaybookVersionsQuery.ts +13 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/usePublishVersionMutation/usePublishVersionMutation.ts +23 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useReseedMemoryMutation/useReseedMemoryMutation.ts +19 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useRetrieverQuery/useRetrieverQuery.ts +8 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useStackQuery/useStackQuery.ts +10 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useTurnMutation/useTurnMutation.ts +19 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/hooks/useWithdrawEntryMutation/useWithdrawEntryMutation.ts +23 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/types/chat.ts +7 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/utils/formatScore/formatScore.test.ts +11 -0
- redis_iris-0.1.0a1/examples/ui/src/screens/meridian/utils/formatScore/formatScore.ts +3 -0
- redis_iris-0.1.0a1/examples/ui/src/styled.d.ts +9 -0
- redis_iris-0.1.0a1/examples/ui/src/test/setup-tests.ts +26 -0
- redis_iris-0.1.0a1/examples/ui/src/theme/ResponsiveRem/ResponsiveRem.ts +21 -0
- redis_iris-0.1.0a1/examples/ui/src/theme/ThemeProvider/ThemeProvider.tsx +22 -0
- redis_iris-0.1.0a1/examples/ui/src/theme/ThemeProvider/ThemeProvider.types.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/utils/formatAmount/formatAmount.test.ts +15 -0
- redis_iris-0.1.0a1/examples/ui/src/utils/formatAmount/formatAmount.ts +7 -0
- redis_iris-0.1.0a1/examples/ui/src/utils/formatDate/formatDate.test.ts +13 -0
- redis_iris-0.1.0a1/examples/ui/src/utils/formatDate/formatDate.ts +5 -0
- redis_iris-0.1.0a1/examples/ui/src/vite-env.d.ts +1 -0
- redis_iris-0.1.0a1/examples/ui/tsconfig.app.json +25 -0
- redis_iris-0.1.0a1/examples/ui/tsconfig.json +4 -0
- redis_iris-0.1.0a1/examples/ui/tsconfig.node.json +17 -0
- redis_iris-0.1.0a1/examples/ui/vite.config.ts +42 -0
- redis_iris-0.1.0a1/mkdocs.yml +134 -0
- redis_iris-0.1.0a1/mkdocs_hooks.py +20 -0
- redis_iris-0.1.0a1/pyproject.toml +129 -0
- redis_iris-0.1.0a1/src/redis_iris/__init__.py +21 -0
- redis_iris-0.1.0a1/src/redis_iris/__main__.py +6 -0
- redis_iris-0.1.0a1/src/redis_iris/_settings.py +30 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/__init__.py +43 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/_wire.py +47 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/conversation.py +81 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/hooks.py +55 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/ids.py +27 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/memory.py +309 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/settings.py +66 -0
- redis_iris-0.1.0a1/src/redis_iris/agent_memory/values.py +66 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/__init__.py +1 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/__main__.py +6 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/__init__.py +1 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/branding.py +22 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/config.py +95 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/errors.py +65 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/logging.py +12 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/output.py +43 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/core/registry.py +122 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/main.py +69 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/__init__.py +1 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/agent_memory/__init__.py +1 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/agent_memory/client.py +189 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/agent_memory/commands.py +231 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/__init__.py +1 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/apply.py +349 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/client.py +764 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/commands.py +1806 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/config.py +80 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/evidence.py +103 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/exporting.py +260 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/faq_lifecycle.py +376 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/faqs.py +314 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/output.py +194 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/planner.py +401 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/progress.py +134 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/service.py +448 -0
- redis_iris-0.1.0a1/src/redis_iris/cli/services/playbook/skills.py +622 -0
- redis_iris-0.1.0a1/src/redis_iris/context_retriever/__init__.py +32 -0
- redis_iris-0.1.0a1/src/redis_iris/context_retriever/provisioning.py +31 -0
- redis_iris-0.1.0a1/src/redis_iris/context_retriever/results.py +57 -0
- redis_iris-0.1.0a1/src/redis_iris/context_retriever/retriever.py +189 -0
- redis_iris-0.1.0a1/src/redis_iris/context_retriever/settings.py +63 -0
- redis_iris-0.1.0a1/src/redis_iris/errors.py +23 -0
- redis_iris-0.1.0a1/src/redis_iris/integrations/__init__.py +5 -0
- redis_iris-0.1.0a1/src/redis_iris/integrations/langgraph.py +105 -0
- redis_iris-0.1.0a1/src/redis_iris/iris.py +74 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/__init__.py +33 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/_wire.py +68 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/filters.py +11 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/hooks.py +120 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/playbook.py +180 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/settings.py +64 -0
- redis_iris-0.1.0a1/src/redis_iris/playbook/values.py +65 -0
- redis_iris-0.1.0a1/src/redis_iris/py.typed +1 -0
- redis_iris-0.1.0a1/tests/agent_memory/__init__.py +1 -0
- redis_iris-0.1.0a1/tests/agent_memory/test_commands.py +264 -0
- redis_iris-0.1.0a1/tests/integrations/__init__.py +0 -0
- redis_iris-0.1.0a1/tests/integrations/test_langgraph.py +149 -0
- redis_iris-0.1.0a1/tests/playbook/__init__.py +1 -0
- redis_iris-0.1.0a1/tests/playbook/conftest.py +34 -0
- redis_iris-0.1.0a1/tests/playbook/integration/__init__.py +1 -0
- redis_iris-0.1.0a1/tests/playbook/integration/conftest.py +173 -0
- redis_iris-0.1.0a1/tests/playbook/integration/test_cli_lifecycle.py +737 -0
- redis_iris-0.1.0a1/tests/playbook/test_client.py +631 -0
- redis_iris-0.1.0a1/tests/playbook/test_command_values.py +206 -0
- redis_iris-0.1.0a1/tests/playbook/test_commands.py +461 -0
- redis_iris-0.1.0a1/tests/playbook/test_config.py +67 -0
- redis_iris-0.1.0a1/tests/playbook/test_domain_output.py +130 -0
- redis_iris-0.1.0a1/tests/playbook/test_evidence_commands.py +365 -0
- redis_iris-0.1.0a1/tests/playbook/test_exporting.py +345 -0
- redis_iris-0.1.0a1/tests/playbook/test_faqs.py +388 -0
- redis_iris-0.1.0a1/tests/playbook/test_planner_apply.py +334 -0
- redis_iris-0.1.0a1/tests/playbook/test_progress.py +60 -0
- redis_iris-0.1.0a1/tests/playbook/test_proposal_commands.py +244 -0
- redis_iris-0.1.0a1/tests/playbook/test_service_commands.py +336 -0
- redis_iris-0.1.0a1/tests/playbook/test_skills.py +331 -0
- redis_iris-0.1.0a1/tests/test_config.py +58 -0
- redis_iris-0.1.0a1/tests/test_iris.py +570 -0
- redis_iris-0.1.0a1/tests/test_main.py +84 -0
- redis_iris-0.1.0a1/tests/test_output.py +47 -0
- redis_iris-0.1.0a1/tests/test_registry.py +69 -0
- redis_iris-0.1.0a1/uv.lock +3255 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugins": [
|
|
3
|
+
"git-tag",
|
|
4
|
+
"conventional-commits",
|
|
5
|
+
"released"
|
|
6
|
+
],
|
|
7
|
+
"owner": "redis",
|
|
8
|
+
"repo": "redis-iris",
|
|
9
|
+
"onlyPublishWithReleaseLabel": true,
|
|
10
|
+
"labels": [
|
|
11
|
+
{
|
|
12
|
+
"name": "auto:major",
|
|
13
|
+
"changelogTitle": "💥 Breaking Change",
|
|
14
|
+
"description": "Increment the major version when merged",
|
|
15
|
+
"releaseType": "major",
|
|
16
|
+
"color": "#C5000B",
|
|
17
|
+
"overwrite": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "auto:minor",
|
|
21
|
+
"changelogTitle": "🚀 Enhancement",
|
|
22
|
+
"description": "Increment the minor version when merged",
|
|
23
|
+
"releaseType": "minor",
|
|
24
|
+
"color": "#F1A60E",
|
|
25
|
+
"overwrite": true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "auto:patch",
|
|
29
|
+
"changelogTitle": "🐛 Bug Fix",
|
|
30
|
+
"description": "Increment the patch version when merged",
|
|
31
|
+
"releaseType": "patch",
|
|
32
|
+
"color": "#870048",
|
|
33
|
+
"overwrite": true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "auto:skip-release",
|
|
37
|
+
"description": "Preserve the current version when merged",
|
|
38
|
+
"releaseType": "skip",
|
|
39
|
+
"color": "#bf5416",
|
|
40
|
+
"overwrite": true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "auto:release",
|
|
44
|
+
"description": "Create a release when this PR is merged",
|
|
45
|
+
"releaseType": "release",
|
|
46
|
+
"color": "#007f70",
|
|
47
|
+
"overwrite": true
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "auto:internal",
|
|
51
|
+
"changelogTitle": "🏠 Internal",
|
|
52
|
+
"description": "Changes only affect the internal API",
|
|
53
|
+
"releaseType": "none",
|
|
54
|
+
"color": "#696969",
|
|
55
|
+
"overwrite": true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "auto:documentation",
|
|
59
|
+
"changelogTitle": "📝 Documentation",
|
|
60
|
+
"description": "Changes only affect the documentation",
|
|
61
|
+
"releaseType": "none",
|
|
62
|
+
"color": "#cfd3d7",
|
|
63
|
+
"overwrite": true
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "auto:tests",
|
|
67
|
+
"changelogTitle": "🧪 Tests",
|
|
68
|
+
"description": "Add or improve existing tests",
|
|
69
|
+
"releaseType": "none",
|
|
70
|
+
"color": "#ffd3cc",
|
|
71
|
+
"overwrite": true
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "auto:dependencies",
|
|
75
|
+
"changelogTitle": "🔩 Dependency Updates",
|
|
76
|
+
"description": "Update one or more dependencies version",
|
|
77
|
+
"releaseType": "none",
|
|
78
|
+
"color": "#8732bc",
|
|
79
|
+
"overwrite": true
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "auto:ci",
|
|
83
|
+
"changelogTitle": "CI/CD Changes",
|
|
84
|
+
"description": "Updates to CI/CD workflows and processes",
|
|
85
|
+
"releaseType": "none",
|
|
86
|
+
"color": "#E5A3DD",
|
|
87
|
+
"overwrite": true
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Opens a PR here whenever an Iris product SDK publishes a new version to PyPI.
|
|
2
|
+
# Dependabot bumps the exact pin in pyproject.toml and regenerates uv.lock.
|
|
3
|
+
# Scoped to the product SDKs only; one grouped PR per day covers all of them.
|
|
4
|
+
# ponytail: daily polling, not a push from iris-sdks; add a repository_dispatch
|
|
5
|
+
# receiver if same-hour bumps ever matter (releases here are manual anyway).
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: uv
|
|
9
|
+
directory: /
|
|
10
|
+
schedule:
|
|
11
|
+
interval: daily
|
|
12
|
+
allow:
|
|
13
|
+
- dependency-name: redis-agent-*
|
|
14
|
+
- dependency-name: langcache
|
|
15
|
+
- dependency-name: redis-context-retriever
|
|
16
|
+
groups:
|
|
17
|
+
iris-sdks:
|
|
18
|
+
patterns: ["*"]
|
|
19
|
+
# Changelog grouping for the Auto Release workflow; does not trigger a release.
|
|
20
|
+
labels: ["auto:dependencies"]
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
name: Auto Release
|
|
2
|
+
|
|
3
|
+
# BOILERPLATE, NOT YET ACTIVE. Ported from redis-developer/sql-redis so the
|
|
4
|
+
# label-driven release is ready when the alpha series ends. Until then releases
|
|
5
|
+
# are manual through publish.yml, and this workflow runs only on dispatch.
|
|
6
|
+
#
|
|
7
|
+
# To activate: add `push: { branches: [main] }` under `on:`, delete publish.yml,
|
|
8
|
+
# and make sure [project].version is semver (`0.1.0`, not `0.1.0a1`; `auto`
|
|
9
|
+
# bumps semver and cannot parse PEP 440 suffixes).
|
|
10
|
+
#
|
|
11
|
+
# How it works once active: every push to main runs the gate; the release job
|
|
12
|
+
# runs only when the merged PR carries the `auto:release` label. Intuit `auto`
|
|
13
|
+
# picks the bump from the `auto:major` / `auto:minor` / `auto:patch` labels
|
|
14
|
+
# (see .autorc), writes it into pyproject.toml and uv.lock, commits with
|
|
15
|
+
# [skip ci], tags, and writes GitHub release notes. The built distribution is
|
|
16
|
+
# then checked with twine and uploaded to PyPI with REDIS_IRIS_PYPI_TOKEN.
|
|
17
|
+
# `first_release=true` publishes the committed version as-is (bootstrap, recovery).
|
|
18
|
+
|
|
19
|
+
on:
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
inputs:
|
|
22
|
+
first_release:
|
|
23
|
+
description: "Bootstrap: publish the version currently in pyproject.toml. Bypasses the auto:release label gate and skips version bumping. Use only for the first release or manual recovery."
|
|
24
|
+
type: boolean
|
|
25
|
+
default: false
|
|
26
|
+
|
|
27
|
+
permissions:
|
|
28
|
+
contents: write
|
|
29
|
+
issues: write
|
|
30
|
+
pull-requests: write
|
|
31
|
+
|
|
32
|
+
concurrency:
|
|
33
|
+
group: auto-release-${{ github.ref }}
|
|
34
|
+
cancel-in-progress: false
|
|
35
|
+
|
|
36
|
+
env:
|
|
37
|
+
PYTHON_VERSION: "3.11"
|
|
38
|
+
AUTO_VERSION: "11.3.6"
|
|
39
|
+
RELEASE_BOT_NAME: "github-actions[bot]"
|
|
40
|
+
RELEASE_BOT_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com"
|
|
41
|
+
|
|
42
|
+
jobs:
|
|
43
|
+
gate:
|
|
44
|
+
name: Gate on merged PR label
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
# Prevent infinite loops from the bot's "chore(release)" commit.
|
|
47
|
+
if: github.actor != 'github-actions[bot]'
|
|
48
|
+
outputs:
|
|
49
|
+
should_release: ${{ steps.find_pr.outputs.should_release }}
|
|
50
|
+
pr_number: ${{ steps.find_pr.outputs.pr_number }}
|
|
51
|
+
steps:
|
|
52
|
+
- name: Find merged PR and check labels
|
|
53
|
+
id: find_pr
|
|
54
|
+
uses: actions/github-script@v7
|
|
55
|
+
env:
|
|
56
|
+
FIRST_RELEASE: ${{ github.event.inputs.first_release }}
|
|
57
|
+
with:
|
|
58
|
+
script: |
|
|
59
|
+
// Manual bootstrap: bypass the PR label check entirely.
|
|
60
|
+
if (context.eventName === 'workflow_dispatch' && process.env.FIRST_RELEASE === 'true') {
|
|
61
|
+
core.notice('Manual first_release=true; bypassing PR label check.');
|
|
62
|
+
core.setOutput('should_release', 'true');
|
|
63
|
+
core.setOutput('pr_number', '');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { owner, repo } = context.repo;
|
|
67
|
+
const sha = context.sha;
|
|
68
|
+
const maxAttempts = 6;
|
|
69
|
+
let pulls;
|
|
70
|
+
// GitHub can briefly lag in associating a merge commit with its PR, so retry.
|
|
71
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
72
|
+
pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
73
|
+
owner, repo, commit_sha: sha,
|
|
74
|
+
});
|
|
75
|
+
if (pulls.data.length) break;
|
|
76
|
+
if (attempt < maxAttempts) {
|
|
77
|
+
await new Promise((r) => setTimeout(r, 10000));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!pulls.data || !pulls.data.length) {
|
|
81
|
+
core.notice(`No PR associated with ${sha}. Not releasing.`);
|
|
82
|
+
core.setOutput('should_release', 'false');
|
|
83
|
+
core.setOutput('pr_number', '');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const pr = pulls.data.find((p) => p.merged_at && p.base?.ref === 'main') ?? pulls.data[0];
|
|
87
|
+
const labels = (pr.labels || []).map((l) => l.name);
|
|
88
|
+
const should = labels.includes('auto:release');
|
|
89
|
+
core.setOutput('pr_number', String(pr.number));
|
|
90
|
+
core.setOutput('should_release', should ? 'true' : 'false');
|
|
91
|
+
core.notice(`PR #${pr.number} labels: ${labels.join(', ')}`);
|
|
92
|
+
core.notice(`should_release=${should}`);
|
|
93
|
+
|
|
94
|
+
release:
|
|
95
|
+
name: Tag, release, and publish
|
|
96
|
+
runs-on: ubuntu-latest
|
|
97
|
+
needs: gate
|
|
98
|
+
if: needs.gate.outputs.should_release == 'true'
|
|
99
|
+
env:
|
|
100
|
+
# 'true' for manual bootstrap runs; 'false' or empty otherwise.
|
|
101
|
+
FIRST_RELEASE: ${{ github.event.inputs.first_release || 'false' }}
|
|
102
|
+
steps:
|
|
103
|
+
- name: Checkout
|
|
104
|
+
uses: actions/checkout@v4
|
|
105
|
+
with:
|
|
106
|
+
ref: main
|
|
107
|
+
fetch-depth: 0
|
|
108
|
+
fetch-tags: true
|
|
109
|
+
# RELEASE_PAT (a PAT with repo + workflow scopes) lets the bot push to
|
|
110
|
+
# protected branches and trigger other workflows. Falls back to
|
|
111
|
+
# GITHUB_TOKEN for repos without branch protection.
|
|
112
|
+
token: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
|
|
113
|
+
|
|
114
|
+
- name: Install uv
|
|
115
|
+
uses: astral-sh/setup-uv@v6
|
|
116
|
+
with:
|
|
117
|
+
enable-cache: true
|
|
118
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
119
|
+
|
|
120
|
+
- name: Install auto
|
|
121
|
+
run: |
|
|
122
|
+
set -euo pipefail
|
|
123
|
+
curl -L "https://github.com/intuit/auto/releases/download/v${AUTO_VERSION}/auto-linux.gz" -o auto-linux.gz
|
|
124
|
+
gunzip auto-linux.gz
|
|
125
|
+
chmod +x auto-linux
|
|
126
|
+
sudo mv auto-linux /usr/local/bin/auto
|
|
127
|
+
auto --version
|
|
128
|
+
|
|
129
|
+
- name: Check publishing token is configured
|
|
130
|
+
env:
|
|
131
|
+
PYPI_TOKEN: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
|
|
132
|
+
run: |
|
|
133
|
+
if [ -z "$PYPI_TOKEN" ]; then
|
|
134
|
+
echo "::error::Configure the REDIS_IRIS_PYPI_TOKEN Actions secret."
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
- name: Install locked environment
|
|
139
|
+
run: uv sync --locked --all-groups
|
|
140
|
+
|
|
141
|
+
- name: Sanity build (pre-tag)
|
|
142
|
+
run: uv build --no-sources
|
|
143
|
+
|
|
144
|
+
- name: Capture previous tag
|
|
145
|
+
id: previous_tag
|
|
146
|
+
run: |
|
|
147
|
+
set -euo pipefail
|
|
148
|
+
echo "tag=$(git describe --tags --abbrev=0 2>/dev/null || echo '')" >> "$GITHUB_OUTPUT"
|
|
149
|
+
|
|
150
|
+
- name: Resolve next version (auto)
|
|
151
|
+
id: resolve_version
|
|
152
|
+
if: env.FIRST_RELEASE != 'true'
|
|
153
|
+
env:
|
|
154
|
+
GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
|
|
155
|
+
run: |
|
|
156
|
+
set -euo pipefail
|
|
157
|
+
RAW_VERSION="$(auto shipit --name "${RELEASE_BOT_NAME}" --email "${RELEASE_BOT_EMAIL}" --dry-run --quiet | tail -n1 | tr -d '\r')"
|
|
158
|
+
VERSION="${RAW_VERSION#v}"
|
|
159
|
+
if [ -z "$VERSION" ]; then
|
|
160
|
+
echo "Could not resolve release version from auto."
|
|
161
|
+
exit 1
|
|
162
|
+
fi
|
|
163
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
164
|
+
echo "Resolved version: $VERSION"
|
|
165
|
+
|
|
166
|
+
- name: Apply version to pyproject.toml and uv.lock
|
|
167
|
+
if: env.FIRST_RELEASE != 'true'
|
|
168
|
+
run: |
|
|
169
|
+
set -euo pipefail
|
|
170
|
+
VERSION="${{ steps.resolve_version.outputs.version }}"
|
|
171
|
+
sed -i "s/^version = \".*\"$/version = \"${VERSION}\"/" pyproject.toml
|
|
172
|
+
grep '^version = ' pyproject.toml
|
|
173
|
+
# uv.lock records the project's own version; CI syncs with --locked.
|
|
174
|
+
uv lock
|
|
175
|
+
|
|
176
|
+
- name: Commit version bump
|
|
177
|
+
if: env.FIRST_RELEASE != 'true'
|
|
178
|
+
env:
|
|
179
|
+
GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
|
|
180
|
+
run: |
|
|
181
|
+
set -euo pipefail
|
|
182
|
+
if git diff --quiet -- pyproject.toml uv.lock; then
|
|
183
|
+
echo "No version change to commit."
|
|
184
|
+
else
|
|
185
|
+
git config user.name "${RELEASE_BOT_NAME}"
|
|
186
|
+
git config user.email "${RELEASE_BOT_EMAIL}"
|
|
187
|
+
git add pyproject.toml uv.lock
|
|
188
|
+
# [skip ci] avoids re-running this workflow on the bot's own commit.
|
|
189
|
+
git commit -m "chore(release): v${{ steps.resolve_version.outputs.version }} [skip ci]"
|
|
190
|
+
git push origin HEAD:main
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
- name: Read final version from pyproject.toml
|
|
194
|
+
id: final_version
|
|
195
|
+
run: |
|
|
196
|
+
set -euo pipefail
|
|
197
|
+
VERSION="$(grep -E '^version = ' pyproject.toml | head -1 | sed -E 's/version = "([^"]+)".*/\1/')"
|
|
198
|
+
if [ -z "$VERSION" ]; then
|
|
199
|
+
echo "Could not read version from pyproject.toml"
|
|
200
|
+
exit 1
|
|
201
|
+
fi
|
|
202
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
203
|
+
echo "Final version: $VERSION"
|
|
204
|
+
|
|
205
|
+
- name: Capture release commit SHA
|
|
206
|
+
id: release_commit
|
|
207
|
+
run: |
|
|
208
|
+
set -euo pipefail
|
|
209
|
+
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
|
210
|
+
|
|
211
|
+
- name: Create labels (idempotent)
|
|
212
|
+
env:
|
|
213
|
+
GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
|
|
214
|
+
run: auto create-labels
|
|
215
|
+
|
|
216
|
+
- name: Create and push tag
|
|
217
|
+
run: |
|
|
218
|
+
set -euo pipefail
|
|
219
|
+
TAG="v${{ steps.final_version.outputs.version }}"
|
|
220
|
+
TARGET_SHA="${{ steps.release_commit.outputs.sha }}"
|
|
221
|
+
if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
|
|
222
|
+
EXISTING_SHA="$(git rev-list -n1 "$TAG")"
|
|
223
|
+
if [ "$EXISTING_SHA" = "$TARGET_SHA" ]; then
|
|
224
|
+
echo "Tag $TAG already exists at $TARGET_SHA. Skipping."
|
|
225
|
+
exit 0
|
|
226
|
+
fi
|
|
227
|
+
echo "Tag $TAG exists at $EXISTING_SHA but expected $TARGET_SHA."
|
|
228
|
+
exit 1
|
|
229
|
+
fi
|
|
230
|
+
git tag "$TAG" "$TARGET_SHA"
|
|
231
|
+
git push origin "$TAG"
|
|
232
|
+
|
|
233
|
+
- name: Build final artifacts
|
|
234
|
+
run: |
|
|
235
|
+
set -euo pipefail
|
|
236
|
+
rm -rf dist
|
|
237
|
+
uv build --no-sources
|
|
238
|
+
uv run --no-sync twine check --strict dist/*
|
|
239
|
+
|
|
240
|
+
- name: Create GitHub release with auto notes
|
|
241
|
+
env:
|
|
242
|
+
GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
|
|
243
|
+
run: |
|
|
244
|
+
set -euo pipefail
|
|
245
|
+
args=(--to "${{ steps.release_commit.outputs.sha }}" --use-version "v${{ steps.final_version.outputs.version }}")
|
|
246
|
+
if [ -n "${{ steps.previous_tag.outputs.tag }}" ]; then
|
|
247
|
+
args=(--from "${{ steps.previous_tag.outputs.tag }}" "${args[@]}")
|
|
248
|
+
fi
|
|
249
|
+
auto release "${args[@]}"
|
|
250
|
+
gh release upload "v${{ steps.final_version.outputs.version }}" dist/* --clobber
|
|
251
|
+
|
|
252
|
+
- name: Publish to PyPI
|
|
253
|
+
uses: pypa/gh-action-pypi-publish@release/v1 # maintainer-recommended rolling ref: a SHA pin has no prebuilt ghcr image (manifest unknown)
|
|
254
|
+
with:
|
|
255
|
+
user: __token__
|
|
256
|
+
password: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
|
|
257
|
+
attestations: false
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
outputs:
|
|
6
|
+
version:
|
|
7
|
+
description: Validated distribution version
|
|
8
|
+
value: ${{ jobs.build-and-install.outputs.version }}
|
|
9
|
+
prerelease:
|
|
10
|
+
description: Whether the distribution is a prerelease
|
|
11
|
+
value: ${{ jobs.build-and-install.outputs.prerelease }}
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
pull_request:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
# A reusable workflow inherits its caller's github.workflow. Keep this
|
|
19
|
+
# distinct from the publish workflow's concurrency group.
|
|
20
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
21
|
+
cancel-in-progress: true
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
quality:
|
|
28
|
+
name: Quality (Python ${{ matrix.python-version }})
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
timeout-minutes: 10
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
- uses: astral-sh/setup-uv@v6
|
|
38
|
+
with:
|
|
39
|
+
enable-cache: true
|
|
40
|
+
python-version: ${{ matrix.python-version }}
|
|
41
|
+
- run: uv sync --locked --all-groups --python ${{ matrix.python-version }}
|
|
42
|
+
- run: uv run ruff format --check .
|
|
43
|
+
- run: uv run ruff check .
|
|
44
|
+
- run: uv run mypy
|
|
45
|
+
- run: uv run pytest -m "not integration"
|
|
46
|
+
|
|
47
|
+
build-and-install:
|
|
48
|
+
name: Build and install distribution
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
timeout-minutes: 10
|
|
51
|
+
outputs:
|
|
52
|
+
version: ${{ steps.metadata.outputs.version }}
|
|
53
|
+
prerelease: ${{ steps.metadata.outputs.prerelease }}
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v4
|
|
56
|
+
- uses: astral-sh/setup-uv@v6
|
|
57
|
+
with:
|
|
58
|
+
python-version: "3.11"
|
|
59
|
+
- run: uv sync --locked --all-groups
|
|
60
|
+
- name: Validate release metadata
|
|
61
|
+
id: metadata
|
|
62
|
+
run: |
|
|
63
|
+
uv run --locked python - <<'PY'
|
|
64
|
+
import os
|
|
65
|
+
import tomllib
|
|
66
|
+
from packaging.version import Version
|
|
67
|
+
|
|
68
|
+
with open("pyproject.toml", "rb") as source:
|
|
69
|
+
project = tomllib.load(source)["project"]
|
|
70
|
+
version = Version(project["version"])
|
|
71
|
+
assert project["name"] == "redis-iris", "Unexpected distribution name"
|
|
72
|
+
assert str(version) == project["version"], "Use a canonical Python version"
|
|
73
|
+
assert version.local is None, "Local versions cannot be published to PyPI"
|
|
74
|
+
with open(os.environ["GITHUB_OUTPUT"], "a") as output:
|
|
75
|
+
output.write(f"version={version}\n")
|
|
76
|
+
output.write(f"prerelease={str(version.is_prerelease).lower()}\n")
|
|
77
|
+
PY
|
|
78
|
+
- run: uv build --no-sources
|
|
79
|
+
- run: uv run --locked twine check --strict dist/*
|
|
80
|
+
- run: uv venv --python 3.11 /tmp/iris-cli-venv
|
|
81
|
+
- run: uv pip install --python /tmp/iris-cli-venv/bin/python dist/*.whl
|
|
82
|
+
- run: uv pip check --python /tmp/iris-cli-venv/bin/python
|
|
83
|
+
- name: Verify installed distribution version
|
|
84
|
+
env:
|
|
85
|
+
EXPECTED_VERSION: ${{ steps.metadata.outputs.version }}
|
|
86
|
+
run: |
|
|
87
|
+
cd "$RUNNER_TEMP"
|
|
88
|
+
/tmp/iris-cli-venv/bin/python - <<'PY'
|
|
89
|
+
import os
|
|
90
|
+
import subprocess
|
|
91
|
+
from importlib.metadata import version
|
|
92
|
+
assert version("redis-iris") == os.environ["EXPECTED_VERSION"]
|
|
93
|
+
actual = subprocess.check_output(
|
|
94
|
+
["/tmp/iris-cli-venv/bin/iris", "--version"], text=True
|
|
95
|
+
).strip()
|
|
96
|
+
assert actual == f"iris, version {os.environ['EXPECTED_VERSION']}"
|
|
97
|
+
PY
|
|
98
|
+
- run: /tmp/iris-cli-venv/bin/iris --help
|
|
99
|
+
- run: /tmp/iris-cli-venv/bin/iris playbook --help
|
|
100
|
+
- run: /tmp/iris-cli-venv/bin/python -m redis_iris --help
|
|
101
|
+
- run: /tmp/iris-cli-venv/bin/python -m redis_iris.cli --help
|
|
102
|
+
- uses: actions/upload-artifact@v4
|
|
103
|
+
with:
|
|
104
|
+
name: redis-iris-dist
|
|
105
|
+
path: dist/*
|
|
106
|
+
if-no-files-found: error
|
|
107
|
+
overwrite: true
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Deploy docs to GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths: ["docs/**", "mkdocs.yml", "src/redis_iris/**"]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths: ["docs/**", "mkdocs.yml", "src/redis_iris/**"]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: pages-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
DISABLE_MKDOCS_2_WARNING: "true"
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: astral-sh/setup-uv@v6
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.12"
|
|
29
|
+
# Docs tooling only: mkdocstrings reads src/ statically, so product SDKs
|
|
30
|
+
# (including the path-sourced Context Retriever client) are not installed.
|
|
31
|
+
- run: uv sync --only-group docs
|
|
32
|
+
- run: uv run --no-sync mkdocs build --strict
|
|
33
|
+
- uses: actions/upload-pages-artifact@v3
|
|
34
|
+
with:
|
|
35
|
+
path: site
|
|
36
|
+
|
|
37
|
+
deploy:
|
|
38
|
+
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
|
39
|
+
needs: build
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
permissions:
|
|
42
|
+
pages: write
|
|
43
|
+
id-token: write
|
|
44
|
+
environment:
|
|
45
|
+
name: github-pages
|
|
46
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
47
|
+
steps:
|
|
48
|
+
- id: deployment
|
|
49
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Manual integration
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
# The suite creates and deletes shared remote resources. Serialize runs so that
|
|
7
|
+
# two manually requested runs cannot interfere with each other.
|
|
8
|
+
concurrency:
|
|
9
|
+
group: playbook-integration
|
|
10
|
+
cancel-in-progress: false
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
playbook:
|
|
17
|
+
name: Playbook lifecycle
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 30
|
|
20
|
+
environment: playbook-integration
|
|
21
|
+
env:
|
|
22
|
+
IRIS_PLAYBOOK_TEST_CONTROL_URL: ${{ vars.IRIS_PLAYBOOK_TEST_CONTROL_URL }}
|
|
23
|
+
IRIS_PLAYBOOK_TEST_DATA_URL: ${{ vars.IRIS_PLAYBOOK_TEST_DATA_URL }}
|
|
24
|
+
IRIS_PLAYBOOK_TEST_IDENTITY_URL: ${{ vars.IRIS_PLAYBOOK_TEST_IDENTITY_URL }}
|
|
25
|
+
IRIS_PLAYBOOK_TEST_CONTROL_TOKEN: ${{ secrets.IRIS_PLAYBOOK_TEST_CONTROL_TOKEN }}
|
|
26
|
+
IRIS_PLAYBOOK_TEST_IDENTITY_TOKEN: ${{ secrets.IRIS_PLAYBOOK_TEST_IDENTITY_TOKEN }}
|
|
27
|
+
IRIS_PLAYBOOK_TEST_EMBEDDING_PROVIDER: ${{ vars.IRIS_PLAYBOOK_TEST_EMBEDDING_PROVIDER }}
|
|
28
|
+
IRIS_PLAYBOOK_TEST_EMBEDDING_MODEL: ${{ vars.IRIS_PLAYBOOK_TEST_EMBEDDING_MODEL }}
|
|
29
|
+
IRIS_PLAYBOOK_TEST_EMBEDDING_DIMENSIONS: ${{ vars.IRIS_PLAYBOOK_TEST_EMBEDDING_DIMENSIONS }}
|
|
30
|
+
steps:
|
|
31
|
+
- name: Validate integration configuration
|
|
32
|
+
shell: bash
|
|
33
|
+
run: |
|
|
34
|
+
required=(
|
|
35
|
+
IRIS_PLAYBOOK_TEST_CONTROL_URL
|
|
36
|
+
IRIS_PLAYBOOK_TEST_DATA_URL
|
|
37
|
+
IRIS_PLAYBOOK_TEST_IDENTITY_URL
|
|
38
|
+
IRIS_PLAYBOOK_TEST_CONTROL_TOKEN
|
|
39
|
+
IRIS_PLAYBOOK_TEST_IDENTITY_TOKEN
|
|
40
|
+
IRIS_PLAYBOOK_TEST_EMBEDDING_PROVIDER
|
|
41
|
+
IRIS_PLAYBOOK_TEST_EMBEDDING_MODEL
|
|
42
|
+
IRIS_PLAYBOOK_TEST_EMBEDDING_DIMENSIONS
|
|
43
|
+
)
|
|
44
|
+
missing=()
|
|
45
|
+
for name in "${required[@]}"; do
|
|
46
|
+
if [[ -z "${!name:-}" ]]; then
|
|
47
|
+
missing+=("$name")
|
|
48
|
+
fi
|
|
49
|
+
done
|
|
50
|
+
if (( ${#missing[@]} )); then
|
|
51
|
+
printf 'Missing integration configuration: %s\n' "${missing[*]}" >&2
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: astral-sh/setup-uv@v6
|
|
56
|
+
with:
|
|
57
|
+
enable-cache: true
|
|
58
|
+
python-version: "3.13"
|
|
59
|
+
- run: uv sync --locked --all-groups --python 3.13
|
|
60
|
+
- run: task test:integration
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: Publish Redis Iris
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: publish-redis-iris
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
check:
|
|
15
|
+
if: github.ref == 'refs/heads/main'
|
|
16
|
+
uses: ./.github/workflows/ci.yml
|
|
17
|
+
|
|
18
|
+
publish:
|
|
19
|
+
name: Publish to PyPI
|
|
20
|
+
needs: check
|
|
21
|
+
if: github.ref == 'refs/heads/main'
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 10
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
with:
|
|
27
|
+
ref: ${{ github.sha }}
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
persist-credentials: false
|
|
30
|
+
- name: Reject an existing release tag
|
|
31
|
+
env:
|
|
32
|
+
RELEASE_TAG: v${{ needs.check.outputs.version }}
|
|
33
|
+
run: |
|
|
34
|
+
if git show-ref --verify --quiet "refs/tags/$RELEASE_TAG"; then
|
|
35
|
+
echo "::error::Release tag already exists. Bump the version before publishing."
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
- name: Check publishing token is configured
|
|
39
|
+
env:
|
|
40
|
+
PYPI_TOKEN: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
|
|
41
|
+
run: |
|
|
42
|
+
if [ -z "$PYPI_TOKEN" ]; then
|
|
43
|
+
echo "::error::Configure the REDIS_IRIS_PYPI_TOKEN Actions secret."
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
- uses: actions/download-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: redis-iris-dist
|
|
49
|
+
path: dist
|
|
50
|
+
- name: Publish tested distributions
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1 # maintainer-recommended rolling ref: a SHA pin has no prebuilt ghcr image (manifest unknown)
|
|
52
|
+
with:
|
|
53
|
+
user: __token__
|
|
54
|
+
password: ${{ secrets.REDIS_IRIS_PYPI_TOKEN }}
|
|
55
|
+
attestations: false
|
|
56
|
+
|
|
57
|
+
release:
|
|
58
|
+
name: Create GitHub Release
|
|
59
|
+
needs: [check, publish]
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
timeout-minutes: 5
|
|
62
|
+
permissions:
|
|
63
|
+
contents: write
|
|
64
|
+
steps:
|
|
65
|
+
- uses: actions/download-artifact@v4
|
|
66
|
+
with:
|
|
67
|
+
name: redis-iris-dist
|
|
68
|
+
path: dist
|
|
69
|
+
- name: Create tag and release at the tested commit
|
|
70
|
+
env:
|
|
71
|
+
GH_TOKEN: ${{ github.token }}
|
|
72
|
+
GH_REPO: ${{ github.repository }}
|
|
73
|
+
RELEASE_TAG: v${{ needs.check.outputs.version }}
|
|
74
|
+
PRERELEASE: ${{ needs.check.outputs.prerelease }}
|
|
75
|
+
RELEASE_COMMIT: ${{ github.sha }}
|
|
76
|
+
run: |
|
|
77
|
+
args=(--repo "$GH_REPO" --target "$RELEASE_COMMIT"
|
|
78
|
+
--title "Redis Iris $RELEASE_TAG" --generate-notes)
|
|
79
|
+
if [ "$PRERELEASE" = true ]; then
|
|
80
|
+
args+=(--prerelease --latest=false)
|
|
81
|
+
fi
|
|
82
|
+
gh release create "$RELEASE_TAG" dist/* "${args[@]}"
|