diff --git a/.github/workflows/autocomment_jira_link.yaml b/.github/workflows/autocomment_jira_link.yaml deleted file mode 100644 index fc9d12dfc8..0000000000 --- a/.github/workflows/autocomment_jira_link.yaml +++ /dev/null @@ -1,50 +0,0 @@ -name: autocomment_jira_link - -on: - pull_request: - types: - - opened -permissions: - pull-requests: write - contents: read - -jobs: - auto-comment: - runs-on: ubuntu-latest - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: Create Comment - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - REPO: ${{ github.repository }} - BRANCH_NAME: ${{ github.event.pull_request.head.ref }} - run: | - generate_post_data() - { - cat </dev/null - - printf '%s\n' 'Comment written!' - fi \ No newline at end of file diff --git a/.github/workflows/autocomment_staging_links.yaml b/.github/workflows/autocomment_staging_links.yaml deleted file mode 100644 index 0d75c5cfed..0000000000 --- a/.github/workflows/autocomment_staging_links.yaml +++ /dev/null @@ -1,171 +0,0 @@ -name: autocomment_staging_links - -on: - pull_request: - paths: - - 'content/**' - types: - - opened - - synchronize -permissions: - pull-requests: write - contents: read - -jobs: - auto-comment: - runs-on: ubuntu-latest - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: 'Install jq' - run: sudo apt-get install jq - - - name: Create Comment - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - BRANCH_NAME: ${{ github.head_ref }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_REPOSITORY: ${{ github.repository }} - run: | - set -e - - CREATE_COMMENT_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" - UPDATE_COMMENT_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/comments" - FILES_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files" - - # Check if comment already exists - EXISTING_COMMENT_JSON=$(curl -Ls \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -H "Authorization: Bearer ${GITHUB_TOKEN}" \ - $CREATE_COMMENT_URL \ - | jq -r '.[] | select(.user.login == "github-actions[bot]" and ((.body // "") | contains("Staging links:")))' - ) - EXISTING_COMMENT_ID=$(jq -r '.id' <<<"$EXISTING_COMMENT_JSON") - EXISTING_COMMENT=$(jq -r '.body' <<<"$EXISTING_COMMENT_JSON") - - # Get all changed md files - CHANGED_MD_FILES=$(curl -Ls \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -H "Authorization: Bearer ${GITHUB_TOKEN}" \ - $FILES_URL \ - | jq -r --arg prefix $BRANCH_NAME/ '.[] | select(((.filename | test("content/(?!.*embed).*\\.md")) and .status != "removed")) | ($prefix + .filename)' \ - | sed -E -e 's|(^[^/]+/)([^/]+/)|\1|' -e 's|^|https://redis.io/docs/staging/|' -e 's|(\/_?index)?\.md|\/|' \ - | sort \ - | uniq) - - # Get all changed image files - CHANGED_IMAGE_FILES=$(curl -Ls \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -H "Authorization: Bearer ${GITHUB_TOKEN}" \ - $FILES_URL \ - | jq -r '.[] | select(.filename | test("^static/images\/.+(.png|.svg|.gif|.)")) | .filename | sub("^static/";"")') - - # Get all changed embeds files - CHANGED_EMBED_FILES=$(curl -Ls \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -H "Authorization: Bearer ${GITHUB_TOKEN}" \ - $FILES_URL \ - | jq -r '.[] | select(.filename | test("^content/embeds\/.+.md")) | .filename | split("/")[-1]') - - if [[ -n "$CHANGED_IMAGE_FILES" ]] - then - # For each image, work out in which README it is present - MD_FILES_WITH_IMAGE=() - for CHANGED_IMAGE_FILE in "${CHANGED_IMAGE_FILES[@]}"; do - MD_FILE_WITH_IMAGE=$(grep -ro "$CHANGED_IMAGE_FILE" content \ - | sed -E -e 's|:.+||' -e "s|^content/|https://redis.io/docs/staging/$BRANCH_NAME/|" -e 's|(_?index)?\.md||' \ - | grep -v "https://redis.io/docs/staging/$BRANCH_NAME/embeds/" \ - | sort \ - | uniq) - MD_FILES_WITH_IMAGE+=($MD_FILE_WITH_IMAGE) - done - CHANGED_MD_FILES=$(printf "%s\n" "${CHANGED_MD_FILES}" "${MD_FILES_WITH_IMAGE[@]}" \ - | sort \ - | uniq) - fi - - if [[ -n "$CHANGED_EMBED_FILES" ]] - then - # For each embed, work out in which README it is present - MD_FILES_WITH_EMBED=() - for CHANGED_EMBED_FILE in "${CHANGED_EMBED_FILES[@]}"; do - MD_FILE_WITH_EMBED=$(grep -ro "< embed-md \"${CHANGED_EMBED_FILE}\" >" content \ - | sed -E -e 's|:.+||' -e "s|^content/|https://redis.io/docs/staging/$BRANCH_NAME/|" -e 's|(_?index)?\.md||' \ - | sort \ - | uniq) - MD_FILES_WITH_EMBED+=($MD_FILE_WITH_EMBED) - done - CHANGED_MD_FILES=$(printf "%s\n" "${CHANGED_MD_FILES}" "${MD_FILES_WITH_EMBED[@]}" \ - | sort \ - | uniq) - fi - - CHANGED_MD_FILES=$(printf "%s\n" "${CHANGED_MD_FILES}" \ - | xargs \ - | sed 's/ /
/g') - - if [[ -z "$CHANGED_MD_FILES" ]] - then - if [[ -z "$EXISTING_COMMENT_ID" ]] - then - printf '%s\n' 'Nothing to do!' - exit 0 - else - # If a comment already exists but there are no changed files in the PR anymore, delete the comment - curl -Ls \ - -X DELETE \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${UPDATE_COMMENT_URL}/${EXISTING_COMMENT_ID}" - printf '%s\n' 'Comment deleted!' - exit 0 - fi - fi - - COMMENT="Staging links:
$CHANGED_MD_FILES" - - printf '%s %s\n' 'Writing comment: ' "$COMMENT" - - generate_post_data() - { - cat </dev/null - - printf '%s\n' 'Comment updated!' - else - printf '%s\n' 'Nothing changed!' - fi - else - # Write comment on pull request - curl -Ls \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - $CREATE_COMMENT_URL \ - --data "$(generate_post_data)" 1>/dev/null - - printf '%s\n' 'Comment written!' - fi \ No newline at end of file diff --git a/.github/workflows/cleanup_pr_folders.yaml b/.github/workflows/cleanup_pr_folders.yaml deleted file mode 100644 index cbd89f55a5..0000000000 --- a/.github/workflows/cleanup_pr_folders.yaml +++ /dev/null @@ -1,77 +0,0 @@ -name: cleanup_pr_folders - -on: - pull_request: - types: - - closed - -jobs: - staging: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - env: - STAGING_BUCKET: docs-staging-learn-redis-com - STAGING_PROJECT_ID: ${{ secrets.GCP_PROJECT_STAGING }} - STAGING_SERVICE_ACCOUNT: ${{ secrets.STAGING_SERVICE_ACCOUNT }} - STAGING_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.STAGING_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.STAGING_PROJECT_ID }}' - service_account: '${{ env.STAGING_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.STAGING_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.STAGING_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Remove pull request staging folder - env: - BRANCH_TO_CLEANUP: ${{ github.event.pull_request.head.ref }} - run: | - if gsutil -q stat "gs://${STAGING_BUCKET}/staging/${BRANCH_TO_CLEANUP}/*"; then - gsutil -q -m rm -r "gs://${STAGING_BUCKET}/staging/${BRANCH_TO_CLEANUP}/*" - echo "Removed gs://${STAGING_BUCKET}/staging/${BRANCH_TO_CLEANUP}" - fi - - prod: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - env: - PROD_BUCKET: docs-prod-learn-redis-com - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Remove pull request staging folder - env: - BRANCH_TO_CLEANUP: ${{ github.event.pull_request.head.ref }} - run: | - if gsutil -q stat "gs://${PROD_BUCKET}/staging/${BRANCH_TO_CLEANUP}/*"; then - gsutil -q -m rm -r "gs://${PROD_BUCKET}/staging/${BRANCH_TO_CLEANUP}/*" - echo "Removed gs://${PROD_BUCKET}/staging/${BRANCH_TO_CLEANUP}" - fi \ No newline at end of file diff --git a/.github/workflows/k8s_apis_sync.yaml b/.github/workflows/k8s_apis_sync.yaml deleted file mode 100644 index 55f516a625..0000000000 --- a/.github/workflows/k8s_apis_sync.yaml +++ /dev/null @@ -1,282 +0,0 @@ -name: k8s_apis_sync - -on: - workflow_dispatch: - inputs: - release: - type: string - required: true - description: '' - bucket_folder: - type: string - required: true - description: '' - -jobs: - k8s_apis_sync: - runs-on: ubuntu-latest - permissions: - id-token: write - contents: write - pull-requests: write - actions: write - steps: - - name: Generate a token - id: generate-token - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.DOCS_APP_ID }} - private-key: ${{ secrets.DOCS_APP_PRIVATE_KEY }} - - - name: 'Checkout' - uses: actions/checkout@v3 - with: - token: ${{ steps.generate-token.outputs.token }} - - - name: 'Install crdoc' - run: |- - curl -LO https://github.com/fybrik/crdoc/releases/download/v0.6.3/crdoc_Linux_x86_64.tar.gz - tar -xvzf crdoc_Linux_x86_64.tar.gz - sudo mv crdoc /bin/crdoc - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: arn:aws:iam::022044324644:role/GitHubRedisDocsS3Access - aws-region: us-east-1 - - - name: 'Fetch release' - env: - RELEASE: ${{ github.event.inputs.release }} - BUCKET_FOLDER: ${{ github.event.inputs.bucket_folder }} - run: |- - aws s3 cp "s3://redislabs-k8s/${BUCKET_FOLDER}/redis-enterprise-operator-${RELEASE}.tar.gz" . - - tar xf "redis-enterprise-operator-${RELEASE}.tar.gz" - - - name: 'Generate READMEs' - run: |- - mkdir artifacts - mkdir templates - cp content/operate/kubernetes/reference/api/kubernetes-api-reference-template.tmpl templates/template.tmpl - - crdoc --resources crds/reaadb_crd.yaml --output artifacts/redis_enterprise_active_active_database_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseActiveActiveDatabase\./### /g' artifacts/redis_enterprise_active_active_database_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterpriseactiveactivedatabase/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_active_active_database_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_active_active_database_api.md - - crdoc --resources crds/rec_crd.yaml --output artifacts/redis_enterprise_cluster_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseCluster\./### /g' artifacts/redis_enterprise_cluster_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterprisecluster/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_cluster_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_cluster_api.md - - crdoc --resources crds/redb_crd.yaml --output artifacts/redis_enterprise_database_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseDatabase\./### /g' artifacts/redis_enterprise_database_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterprisedatabase/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_database_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_database_api.md - - crdoc --resources crds/rerc_crd.yaml --output artifacts/redis_enterprise_remote_cluster_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseRemoteCluster\./### /g' artifacts/redis_enterprise_remote_cluster_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterpriseremotecluster/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_remote_cluster_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_remote_cluster_api.md - - crdoc --resources crds/reacl_crd.yaml --output artifacts/redis_enterprise_acl_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseACL\./### /g' artifacts/redis_enterprise_acl_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterpriseacl/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_acl_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_acl_api.md - - crdoc --resources crds/recrole_crd.yaml --output artifacts/redis_enterprise_cluster_role_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseClusterRole\./### /g' artifacts/redis_enterprise_cluster_role_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterpriseclusterrole/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_cluster_role_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_cluster_role_api.md - - crdoc --resources crds/recrolebinding_crd.yaml --output artifacts/redis_enterprise_cluster_role_binding_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseClusterRoleBinding\./### /g' artifacts/redis_enterprise_cluster_role_binding_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterpriseclusterrolebinding/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_cluster_role_binding_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_cluster_role_binding_api.md - - crdoc --resources crds/redbrole_crd.yaml --output artifacts/redis_enterprise_database_role_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseDatabaseRole\./### /g' artifacts/redis_enterprise_database_role_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterprisedatabaserole/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_database_role_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_database_role_api.md - - crdoc --resources crds/redbrolebinding_crd.yaml --output artifacts/redis_enterprise_database_role_binding_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseDatabaseRoleBinding\./### /g' artifacts/redis_enterprise_database_role_binding_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterprisedatabaserolebinding/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_database_role_binding_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_database_role_binding_api.md - - crdoc --resources crds/reuser_crd.yaml --output artifacts/redis_enterprise_user_api.md --template templates/template.tmpl - sed -E -i 's/^### RedisEnterpriseUser\./### /g' artifacts/redis_enterprise_user_api.md - sed -E -i 's/^\[↩ Parent\]\(#redisenterpriseuser/\[↩ Parent\]\(#/g' artifacts/redis_enterprise_user_api.md - sed -E -i 's/ _tmp.md && mv _tmp.md artifacts/redis_enterprise_user_api.md - - - name: 'Remove fields without description' - run: |- - file="artifacts/redis_enterprise_cluster_api.md" - empty_fields_file="content/operate/kubernetes/reference/api/redis_enterprise_cluster_empty_fields" - - # Read empty fields and process them - while IFS= read -r field; do - # Skip empty lines and comments - [[ -z "$field" || "$field" =~ ^# ]] && continue - - # Convert field path to section header pattern - section_pattern="${field}" - - # Remove subsections that go deeper than [index] level - # Keep: spec.extraEnvVars - # Keep: spec.extraEnvVars[index] - # Remove: spec.extraEnvVars[index].valueFrom - # Remove: spec.extraEnvVars[index].valueFrom.fieldRef - awk -v base_pattern="${section_pattern}" ' - BEGIN { skip = 0 } - /^### / { - # Check if this line matches a pattern we want to remove - section = $0 - gsub(/^### /, "", section) - - # If it starts with our base pattern - if (index(section, base_pattern) == 1) { - remainder = substr(section, length(base_pattern) + 1) - - # If remainder is empty, keep it (main section) - if (remainder == "") { - skip = 0 - } - # If remainder is just [index], keep it - else if (remainder == "[index]") { - skip = 0 - } - # If remainder starts with [index]. (has more after [index]), remove it - else if (index(remainder, "[index].") == 1) { - skip = 1 - next - } - # If remainder starts with . (direct subsection), remove it - else if (index(remainder, ".") == 1) { - skip = 1 - next - } - # If remainder starts with []. (direct subsection), remove it - else if (index(remainder, "[].") == 1) { - skip = 1 - next - } - # Otherwise keep it - else { - skip = 0 - } - } else { - # Different section, stop skipping - skip = 0 - } - } - - skip == 0 { print } - ' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" - - done < "$empty_fields_file" - - - name: 'Fix link titles' - run: |- - sed -E -i 's/linkTitle: RedisEnterpriseActiveActiveDatabase API Reference/linkTitle: REAADB API/g' artifacts/redis_enterprise_active_active_database_api.md - sed -E -i 's/linkTitle: RedisEnterpriseCluster API Reference/linkTitle: REC API/g' artifacts/redis_enterprise_cluster_api.md - sed -E -i 's/linkTitle: RedisEnterpriseDatabase API Reference/linkTitle: REDB API/g' artifacts/redis_enterprise_database_api.md - sed -E -i 's/linkTitle: RedisEnterpriseRemoteCluster API Reference/linkTitle: RERC API/g' artifacts/redis_enterprise_remote_cluster_api.md - sed -E -i 's/linkTitle: RedisEnterpriseACL API Reference/linkTitle: REACL API/g' artifacts/redis_enterprise_acl_api.md - sed -E -i 's/linkTitle: RedisEnterpriseClusterRole API Reference/linkTitle: RECROLE API/g' artifacts/redis_enterprise_cluster_role_api.md - sed -E -i 's/linkTitle: RedisEnterpriseClusterRoleBinding API Reference/linkTitle: RECROLEBINDING API/g' artifacts/redis_enterprise_cluster_role_binding_api.md - sed -E -i 's/linkTitle: RedisEnterpriseDatabaseRole API Reference/linkTitle: REDBROLE API/g' artifacts/redis_enterprise_database_role_api.md - sed -E -i 's/linkTitle: RedisEnterpriseDatabaseRoleBinding API Reference/linkTitle: REDBROLEBINDING API/g' artifacts/redis_enterprise_database_role_binding_api.md - sed -E -i 's/linkTitle: RedisEnterpriseUser API Reference/linkTitle: REUSER API/g' artifacts/redis_enterprise_user_api.md - - - name: 'Generate YAML snippets' - run: |- - function formatYamlSnippet() { - cat > "$2" << EOL - \`\`\`yaml - $(cat $1) - \`\`\` - EOL - } - - formatYamlSnippet admission-service.yaml content/embeds/k8s/admission-service.md - formatYamlSnippet admission/webhook.yaml content/embeds/k8s/admission_webhook.md - formatYamlSnippet examples/v1/rec.yaml content/embeds/k8s/rec.md - formatYamlSnippet examples/v1alpha1/reaadb.yaml content/embeds/k8s/reaadb.md - formatYamlSnippet examples/v1alpha1/redb.yaml content/embeds/k8s/redb.md - formatYamlSnippet examples/v1alpha1/rerc.yaml content/embeds/k8s/rerc.md - formatYamlSnippet log_collector/log_collector_role_all_mode.yaml content/embeds/k8s/log_collector_role_all_mode.md - formatYamlSnippet log_collector/log_collector_role_restricted_mode.yaml content/embeds/k8s/log_collector_role_restricted_mode.md - formatYamlSnippet multi-namespace-redb/operator_cluster_role_binding.yaml content/embeds/k8s/multi-ns_operator_cluster_role_binding.md - formatYamlSnippet multi-namespace-redb/operator_cluster_role.yaml content/embeds/k8s/multi-ns_operator_cluster_role.md - formatYamlSnippet multi-namespace-redb/role_binding.yaml content/embeds/k8s/multi-ns_role_binding.md - formatYamlSnippet multi-namespace-redb/role.yaml content/embeds/k8s/multi-ns_role.md - formatYamlSnippet openshift/admission-service.yaml content/embeds/k8s/openshift_admission-service.md - formatYamlSnippet openshift/rec_rhel.yaml content/embeds/k8s/openshift_rec.md - formatYamlSnippet openshift/role_binding.yaml content/embeds/k8s/openshift_role_binding.md - formatYamlSnippet openshift/role.yaml content/embeds/k8s/openshift_role.md - formatYamlSnippet openshift/scc.yaml content/embeds/k8s/openshift_scc.md - formatYamlSnippet openshift/service_account.yaml content/embeds/k8s/openshift_service_account.md - formatYamlSnippet rack_awareness/rack_aware_cluster_role_binding.yaml content/embeds/k8s/rack_aware_cluster_role_binding.md - formatYamlSnippet rack_awareness/rack_aware_cluster_role.yaml content/embeds/k8s/rack_aware_cluster_role.md - formatYamlSnippet rack_awareness/rack_aware_rec.yaml content/embeds/k8s/rack_aware_rec.md - formatYamlSnippet role_binding.yaml content/embeds/k8s/role_binding.md - formatYamlSnippet role.yaml content/embeds/k8s/role.md - formatYamlSnippet service_account.yaml content/embeds/k8s/service_account.md - - - name: 'Send pull request' - env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - RELEASE: ${{ github.event.inputs.release }} - run: |- - BRANCH="k8s_apis_docs_${RELEASE}" - - # Setup git email and username - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config user.name "github-actions[bot]" - - git checkout -b "${BRANCH}" - - cp artifacts/redis_enterprise_active_active_database_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_cluster_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_database_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_remote_cluster_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_acl_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_cluster_role_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_cluster_role_binding_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_database_role_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_database_role_binding_api.md content/operate/kubernetes/reference/api/ - cp artifacts/redis_enterprise_user_api.md content/operate/kubernetes/reference/api/ - - git add content/operate/kubernetes/reference/api/ - git add content/embeds/k8s/ - - git commit -m "k8s api docs ${RELEASE}" - git push origin "${BRANCH}" - - gh pr create \ - --body "k8s api docs ${RELEASE}" \ - --title "k8s api docs ${RELEASE}" \ - --head "$BRANCH" \ - --base "main" \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 5ea69b01af..0000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,793 +0,0 @@ -name: build_docs - -on: - push: - branches: - - '**' - -env: - HUGO_VERSION: 0.143.1 - BUCKET: docs-prod-learn-redis-com - -jobs: - # Discover versions and build the latest docs - setup_and_build_latest: - name: Setup and build latest docs - runs-on: ubuntu-latest - permissions: - contents: 'read' - outputs: - kubernetes_versions: ${{ steps.discover.outputs.kubernetes_versions }} - rs_versions: ${{ steps.discover.outputs.rs_versions }} - rdi_versions: ${{ steps.discover.outputs.rdi_versions }} - redisvl_versions: ${{ steps.discover.outputs.redisvl_versions }} - hugo_root_path: ${{ steps.set-paths.outputs.hugo_root_path }} - bucket_path: ${{ steps.set-paths.outputs.bucket_path }} - - steps: - - name: Free up disk space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - - - name: Validate the branch name - env: - BRANCH_NAME: ${{ github.ref_name }} - run: | - if [[ "$BRANCH_NAME" =~ ^[a-zA-Z0-9_.-]+$ ]]; then - echo "The branch name $BRANCH_NAME is valid." - else - echo "ERROR: Invalid branch name $BRANCH_NAME!" - exit 1 - fi - - - name: Install Hugo - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Check the branch out - uses: actions/checkout@v4 - - - name: Set paths - id: set-paths - run: | - if [[ "${{ github.ref_name }}" == "main" ]]; then - echo "hugo_root_path=docs/staging/dev" >> $GITHUB_OUTPUT - echo "bucket_path=staging/dev" >> $GITHUB_OUTPUT - elif [[ "${{ github.ref_name }}" == "latest" ]]; then - echo "hugo_root_path=docs/latest" >> $GITHUB_OUTPUT - echo "bucket_path=latest" >> $GITHUB_OUTPUT - elif [[ "${{ endsWith(github.ref_name, '-build') }}" == "true" ]]; then - path=$(echo "docs/version/${{ github.ref_name }}" | sed 's/-build$//') - bucket=$(echo "version/${{ github.ref_name }}" | sed 's/-build$//') - echo "hugo_root_path=${path}" >> $GITHUB_OUTPUT - echo "bucket_path=${bucket}" >> $GITHUB_OUTPUT - else - echo "hugo_root_path=docs/staging/${{ github.ref_name }}" >> $GITHUB_OUTPUT - echo "bucket_path=staging/${{ github.ref_name }}" >> $GITHUB_OUTPUT - fi - - - name: Discover versions - id: discover - run: | - kubernetes_versions=$(find content/operate/kubernetes/ -maxdepth 1 -type d -regex ".*[0-9-]" | awk -F/ '{print $NF}' | jq -R -s -c 'split("\n") | map(select(length > 0))') - rs_versions=$(find content/operate/rs/ -maxdepth 1 -type d -regex ".*[0-9-]" | awk -F/ '{print $NF}' | jq -R -s -c 'split("\n") | map(select(length > 0))') - rdi_versions=$(find content/integrate/redis-data-integration/ -maxdepth 1 -type d -regex ".*[0-9-]" | awk -F/ '{print $NF}' | jq -R -s -c 'split("\n") | map(select(length > 0))') - redisvl_versions=$(find content/develop/ai/redisvl/ -maxdepth 1 -type d -regex ".*[0-9-]" | awk -F/ '{print $NF}' | jq -R -s -c 'split("\n") | map(select(length > 0))') - - echo "kubernetes_versions=${kubernetes_versions}" >> $GITHUB_OUTPUT - echo "rs_versions=${rs_versions}" >> $GITHUB_OUTPUT - echo "rdi_versions=${rdi_versions}" >> $GITHUB_OUTPUT - echo "redisvl_versions=${redisvl_versions}" >> $GITHUB_OUTPUT - - echo "Discovered versions:" - echo " Kubernetes: ${kubernetes_versions}" - echo " RS: ${rs_versions}" - echo " RDI: ${rdi_versions}" - echo " RedisVL: ${redisvl_versions}" - - - name: Install dependencies - run: make deps - - - name: Build latest (without versioned content) - run: | - set -x - hugo_root_path="${{ steps.set-paths.outputs.hugo_root_path }}" - sed -i "s#baseURL = \"https://redis.io\"#baseURL = \"https://redis.io/${hugo_root_path}\"#g" config.toml - - # Remove all versioned directories for the latest build - kubernetes_versions='${{ steps.discover.outputs.kubernetes_versions }}' - rs_versions='${{ steps.discover.outputs.rs_versions }}' - rdi_versions='${{ steps.discover.outputs.rdi_versions }}' - redisvl_versions='${{ steps.discover.outputs.redisvl_versions }}' - - for version in $(echo "$kubernetes_versions" | jq -r '.[]'); do - rm -rf "content/operate/kubernetes/${version}" - done - for version in $(echo "$rs_versions" | jq -r '.[]'); do - rm -rf "content/operate/rs/${version}" - done - for version in $(echo "$rdi_versions" | jq -r '.[]'); do - rm -rf "content/integrate/redis-data-integration/${version}" - done - for version in $(echo "$redisvl_versions" | jq -r '.[]'); do - rm -rf "content/develop/ai/redisvl/${version}" - done - - # Create version files for docs-nav.html dropdowns - echo "$kubernetes_versions" | jq -r '.[]' > kubernetes-versions - echo "$rs_versions" | jq -r '.[]' > rs-versions - echo "$rdi_versions" | jq -r '.[]' > rdi-versions - echo "$redisvl_versions" | jq -r '.[]' > redisvl-versions - - make all - - - name: List client examples - run: ls "${{ github.workspace }}/examples" - - - name: List files to be published - run: ls "${{ github.workspace }}/public" - - - name: Upload latest artifact - uses: actions/upload-artifact@v4 - with: - name: build-latest - path: public/ - retention-days: 1 - - # Build Kubernetes versions in parallel - build_kubernetes: - name: Build Kubernetes ${{ matrix.version }} - needs: setup_and_build_latest - if: ${{ needs.setup_and_build_latest.outputs.kubernetes_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.kubernetes_versions) }} - - steps: - - name: Free up disk space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - - - name: Install Hugo - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Check the branch out - uses: actions/checkout@v4 - - - name: Install dependencies - run: make deps - - - name: Generate components - run: make components - - - name: Build Kubernetes ${{ matrix.version }} - run: | - set -x - version="${{ matrix.version }}" - hugo_root_path="${{ needs.setup_and_build_latest.outputs.hugo_root_path }}" - - sed -i "s#baseURL = \"https://redis.io\"#baseURL = \"https://redis.io/${hugo_root_path}\"#g" config.toml - - # Remove all other kubernetes versions - kubernetes_versions='${{ needs.setup_and_build_latest.outputs.kubernetes_versions }}' - for v in $(echo "$kubernetes_versions" | jq -r '.[]'); do - if [[ "$v" != "$version" ]]; then - rm -rf "content/operate/kubernetes/${v}" - fi - done - - # relrefs should not include version - find "content/operate/kubernetes/${version}" -type f | while read file; do - awk '{gsub(/\(\{\{< ?relref "\/operate\/kubernetes\/'"${version}"'/, "({{< relref \"/operate/kubernetes") }1' "$file" > tmpfile && mv tmpfile "$file" - done - - rsync -a --delete-after "content/operate/kubernetes/${version}"/ content/operate/kubernetes/ - sed -i 's/id="versionSelectorKubernetesValue" class="version-selector-control">latest/id="versionSelectorKubernetesValue" class="version-selector-control">v'"${version}"'/' layouts/partials/docs-nav.html - sed -i 's/linkTitle: '"${version}"'/linkTitle: Redis for Kubernetes/' content/operate/kubernetes/_index.md - - # inject replace command in meta-links - sed -i "12i \{\{ \$gh_path = replaceRE \`\^operate\/kubernetes\/\` \"operate\/kubernetes\/${version}\/\" \$gh_path }}" layouts/partials/meta-links.html - - # Create version files for docs-nav.html dropdowns - echo '${{ needs.setup_and_build_latest.outputs.kubernetes_versions }}' | jq -r '.[]' > kubernetes-versions - echo '${{ needs.setup_and_build_latest.outputs.rs_versions }}' | jq -r '.[]' > rs-versions - echo '${{ needs.setup_and_build_latest.outputs.rdi_versions }}' | jq -r '.[]' > rdi-versions - echo '${{ needs.setup_and_build_latest.outputs.redisvl_versions }}' | jq -r '.[]' > redisvl-versions - - hugo -d "output" - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: build-kubernetes-${{ matrix.version }} - path: output/ - retention-days: 1 - - # Build RS versions in parallel - build_rs: - name: Build RS ${{ matrix.version }} - needs: setup_and_build_latest - if: ${{ needs.setup_and_build_latest.outputs.rs_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.rs_versions) }} - - steps: - - name: Free up disk space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - - - name: Install Hugo - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Check the branch out - uses: actions/checkout@v4 - - - name: Install dependencies - run: make deps - - - name: Generate components - run: make components - - - name: Build RS ${{ matrix.version }} - run: | - set -x - version="${{ matrix.version }}" - hugo_root_path="${{ needs.setup_and_build_latest.outputs.hugo_root_path }}" - - sed -i "s#baseURL = \"https://redis.io\"#baseURL = \"https://redis.io/${hugo_root_path}\"#g" config.toml - - # Remove all other rs versions - rs_versions='${{ needs.setup_and_build_latest.outputs.rs_versions }}' - for v in $(echo "$rs_versions" | jq -r '.[]'); do - if [[ "$v" != "$version" ]]; then - rm -rf "content/operate/rs/${v}" - fi - done - - # relrefs should not include version - find "content/operate/rs/${version}" -type f | while read file; do - awk '{gsub(/\(\{\{< ?relref "\/operate\/rs\/'"${version}"'/, "({{< relref \"/operate/rs") }1' "$file" > tmpfile && mv tmpfile "$file" - done - - rsync -a --delete-after "content/operate/rs/${version}"/ content/operate/rs/ - sed -i 's/id="versionSelectorRsValue" class="version-selector-control">latest/id="versionSelectorRsValue" class="version-selector-control">v'"${version}"'/' layouts/partials/docs-nav.html - sed -i 's/linkTitle: '"${version}"'/linkTitle: Redis Software/' content/operate/rs/_index.md - - # inject replace command in meta-links - sed -i "12i \{\{ \$gh_path = replaceRE \`\^operate\/rs\/\` \"operate\/rs\/${version}\/\" \$gh_path }}" layouts/partials/meta-links.html - - # Create version files for docs-nav.html dropdowns - echo '${{ needs.setup_and_build_latest.outputs.kubernetes_versions }}' | jq -r '.[]' > kubernetes-versions - echo '${{ needs.setup_and_build_latest.outputs.rs_versions }}' | jq -r '.[]' > rs-versions - echo '${{ needs.setup_and_build_latest.outputs.rdi_versions }}' | jq -r '.[]' > rdi-versions - echo '${{ needs.setup_and_build_latest.outputs.redisvl_versions }}' | jq -r '.[]' > redisvl-versions - - hugo -d "output" - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: build-rs-${{ matrix.version }} - path: output/ - retention-days: 1 - - # Build RDI versions in parallel - build_rdi: - name: Build RDI ${{ matrix.version }} - needs: setup_and_build_latest - if: ${{ needs.setup_and_build_latest.outputs.rdi_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.rdi_versions) }} - - steps: - - name: Free up disk space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - - - name: Install Hugo - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Check the branch out - uses: actions/checkout@v4 - - - name: Install dependencies - run: make deps - - - name: Generate components - run: make components - - - name: Build RDI ${{ matrix.version }} - run: | - set -x - version="${{ matrix.version }}" - hugo_root_path="${{ needs.setup_and_build_latest.outputs.hugo_root_path }}" - - sed -i "s#baseURL = \"https://redis.io\"#baseURL = \"https://redis.io/${hugo_root_path}\"#g" config.toml - - # Remove all other rdi versions - rdi_versions='${{ needs.setup_and_build_latest.outputs.rdi_versions }}' - for v in $(echo "$rdi_versions" | jq -r '.[]'); do - if [[ "$v" != "$version" ]]; then - rm -rf "content/integrate/redis-data-integration/${v}" - fi - done - - # relrefs should not include version - find "content/integrate/redis-data-integration/${version}" -type f | while read file; do - awk '{gsub(/\(\{\{< ?relref "\/integrate\/redis-data-integration\/'"${version}"'/, "({{< relref \"/integrate/redis-data-integration") }1' "$file" > tmpfile && mv tmpfile "$file" - done - - rsync -a --delete-after "content/integrate/redis-data-integration/${version}"/ content/integrate/redis-data-integration/ - sed -i 's/id="versionSelectorRedis-Data-IntegrationValue" class="version-selector-control">latest/id="versionSelectorRedis-Data-IntegrationValue" class="version-selector-control">v'"${version}"'/' layouts/partials/docs-nav.html - sed -i 's/linkTitle: '"${version}"'/linkTitle: Redis Data Integration/' content/integrate/redis-data-integration/_index.md - - # inject replace command in meta-links - sed -i "12i \{\{ \$gh_path = replaceRE \`\^integrate\/redis-data-integration\/\` \"integrate\/redis-data-integration\/${version}\/\" \$gh_path }}" layouts/partials/meta-links.html - - # Create version files for docs-nav.html dropdowns - echo '${{ needs.setup_and_build_latest.outputs.kubernetes_versions }}' | jq -r '.[]' > kubernetes-versions - echo '${{ needs.setup_and_build_latest.outputs.rs_versions }}' | jq -r '.[]' > rs-versions - echo '${{ needs.setup_and_build_latest.outputs.rdi_versions }}' | jq -r '.[]' > rdi-versions - echo '${{ needs.setup_and_build_latest.outputs.redisvl_versions }}' | jq -r '.[]' > redisvl-versions - - hugo -d "output" - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: build-rdi-${{ matrix.version }} - path: output/ - retention-days: 1 - - # Build RedisVL versions in parallel - build_redisvl: - name: Build RedisVL ${{ matrix.version }} - needs: setup_and_build_latest - if: ${{ needs.setup_and_build_latest.outputs.redisvl_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.redisvl_versions) }} - - steps: - - name: Free up disk space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - - - name: Install Hugo - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Check the branch out - uses: actions/checkout@v4 - - - name: Install dependencies - run: make deps - - - name: Generate components - run: make components - - - name: Build RedisVL ${{ matrix.version }} - run: | - set -x - version="${{ matrix.version }}" - hugo_root_path="${{ needs.setup_and_build_latest.outputs.hugo_root_path }}" - - sed -i "s#baseURL = \"https://redis.io\"#baseURL = \"https://redis.io/${hugo_root_path}\"#g" config.toml - - # Remove all other redisvl versions - redisvl_versions='${{ needs.setup_and_build_latest.outputs.redisvl_versions }}' - for v in $(echo "$redisvl_versions" | jq -r '.[]'); do - if [[ "$v" != "$version" ]]; then - rm -rf "content/develop/ai/redisvl/${v}" - fi - done - - # relrefs should not include version - find "content/develop/ai/redisvl/${version}" -type f | while read file; do - awk '{gsub(/\(\{\{< ?relref "\/develop\/ai\/redisvl\/'"${version}"'/, "({{< relref \"/develop/ai/redisvl") }1' "$file" > tmpfile && mv tmpfile "$file" - done - - rsync -a --delete-after "content/develop/ai/redisvl/${version}"/ content/develop/ai/redisvl/ - sed -i 's/id="versionSelectorRedisvlValue" class="version-selector-control">latest/id="versionSelectorRedisvlValue" class="version-selector-control">v'"${version}"'/' layouts/partials/docs-nav.html - sed -i 's/linkTitle: '"${version}"'/linkTitle: RedisVL/' content/develop/ai/redisvl/_index.md - - # inject replace command in meta-links - sed -i "12i \{\{ \$gh_path = replaceRE \`\^develop\/ai\/redisvl\/\` \"develop\/ai\/redisvl\/${version}\/\" \$gh_path }}" layouts/partials/meta-links.html - - # Create version files for docs-nav.html dropdowns - echo '${{ needs.setup_and_build_latest.outputs.kubernetes_versions }}' | jq -r '.[]' > kubernetes-versions - echo '${{ needs.setup_and_build_latest.outputs.rs_versions }}' | jq -r '.[]' > rs-versions - echo '${{ needs.setup_and_build_latest.outputs.rdi_versions }}' | jq -r '.[]' > rdi-versions - echo '${{ needs.setup_and_build_latest.outputs.redisvl_versions }}' | jq -r '.[]' > redisvl-versions - - hugo -d "output" - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: build-redisvl-${{ matrix.version }} - path: output/ - retention-days: 1 - - # Deploy latest build to GCS - deploy_latest: - name: Deploy latest - needs: setup_and_build_latest - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - env: - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: Download latest artifact - uses: actions/download-artifact@v4 - with: - name: build-latest - path: public/ - - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Deploy latest to GCS - run: | - bucket_path="${{ needs.setup_and_build_latest.outputs.bucket_path }}" - gsutil -m rsync -r -c -j html -d public gs://$BUCKET/$bucket_path - gsutil -m rsync -r -c -j html -d public gs://$BUCKET/docs/$bucket_path - - # Deploy Kubernetes versions to GCS - deploy_kubernetes: - name: Deploy Kubernetes ${{ matrix.version }} - needs: - - setup_and_build_latest - - build_kubernetes - if: ${{ needs.setup_and_build_latest.outputs.kubernetes_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.kubernetes_versions) }} - env: - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: build-kubernetes-${{ matrix.version }} - path: output/ - - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Deploy Kubernetes ${{ matrix.version }} to GCS - run: | - version="${{ matrix.version }}" - bucket_path="${{ needs.setup_and_build_latest.outputs.bucket_path }}" - - # Matrix Hugo builds can produce different CSS hashes than deploy_latest, - # so versioned pages 404 on /css/index.min.{hash}.css. Additively rsync - # this build's css/scss (no -d) so each hash coexists alongside the - # canonical hash uploaded by deploy_latest. Applied on both latest and - # staging. - upload_assets() { - local dest="$1" - for d in css scss; do - if [ -d "output/$d" ]; then - gsutil -m rsync -r -c -j css "output/$d" "${dest}/$d" - fi - done - } - - if [[ "${{ github.ref_name }}" == "latest" ]]; then - gsutil -m rsync -r -c -j html -d output/operate/kubernetes "gs://${BUCKET}/kubernetes-${version}/operate/kubernetes" - gsutil -m rsync -r -c -j html -d "output/operate/kubernetes/${version}" "gs://${BUCKET}/docs/${bucket_path}/operate/kubernetes/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - elif [[ "$bucket_path" == staging/* ]]; then - gsutil -m rsync -r -c -j html -d output/operate/kubernetes "gs://${BUCKET}/${bucket_path}/kubernetes-${version}/operate/kubernetes" - gsutil -m rsync -r -c -j html -d "output/operate/kubernetes/${version}" "gs://${BUCKET}/docs/${bucket_path}/operate/kubernetes/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - fi - - # Deploy RS versions to GCS - deploy_rs: - name: Deploy RS ${{ matrix.version }} - needs: - - setup_and_build_latest - - build_rs - if: ${{ needs.setup_and_build_latest.outputs.rs_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.rs_versions) }} - env: - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: build-rs-${{ matrix.version }} - path: output/ - - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Deploy RS ${{ matrix.version }} to GCS - run: | - version="${{ matrix.version }}" - bucket_path="${{ needs.setup_and_build_latest.outputs.bucket_path }}" - - upload_assets() { - local dest="$1" - for d in css scss; do - if [ -d "output/$d" ]; then - gsutil -m rsync -r -c -j css "output/$d" "${dest}/$d" - fi - done - } - - if [[ "${{ github.ref_name }}" == "latest" ]]; then - gsutil -m rsync -r -c -j html -d output/operate/rs "gs://${BUCKET}/rs-${version}/operate/rs" - gsutil -m rsync -r -c -j html -d "output/operate/rs/${version}" "gs://${BUCKET}/docs/${bucket_path}/operate/rs/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - elif [[ "$bucket_path" == staging/* ]]; then - gsutil -m rsync -r -c -j html -d output/operate/rs "gs://${BUCKET}/${bucket_path}/rs-${version}/operate/rs" - gsutil -m rsync -r -c -j html -d "output/operate/rs/${version}" "gs://${BUCKET}/docs/${bucket_path}/operate/rs/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - fi - - # Deploy RDI versions to GCS - deploy_rdi: - name: Deploy RDI ${{ matrix.version }} - needs: - - setup_and_build_latest - - build_rdi - if: ${{ needs.setup_and_build_latest.outputs.rdi_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.rdi_versions) }} - env: - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: build-rdi-${{ matrix.version }} - path: output/ - - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Deploy RDI ${{ matrix.version }} to GCS - run: | - version="${{ matrix.version }}" - bucket_path="${{ needs.setup_and_build_latest.outputs.bucket_path }}" - - upload_assets() { - local dest="$1" - for d in css scss; do - if [ -d "output/$d" ]; then - gsutil -m rsync -r -c -j css "output/$d" "${dest}/$d" - fi - done - } - - if [[ "${{ github.ref_name }}" == "latest" ]]; then - gsutil -m rsync -r -c -j html -d output/integrate/redis-data-integration "gs://${BUCKET}/redis-data-integration-${version}/integrate/redis-data-integration" - gsutil -m rsync -r -c -j html -d "output/integrate/redis-data-integration/${version}" "gs://${BUCKET}/docs/${bucket_path}/integrate/redis-data-integration/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - elif [[ "$bucket_path" == staging/* ]]; then - gsutil -m rsync -r -c -j html -d output/integrate/redis-data-integration "gs://${BUCKET}/${bucket_path}/redis-data-integration-${version}/integrate/redis-data-integration" - gsutil -m rsync -r -c -j html -d "output/integrate/redis-data-integration/${version}" "gs://${BUCKET}/docs/${bucket_path}/integrate/redis-data-integration/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - fi - - # Deploy RedisVL versions to GCS - deploy_redisvl: - name: Deploy RedisVL ${{ matrix.version }} - needs: - - setup_and_build_latest - - build_redisvl - if: ${{ needs.setup_and_build_latest.outputs.redisvl_versions != '[]' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.setup_and_build_latest.outputs.redisvl_versions) }} - env: - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: build-redisvl-${{ matrix.version }} - path: output/ - - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Deploy RedisVL ${{ matrix.version }} to GCS - run: | - version="${{ matrix.version }}" - bucket_path="${{ needs.setup_and_build_latest.outputs.bucket_path }}" - - upload_assets() { - local dest="$1" - for d in css scss; do - if [ -d "output/$d" ]; then - gsutil -m rsync -r -c -j css "output/$d" "${dest}/$d" - fi - done - } - - if [[ "${{ github.ref_name }}" == "latest" ]]; then - gsutil -m rsync -r -c -j html -d output/develop/ai/redisvl "gs://${BUCKET}/redisvl-${version}/develop/ai/redisvl" - gsutil -m rsync -r -c -j html -d "output/develop/ai/redisvl/${version}" "gs://${BUCKET}/docs/${bucket_path}/develop/ai/redisvl/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - elif [[ "$bucket_path" == staging/* ]]; then - gsutil -m rsync -r -c -j html -d output/develop/ai/redisvl "gs://${BUCKET}/${bucket_path}/redisvl-${version}/develop/ai/redisvl" - gsutil -m rsync -r -c -j html -d "output/develop/ai/redisvl/${version}" "gs://${BUCKET}/docs/${bucket_path}/develop/ai/redisvl/${version}" - upload_assets "gs://${BUCKET}/docs/${bucket_path}" - fi - - # Deploy custom 404 page (only on latest branch) - deploy_404: - name: Deploy 404 page - needs: setup_and_build_latest - if: ${{ github.ref_name == 'latest' }} - runs-on: ubuntu-latest - permissions: - contents: 'read' - id-token: 'write' - env: - PROD_PROJECT_ID: ${{ secrets.GCP_PROJECT_PROD }} - PROD_SERVICE_ACCOUNT: ${{ secrets.PROD_SERVICE_ACCOUNT }} - PROD_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.PROD_WORKLOAD_IDENTITY_PROVIDER }} - - steps: - - name: Download latest artifact - uses: actions/download-artifact@v4 - with: - name: build-latest - path: public/ - - - name: Prepare 404 page - run: | - sed -i "s#/docs/latest/scss/#https://storage.googleapis.com/$BUCKET/docs/latest/scss/#g" public/404.html - sed -i "s#/docs/latest/css/#https://storage.googleapis.com/$BUCKET/docs/latest/css/#g" public/404.html - - - name: 'Google auth' - uses: 'google-github-actions/auth@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - service_account: '${{ env.PROD_SERVICE_ACCOUNT }}' - workload_identity_provider: '${{ env.PROD_WORKLOAD_IDENTITY_PROVIDER }}' - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - project_id: '${{ env.PROD_PROJECT_ID }}' - version: '>= 363.0.0' - - - name: Deploy 404 page to GCS - run: gsutil cp public/404.html gs://$BUCKET/docs/ diff --git a/.github/workflows/rc_api_sync.yaml b/.github/workflows/rc_api_sync.yaml deleted file mode 100644 index a90b16545a..0000000000 --- a/.github/workflows/rc_api_sync.yaml +++ /dev/null @@ -1,70 +0,0 @@ -name: rc_api_sync - -on: - schedule: - - cron: '0 0 * * *' # run every day at midnight UTC time - workflow_dispatch: # or run on manual trigger - -jobs: - rc_api_sync: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - actions: write - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: 'Fetch openapi json file' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - branch="rc_api_sync" - spec_change=false - - # check if remote branch already exists - git fetch --all - set +e - git ls-remote --exit-code --heads origin "refs/heads/${branch}" - if [ "$?" -eq 0 ]; then - set -e - # if it does, create local branch off existing remote branch - git checkout -b "${branch}" "origin/${branch}" - git branch --set-upstream-to="origin/${branch}" "${branch}" - git pull - else - set -e - # otherwise, create local branch from main - git checkout -b "${branch}" - fi - - curl -Ls https://api.redislabs.com/v1/cloud-api-docs \ - | jq '(.. | .example? | try select(test("^{"))) |= fromjson' > content/operate/rc/api/api-reference/openapi.json - - spec_is_different=$(git diff content/operate/rc/api/api-reference/openapi.json) - - if [[ ! -z $spec_is_different ]]; then - spec_change=true - - git add "content/operate/rc/api/api-reference/openapi.json" - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update content/operate/rc/api/api-reference/openapi.json" - fi - - if [ "$spec_change" = true ] ; then - git push origin "${branch}" - - # If a pr is not already open, create one - set +e - gh search prs -R redis/docs --state open --match title "update rc openapi spec" | grep -q "update rc openapi spec" - if [ "$?" -eq 1 ]; then - set -e - gh pr create \ - --body "update rc openapi spec" \ - --title "update rc openapi spec" \ - --head "$branch" \ - --base "main" - fi - fi \ No newline at end of file diff --git a/.github/workflows/rc_supported_regions_sync.yaml b/.github/workflows/rc_supported_regions_sync.yaml deleted file mode 100644 index a930bb1ac3..0000000000 --- a/.github/workflows/rc_supported_regions_sync.yaml +++ /dev/null @@ -1,74 +0,0 @@ -name: rc_supported_regions_sync - -on: - schedule: - - cron: '0 0 * * 1' # run every Monday at midnight UTC time - workflow_dispatch: # or run on manual trigger - -jobs: - rc_supported_regions_sync: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - actions: write - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: 'Install dependencies' - run: pip3 install requests - - - name: 'Run rc_supported_regions_sync.py' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RC_API_KEY: ${{ secrets.RC_API_KEY }} - RC_API_SECRET_KEY: ${{ secrets.RC_API_SECRET_KEY }} - run: | - branch="rc_supported_regions_sync" - regions_change=false - - # check if remote branch already exists - git fetch --all - set +e - git ls-remote --exit-code --heads origin "refs/heads/${branch}" - if [ "$?" -eq 0 ]; then - set -e - # if it does, create local branch off existing remote branch - git checkout -b "${branch}" "origin/${branch}" - git branch --set-upstream-to="origin/${branch}" "${branch}" - git pull - else - set -e - # otherwise, create local branch from main - git checkout -b "${branch}" - fi - - python3 build/rc_supported_regions_sync.py - - regions_are_different=$(git diff data/rc_supported_regions.json) - - if [[ ! -z $regions_are_different ]]; then - regions_change=true - - git add "data/rc_supported_regions.json" - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update data/rc_supported_regions.json" - fi - - if [ "$regions_change" = true ] ; then - git push origin "${branch}" - - # If a pr is not already open, create one - set +e - gh search prs -R redis/docs --state open --match title "update rc supported regions" | grep -q "update rc supported regions" - if [ "$?" -eq 1 ]; then - set -e - gh pr create \ - --body "update rc supported regions" \ - --title "update rc supported regions" \ - --head "$branch" \ - --base "main" - fi - fi diff --git a/.github/workflows/redis_docs_sync.yaml b/.github/workflows/redis_docs_sync.yaml deleted file mode 100644 index 7b1aedbcaf..0000000000 --- a/.github/workflows/redis_docs_sync.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: redis_docs_sync - -on: - workflow_dispatch: - inputs: - release: - type: string - required: true - description: '' - -jobs: - redis_docs_sync: - runs-on: ubuntu-latest - permissions: - contents: write - actions: write - steps: - - name: Generate a token - id: generate-token - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.DOCS_APP_ID }} - private-key: ${{ secrets.DOCS_APP_PRIVATE_KEY }} - - - name: 'Checkout' - uses: actions/checkout@v3 - with: - token: ${{ steps.generate-token.outputs.token }} - - - name: 'Generate modules-api-ref.md and commands.json files and push if necessary' - env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - RELEASE: ${{ github.event.inputs.release }} - run: |- - BRANCH="redis_docs_sync_${RELEASE}" - - # Generate modules-api-ref.md - gh repo clone redis/redis - pushd redis - git fetch origin --tags - git checkout "tags/${RELEASE}" - make 1>/dev/null - src/redis-server & - utils/generate-commands-json.py > generated-commands.json - utils/generate-module-api-doc.rb > generated-modules-api-ref.md - popd - - # check if remote branch already exists - git fetch --all - set +e - git ls-remote --exit-code --heads origin "refs/heads/${BRANCH}" - if [ "$?" -eq 0 ]; then - set -e - # if it does, create local branch off existing remote branch - git checkout -b "${BRANCH}" "origin/${BRANCH}" - git branch --set-upstream-to="origin/${BRANCH}" "${BRANCH}" - git pull - else - set -e - # otherwise, create local branch from main - git checkout -b "${BRANCH}" - fi - - mv redis/generated-modules-api-ref.md content/develop/reference/modules/modules-api-ref.md - mv redis/generated-commands.json data/commands_core.json - - # Apply frontmatter patch - git apply content/develop/reference/modules/modules-api-ref-frontmatter.patch - - # Check if there are any changes - commands_core_is_different=$(git diff data/commands_core.json) - modules_api_is_different=$(git diff content/develop/reference/modules/modules-api-ref.md) - - # If commands_core file has changed, commit it - if [[ ! -z $commands_core_is_different ]]; then - git add data/commands_core.json - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update commands_core.json for release ${RELEASE}" - fi - - # If modules-api-ref file has changed, commit it - if [[ ! -z $modules_api_is_different ]]; then - git add content/develop/reference/modules/modules-api-ref.md - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update modules-api-ref.md for release ${RELEASE}" - fi - - if [[ ! -z $commands_core_is_different || ! -z $modules_api_is_different ]]; then - git push origin "${BRANCH}" - fi - - # If a pr is not already open, create one - set +e - gh search prs -R redis/docs --state open --match title "redis docs sync ${RELEASE}" | grep -q "redis docs sync ${RELEASE}" - if [ "$?" -eq 1 ]; then - set -e - gh pr create \ - --body "redis docs sync ${RELEASE}" \ - --title "redis docs sync ${RELEASE}" \ - --head "$BRANCH" \ - --base "main" - fi \ No newline at end of file diff --git a/.github/workflows/redis_modules_docs_sync.yaml b/.github/workflows/redis_modules_docs_sync.yaml deleted file mode 100644 index b72d565311..0000000000 --- a/.github/workflows/redis_modules_docs_sync.yaml +++ /dev/null @@ -1,84 +0,0 @@ -name: redis_modules_docs_sync - -on: - schedule: - - cron: '0 0 * * *' # run every day at midnight UTC time - workflow_dispatch: # or run on manual trigger - -jobs: - redis_modules_docs_sync: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - actions: write - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: 'Fetch commands json files from modules' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - branch="redis_modules_docs_sync" - modules_list=("redisjson" "redisbloom" "redistimeseries" "redisearch") - module_change=false - - # check if remote branch already exists - git fetch --all - set +e - git ls-remote --exit-code --heads origin "refs/heads/${branch}" - if [ "$?" -eq 0 ]; then - set -e - # if it does, create local branch off existing remote branch - git checkout -b "${branch}" "origin/${branch}" - git branch --set-upstream-to="origin/${branch}" "${branch}" - git pull - else - set -e - # otherwise, create local branch from main - git checkout -b "${branch}" - fi - - for module in "${modules_list[@]}"; do - # Find latest version - module_version=$( - curl -Ls \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${GH_TOKEN}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "https://api.github.com/repos/${module}/${module}/releases/latest" \ - | jq -r '.tag_name' - ) - - # Fetch release - gh release download "$module_version" -R "${module}/${module}" -A zip -O "${module}.zip" - unzip "${module}.zip" -d "${module}" - cp ${module}/*/commands.json "data/commands_${module}.json" - - modules_commands_is_different=$(git diff "data/commands_${module}.json") - if [[ ! -z $modules_commands_is_different ]]; then - module_change=true - - git add "data/commands_${module}.json" - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update data/commands_${module}.json for release ${module_version}" - fi - done - - if [ "$module_change" = true ] ; then - git push origin "${branch}" - - # If a pr is not already open, create one - set +e - gh search prs -R redis/docs --state open --match title "redis modules docs sync" | grep -q "redis modules docs sync" - if [ "$?" -eq 1 ]; then - set -e - gh pr create \ - --body "redis modules docs sync" \ - --title "redis modules docs sync" \ - --head "$branch" \ - --base "main" - fi - fi \ No newline at end of file diff --git a/.github/workflows/redisvl_docs_sync.yaml b/.github/workflows/redisvl_docs_sync.yaml deleted file mode 100644 index ff5a08f916..0000000000 --- a/.github/workflows/redisvl_docs_sync.yaml +++ /dev/null @@ -1,128 +0,0 @@ -name: redisvl_docs_sync - -on: - schedule: - - cron: '0 0 * * *' # run every day at midnight UTC time - workflow_dispatch: # or run on manual trigger - -jobs: - define-version-matrix: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - id: set-matrix - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - OLDEST_SUPPORTED_VERSION="0.6.0" - versions=$(gh release -R redis/redis-vl-python list --json name,isLatest \ - | jq -r '.[] | [.name, .isLatest] | @tsv' \ - | sed "/${OLDEST_SUPPORTED_VERSION}/q" \ - | jq -Rnc '{include: [inputs | split("\t") | {version: .[0], isLatest: .[1]}]}') - - echo "${versions}" - echo "matrix=${versions}" >> "$GITHUB_OUTPUT" - - redisvl_docs_sync: - runs-on: ubuntu-latest - needs: define-version-matrix - strategy: - matrix: ${{ fromJSON(needs['define-version-matrix'].outputs.matrix) }} - fail-fast: false - permissions: - contents: write - pull-requests: write - actions: write - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: 'Setup Python' - uses: 'actions/setup-python@v5' - with: - python-version: '3.11' - - - name: 'Install deps' - run: | - pip3 install \ - sphinx==8.1.3 \ - sphinx_design==0.7.0 \ - sphinx_copybutton==0.5.2 \ - nbsphinx==0.9.7 \ - sphinx_favicon==1.1.0 \ - myst_nb==1.4.0 \ - sphinx_markdown_builder==0.6.8 \ - jupyter==1.1.1 - - - name: 'Fetch redisvl repo' - run: | - git clone https://github.com/redis/redis-vl-python - - - name: 'Sync redisvl docs' - run: | - version="${{ matrix.version }}" - version="${version#v}" - latest_flag="" - if [ "${{ matrix.isLatest }}" = "true" ]; then - latest_flag="--latest" - fi - python3 build/redisvl_docs_sync.py \ - --version "${version}" \ - --repo redis-vl-python \ - ${latest_flag} - - - name: 'Create pull request if necessary' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - release="${{ matrix.version }}" - release="${release#v}" - branch="redisvl_docs_sync_${release}" - redisvl_change=false - - # check if remote branch already exists - git fetch --all - set +e - git ls-remote --exit-code --heads origin "refs/heads/${branch}" - if [ "$?" -eq 0 ]; then - set -e - # if it does, create local branch off existing remote branch - git checkout -f -b "${branch}" "origin/${branch}" - git branch --set-upstream-to="origin/${branch}" "${branch}" - git pull - else - set -e - # otherwise, create local branch from main - git checkout -b "${branch}" - fi - - set +e - latest_redisvl_release_is_different=$(git diff content/develop/ai/redisvl/ static/images/redisvl/) - new_release=$(git ls-files --others --directory | grep -E 'content/develop/ai/redisvl/'${release}'|static/images/redisvl/') - - if [[ -n "$latest_redisvl_release_is_different" || -n "$new_release" ]]; then - redisvl_change=true - - git add "content/develop/ai/redisvl/" - git add "static/images/redisvl/" - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update for redisvl ${release}" - fi - - if [ "$redisvl_change" = true ] ; then - git push origin "${branch}" - - # If a pr is not already open, create one - set +e - gh search prs -R redis/docs --state open --match title "update for redisvl ${release}" | grep -q "update for redisvl ${release}" - if [ "$?" -eq 1 ]; then - set -e - gh pr create \ - --body "update for redisvl ${release}" \ - --title "update for redisvl ${release}" \ - --head "$branch" \ - --base "main" - fi - fi diff --git a/.github/workflows/repository-memory.yml b/.github/workflows/repository-memory.yml new file mode 100644 index 0000000000..9cfe55f3f0 --- /dev/null +++ b/.github/workflows/repository-memory.yml @@ -0,0 +1,46 @@ +name: Redis Repository Memory + +on: + push: + branches-ignore: + - main + pull_request: + types: + - opened + workflow_dispatch: + +permissions: + pull-requests: write + contents: read + statuses: write + +jobs: + memory: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + working-directory: scripts/memory + run: npm install + + - name: Collect context + run: node scripts/memory/collect_context.js + + - name: Retrieve and store memory + env: + REDIS_URL: ${{ secrets.MEMORY_REDIS_URL }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + run: node scripts/memory/retrieve_memory.js + + - name: Post result + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/memory/post_comment.js diff --git a/.github/workflows/update_command_pages.yaml b/.github/workflows/update_command_pages.yaml deleted file mode 100644 index f503564040..0000000000 --- a/.github/workflows/update_command_pages.yaml +++ /dev/null @@ -1,74 +0,0 @@ -name: update_command_pages - -on: - push: - branches: ['main'] - paths: - - data/commands_core.json # run when data/commands_core.json is updated on main - workflow_dispatch: # or run on manual trigger - -jobs: - update_command_pages: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - actions: write - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - name: Install dependencies - run: make deps - - - name: 'Run build/cmd_tools.py update-all' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - branch="update_command_pages" - commands_change=false - - # check if remote branch already exists - git fetch --all - set +e - git ls-remote --exit-code --heads origin "refs/heads/${branch}" - if [ "$?" -eq 0 ]; then - set -e - # if it does, create local branch off existing remote branch - git checkout -b "${branch}" "origin/${branch}" - git branch --set-upstream-to="origin/${branch}" "${branch}" - git pull - else - set -e - # otherwise, create local branch from main - git checkout -b "${branch}" - fi - - python3 build/cmd_tools.py update-all - - commands_are_different=$(git diff "content/commands/") - - if [[ ! -z $commands_are_different ]]; then - commands_change=true - - git add "content/commands/" - git config user.email "177626021+redisdocsapp[bot]@users.noreply.github.com" - git config user.name "redisdocsapp[bot]" - git commit -m "Update content/commands/" - fi - - if [ "$commands_change" = true ] ; then - git push origin "${branch}" - - # If a pr is not already open, create one - set +e - gh search prs -R redis/docs --state open --match title "update command pages" | grep -q "update command pages" - if [ "$?" -eq 1 ]; then - set -e - gh pr create \ - --body "update command pages" \ - --title "update command pages" \ - --head "$branch" \ - --base "main" - fi - fi \ No newline at end of file diff --git a/content/develop/data-types/hashes.md b/content/develop/data-types/hashes.md index 06153cf87f..82e78d4fc8 100644 --- a/content/develop/data-types/hashes.md +++ b/content/develop/data-types/hashes.md @@ -44,7 +44,7 @@ You can use hashes to represent basic objects and to store groupings of counters {{< /clients-example >}} -While hashes are handy to represent *objects*, actually the number of fields you can +While hashes are used to represent *objects*, actually the number of fields you can put inside a hash has no practical limits (other than available memory), so you can use hashes in many different ways inside your application. @@ -70,7 +70,7 @@ as well, like [`HINCRBY`]({{< relref "/commands/hincrby" >}}): You can find the [full list of hash commands in the documentation]({{< relref "/commands#hash" >}}). -It is worth noting that small hashes (i.e., a few elements with small values) are +It is worth noting that small hashes (for example, a few elements with small values) are encoded in special way in memory that make them very memory efficient. ## Examples @@ -201,5 +201,5 @@ In practice, your hashes are limited only by the overall memory on the VMs hosti ## Learn more -* [Redis Hashes Explained](https://www.youtube.com/watch?v=-KdITaRkQ-U) is a short, comprehensive video explainer covering Redis hashes. +* [Redis Hashes Explained](https://www.youtube.com/watch?v=-KdITaRkQ-U) is a short, comprehensive video that explains Redis hashes. * [Redis University's RU101](https://university.redis.com/courses/ru101/) covers Redis hashes in detail. diff --git a/scripts/memory/collect_context.js b/scripts/memory/collect_context.js new file mode 100644 index 0000000000..607c5921e9 --- /dev/null +++ b/scripts/memory/collect_context.js @@ -0,0 +1,96 @@ +'use strict'; + +const fs = require('fs'); +const { execSync } = require('child_process'); + +const eventName = process.env.GITHUB_EVENT_NAME; +const eventPath = process.env.GITHUB_EVENT_PATH; +const sha = process.env.GITHUB_SHA; +const ref = process.env.GITHUB_REF || ''; +const repo = process.env.GITHUB_REPOSITORY; + +if (!eventName || !eventPath) { + console.error('Missing required GitHub environment variables (GITHUB_EVENT_NAME, GITHUB_EVENT_PATH)'); + process.exit(1); +} + +const event = JSON.parse(fs.readFileSync(eventPath, 'utf8')); + +function getChangedFiles(commitSha) { + try { + return execSync(`git diff --name-only ${commitSha}^1 ${commitSha}`, { + encoding: 'utf8', + stdio: ['pipe', 'pipe', 'pipe'], + }) + .trim() + .split('\n') + .filter(Boolean); + } catch { + return []; + } +} + +let context; + +if (eventName === 'push') { + const headCommit = event.head_commit || {}; + const branch = ref.replace('refs/heads/', ''); + const title = (headCommit.message || '').split('\n')[0]; + + context = { + eventName, + type: 'push', + sha, + branch, + repo, + prNumber: null, + title, + body: headCommit.message || '', + labels: [], + changedFiles: getChangedFiles(sha), + author: headCommit.author?.name || headCommit.committer?.name || 'unknown', + timestamp: new Date().toISOString(), + }; +} else if (eventName === 'pull_request') { + const pr = event.pull_request; + context = { + eventName, + type: 'pull_request', + sha: pr.head.sha, + branch: pr.head.ref, + repo, + prNumber: pr.number, + title: pr.title, + body: pr.body || '', + labels: (pr.labels || []).map(l => l.name), + changedFiles: [], + author: pr.user?.login || 'unknown', + timestamp: new Date().toISOString(), + }; +} else if (eventName === 'workflow_dispatch') { + context = { + eventName, + type: 'workflow_dispatch', + sha, + branch: ref.replace('refs/heads/', ''), + repo, + prNumber: null, + title: 'Manual workflow dispatch', + body: '', + labels: [], + changedFiles: [], + author: event.sender?.login || 'unknown', + timestamp: new Date().toISOString(), + }; +} else { + console.error(`Unsupported event type: ${eventName}`); + process.exit(1); +} + +context.searchText = [context.title, context.body, context.changedFiles.join(' ')] + .join('\n') + .slice(0, 4000); + +fs.writeFileSync('/tmp/memory_context.json', JSON.stringify(context, null, 2)); + +console.log(`trigger=${eventName} repo=${repo} title="${context.title}" files=${context.changedFiles.length}`); diff --git a/scripts/memory/package.json b/scripts/memory/package.json new file mode 100644 index 0000000000..854d972d3b --- /dev/null +++ b/scripts/memory/package.json @@ -0,0 +1,13 @@ +{ + "name": "redis-repo-memory", + "version": "1.0.0", + "private": true, + "description": "GitHub Actions scripts for Redis-backed repository memory", + "engines": { + "node": ">=18" + }, + "dependencies": { + "openai": "^4.77.0", + "redis": "^4.7.0" + } +} diff --git a/scripts/memory/post_comment.js b/scripts/memory/post_comment.js new file mode 100644 index 0000000000..3639cc2a2f --- /dev/null +++ b/scripts/memory/post_comment.js @@ -0,0 +1,117 @@ +'use strict'; + +const fs = require('fs'); + +const COMMENT_MARKER = ''; + +async function githubRequest(method, path, body, token) { + const res = await fetch(`https://api.github.com${path}`, { + method, + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${token}`, + 'X-GitHub-Api-Version': '2022-11-28', + 'Content-Type': 'application/json', + }, + body: body ? JSON.stringify(body) : undefined, + }); + if (!res.ok) { + const text = await res.text(); + throw new Error(`GitHub API ${method} ${path} → ${res.status}: ${text}`); + } + return res.json(); +} + +function buildMarkdown(related, context, sourceUrl) { + const lines = [ + COMMENT_MARKER, + '## 🧠 Redis Repository Memory', + '', + ]; + + if (related.length === 0) { + lines.push("No related prior context found — this looks new to the repository's memory."); + } else { + lines.push(`Found **${related.length}** related item${related.length === 1 ? '' : 's'} from repository history:`); + lines.push(''); + for (const item of related) { + const label = item.type === 'pr_summary' ? 'PR' : item.type === 'issue_summary' ? 'Issue' : 'Commit'; + const link = item.sourceUrl ? `[${item.title}](${item.sourceUrl})` : `**${item.title}**`; + lines.push(`- **${label}** — ${link}`); + if (item.bodySummary) { + lines.push(` > ${item.bodySummary.split('\n')[0].slice(0, 140)}`); + } + } + } + + lines.push(''); + lines.push(`*Memory updated at [${context.sha?.slice(0, 7)}](${sourceUrl})*`); + return lines.join('\n'); +} + +async function postCommitStatus(repo, sha, related, sourceUrl, token) { + const description = related.length === 0 + ? 'No related prior context found' + : `Found ${related.length} related item${related.length === 1 ? '' : 's'}: ${related[0].title}`.slice(0, 140); + + await githubRequest('POST', `/repos/${repo}/statuses/${sha}`, { + state: 'success', + context: 'Redis Repository Memory', + description, + target_url: sourceUrl, + }, token); + console.log(`posted_commit_status sha=${sha?.slice(0, 7)} related=${related.length}`); +} + +async function postOrUpdatePrComment(repo, prNumber, body, token) { + const comments = await githubRequest('GET', `/repos/${repo}/issues/${prNumber}/comments`, null, token); + const existing = comments.find(c => typeof c.body === 'string' && c.body.includes(COMMENT_MARKER)); + + if (existing) { + await githubRequest('PATCH', `/repos/${repo}/issues/comments/${existing.id}`, { body }, token); + console.log(`updated_comment_id=${existing.id} pr=${prNumber}`); + } else { + const created = await githubRequest('POST', `/repos/${repo}/issues/${prNumber}/comments`, { body }, token); + console.log(`created_comment_id=${created.id} pr=${prNumber}`); + } +} + +async function main() { + const token = process.env.GITHUB_TOKEN; + const repo = process.env.GITHUB_REPOSITORY; + + if (!token) { + console.error('GITHUB_TOKEN is not set'); + process.exit(1); + } + if (!repo) { + console.error('GITHUB_REPOSITORY is not set'); + process.exit(1); + } + + const { context, related, sourceUrl } = JSON.parse( + fs.readFileSync('/tmp/memory_results.json', 'utf8') + ); + + const markdown = buildMarkdown(related, context, sourceUrl); + + if (context.prNumber) { + await postOrUpdatePrComment(repo, context.prNumber, markdown, token); + } else { + // Post commit status so results are visible on the commit without opening Actions + await postCommitStatus(repo, context.sha, related, sourceUrl, token); + + const summaryPath = process.env.GITHUB_STEP_SUMMARY; + if (summaryPath) { + fs.appendFileSync(summaryPath, markdown + '\n'); + } else { + process.stdout.write(markdown + '\n'); + } + console.log(`posted_to=step_summary related=${related.length}`); + } +} + +main().catch(err => { + console.error('post_comment failed:', err.message); + process.exit(1); +}); diff --git a/scripts/memory/retrieve_memory.js b/scripts/memory/retrieve_memory.js new file mode 100644 index 0000000000..9e09e74267 --- /dev/null +++ b/scripts/memory/retrieve_memory.js @@ -0,0 +1,141 @@ +'use strict'; + +const fs = require('fs'); +const { createClient, SchemaFieldTypes, VectorAlgorithms } = require('redis'); +const OpenAI = require('openai'); + +const INDEX_NAME = 'repo_memory_idx'; +const KEY_PREFIX = 'memory:'; +const VECTOR_DIM = 1536; +const SIMILARITY_THRESHOLD = 0.60; // cosine distance [0,2]; lower = more similar +const TOP_K = 10; +const MAX_RESULTS = 5; + +async function ensureIndex(client) { + const exists = await client.ft.info(INDEX_NAME).then(() => true).catch(() => false); + if (exists) return; + await client.ft.create( + INDEX_NAME, + { + type: { type: SchemaFieldTypes.TAG }, + repo: { type: SchemaFieldTypes.TAG }, + title: { type: SchemaFieldTypes.TEXT, WEIGHT: 2 }, + body_summary: { type: SchemaFieldTypes.TEXT }, + source_url: { type: SchemaFieldTypes.TEXT, NOSTEM: true }, + created_at: { type: SchemaFieldTypes.TEXT }, + tags: { type: SchemaFieldTypes.TAG, SEPARATOR: ',' }, + embedding: { + type: SchemaFieldTypes.VECTOR, + ALGORITHM: VectorAlgorithms.HNSW, + TYPE: 'FLOAT32', + DIM: VECTOR_DIM, + DISTANCE_METRIC: 'COSINE', + }, + }, + { ON: 'HASH', PREFIX: KEY_PREFIX } + ); + console.log(`created index: ${INDEX_NAME}`); +} + +async function main() { + const redisUrl = process.env.REDIS_URL; + const openaiKey = process.env.OPENAI_API_KEY; + + if (!redisUrl) { + console.error('REDIS_URL secret is not set'); + process.exit(1); + } + if (!openaiKey) { + console.error('OPENAI_API_KEY secret is not set'); + process.exit(1); + } + + const context = JSON.parse(fs.readFileSync('/tmp/memory_context.json', 'utf8')); + + const client = createClient({ url: redisUrl }); + client.on('error', err => console.error('Redis error:', err.message)); + await client.connect(); + + try { + const openai = new OpenAI({ apiKey: openaiKey }); + + await ensureIndex(client); + + const embeddingRes = await openai.embeddings.create({ + model: 'text-embedding-3-small', + input: context.searchText || context.title, + }); + const embeddingBuffer = Buffer.from( + new Float32Array(embeddingRes.data[0].embedding).buffer + ); + + const searchResult = await client.ft.search( + INDEX_NAME, + `*=>[KNN ${TOP_K} @embedding $BLOB AS score]`, + { + PARAMS: { BLOB: embeddingBuffer }, + RETURN: ['type', 'title', 'body_summary', 'source_url', 'created_at', 'score', 'repo'], + SORTBY: { BY: 'score', DIRECTION: 'ASC' }, + DIALECT: 2, + } + ); + + const related = searchResult.documents + .filter(doc => { + const score = parseFloat(doc.value.score ?? '2'); + return score < SIMILARITY_THRESHOLD && doc.value.repo === context.repo; + }) + .slice(0, MAX_RESULTS); + + // Store the current context as a memory artifact + const safeRepo = context.repo.replace(/\//g, '_'); + const itemId = context.prNumber + ? `${safeRepo}_pr_${context.prNumber}` + : `${safeRepo}_push_${context.sha?.slice(0, 8)}`; + + const sourceUrl = context.prNumber + ? `https://github.com/${context.repo}/pull/${context.prNumber}` + : `https://github.com/${context.repo}/commit/${context.sha}`; + + await client.hSet(`${KEY_PREFIX}${itemId}`, { + id: itemId, + type: context.type === 'pull_request' ? 'pr_summary' : 'push_summary', + repo: context.repo, + title: context.title, + body_summary: context.body.slice(0, 500), + source_url: sourceUrl, + created_at: context.timestamp, + tags: context.labels.join(','), + embedding: embeddingBuffer, + }); + + console.log(`stored=${KEY_PREFIX}${itemId} related_count=${related.length}`); + + fs.writeFileSync( + '/tmp/memory_results.json', + JSON.stringify( + { + context, + sourceUrl, + related: related.map(doc => ({ + type: doc.value.type, + title: doc.value.title, + bodySummary: doc.value.body_summary, + sourceUrl: doc.value.source_url, + createdAt: doc.value.created_at, + score: parseFloat(doc.value.score ?? '2'), + })), + }, + null, + 2 + ) + ); + } finally { + await client.quit(); + } +} + +main().catch(err => { + console.error('retrieve_memory failed:', err.message); + process.exit(1); +});