Skip to content

Conversation

@hasparus
Copy link
Collaborator

@hasparus hasparus commented Oct 29, 2025

we now show cases studies and product updates in the RSS feed and blog index page

  • i've also added zod schemas to mdx frontmatter types and used them for the validation functions
    • i'm not a huge fan of zod compared to alternatives (arktype btw), but it's already used in the repo and in nextra, so choosing it for consistency
  • installed @next/bundle-analyzer (run pnpm build:analyze)
  • changed isBlogPost and isCaseStudy to parse*. now we get a build error instead of hiding a malformed blog post, and we can have some defaults ensured on zod level (like authors optional in mdx frontmatter, but always at least empty array in typescript)

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @hasparus, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the content aggregation strategy by integrating case studies and product updates directly into the main blog feed and listing page. The primary goal is to ensure that all relevant content types are discoverable and presented cohesively to users. This involves updates to data fetching mechanisms, the introduction of a new utility for content transformation, and minor adjustments to content metadata.

Highlights

  • Unified Content Feed: The blog feed and main blog page now include content from 'Case Studies' and 'Product Updates' alongside regular blog posts, providing a single, comprehensive stream of updates.
  • Enhanced Blog Metadata: A 'description' field has been added to the BlogFrontmatter interface, allowing for richer metadata in blog entries, particularly for RSS feeds.
  • Refactored Content Coercion: The logic for converting case studies into a blog post format has been extracted into a dedicated utility file, improving code organization and reusability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces case studies and product updates into the blog feed. It modifies the BlogFrontmatter interface to include a description, updates the feed generation logic to include case studies and product updates, and adjusts the blog page to display these new content types. The coerceCaseStudiesToBlogs function is moved to a separate file for better organization. I have identified a potential issue with the sorting logic in feed.xml/route.ts where the dates are being unnecessarily converted to Date objects, which could be simplified for better performance.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@graphql-hive/cli 0.52.1-alpha-20251103154836-fd8f2da3e4923e90840e1f2a6249371844a13bf2 npm ↗︎ unpkg ↗︎
hive 8.5.3-alpha-20251103154836-fd8f2da3e4923e90840e1f2a6249371844a13bf2 npm ↗︎ unpkg ↗︎

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

📚 Storybook Deployment

The latest changes are available as preview in: https://pr-7192.hive-storybook.pages.dev

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

🐋 This PR was built and pushed to the following Docker images:

Targets: build

Platforms: linux/amd64

Image Tag: fd8f2da3e4923e90840e1f2a6249371844a13bf2

Docker Bake metadata
{
"app": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/api/health",
          "build-arg:IMAGE_DESCRIPTION": "The app of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/app",
          "build-arg:PORT": "3000",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/app",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/dec8ci2d3tjtzmt12xhsze412",
  "containerimage.config.digest": "sha256:52eafa5af042b2d34101e109c2d4e75208a742c224ab5169e146a98e9a66b3a8",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:34e6b6c7f1c00740b533151028c8d3ff332e1272d55ed6081090edc4438845a8",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:34e6b6c7f1c00740b533151028c8d3ff332e1272d55ed6081090edc4438845a8",
  "image.name": "ghcr.io/graphql-hive/app:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/app:hacky_product_updates_in_feed-amd64"
},
"buildx.build.warnings": [
  {
    "vertex": "sha256:086a183eb73ac0e4f0c50c26cd829d38e81749fc5f5c4c4fe79997231a567e22",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9ERVNDUklQVElPTicgKGxpbmUgMTQp",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "services.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UPXByb2R1Y3Rpb24KRU5WIFJFTEVBU0U9JFJFTEVBU0UKRU5WIFBPUlQ9JFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 14
        },
        "end": {
          "line": 14
        }
      }
    ]
  },
  {
    "vertex": "sha256:086a183eb73ac0e4f0c50c26cd829d38e81749fc5f5c4c4fe79997231a567e22",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAyMSk=",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "services.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UPXByb2R1Y3Rpb24KRU5WIFJFTEVBU0U9JFJFTEVBU0UKRU5WIFBPUlQ9JFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 21
        },
        "end": {
          "line": 21
        }
      }
    ]
  },
  {
    "vertex": "sha256:086a183eb73ac0e4f0c50c26cd829d38e81749fc5f5c4c4fe79997231a567e22",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRQT1JUJyAobGluZSAyMik=",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "services.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UPXByb2R1Y3Rpb24KRU5WIFJFTEVBU0U9JFJFTEVBU0UKRU5WIFBPUlQ9JFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 22
        },
        "end": {
          "line": 22
        }
      }
    ]
  },
  {
    "vertex": "sha256:75cd6121ca9bf5f95cb2bef174cf42a4adf6f12b5365c6a6d4e909803aef4fbc",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAxMik=",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "migrations.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQ9cHJvZHVjdGlvbgpFTlYgTk9ERV9FTlY9cHJvZHVjdGlvbgpFTlYgUkVMRUFTRT0kUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 12
        },
        "end": {
          "line": 12
        }
      }
    ]
  },
  {
    "vertex": "sha256:75cd6121ca9bf5f95cb2bef174cf42a4adf6f12b5365c6a6d4e909803aef4fbc",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9USVRMRScgKGxpbmUgMTUp",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "migrations.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQ9cHJvZHVjdGlvbgpFTlYgTk9ERV9FTlY9cHJvZHVjdGlvbgpFTlYgUkVMRUFTRT0kUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 15
        },
        "end": {
          "line": 15
        }
      }
    ]
  },
  {
    "vertex": "sha256:75cd6121ca9bf5f95cb2bef174cf42a4adf6f12b5365c6a6d4e909803aef4fbc",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9ERVNDUklQVElPTicgKGxpbmUgMTcp",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "migrations.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQ9cHJvZHVjdGlvbgpFTlYgTk9ERV9FTlY9cHJvZHVjdGlvbgpFTlYgUkVMRUFTRT0kUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 17
        },
        "end": {
          "line": 17
        }
      }
    ]
  },
  {
    "vertex": "sha256:086a183eb73ac0e4f0c50c26cd829d38e81749fc5f5c4c4fe79997231a567e22",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9USVRMRScgKGxpbmUgMTIp",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "services.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UPXByb2R1Y3Rpb24KRU5WIFJFTEVBU0U9JFJFTEVBU0UKRU5WIFBPUlQ9JFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 12
        },
        "end": {
          "line": 12
        }
      }
    ]
  },
  {
    "vertex": "sha256:086a183eb73ac0e4f0c50c26cd829d38e81749fc5f5c4c4fe79997231a567e22",
    "level": 1,
    "short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAxMyk=",
    "detail": [
      "VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
    ],
    "url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
    "sourceInfo": {
      "filename": "services.dockerfile",
      "data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UPXByb2R1Y3Rpb24KRU5WIFJFTEVBU0U9JFJFTEVBU0UKRU5WIFBPUlQ9JFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
      "language": "Dockerfile"
    },
    "range": [
      {
        "start": {
          "line": 13
        },
        "end": {
          "line": 13
        }
      }
    ]
  }
],
"commerce": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The commerce service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/commerce",
          "build-arg:PORT": "3010",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/commerce",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/pufy8ql6as1nrg53sq2wkenvn",
  "containerimage.config.digest": "sha256:9bb112df9d6064134785cb6cf7687fe6a36151ef69f5b7d8e48aa62f6da9fe33",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:ee0916d5446c951b5f1aabc44f3c141c72a3888581b6d6a6809e4a4bcc46c0cf",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:ee0916d5446c951b5f1aabc44f3c141c72a3888581b6d6a6809e4a4bcc46c0cf",
  "image.name": "ghcr.io/graphql-hive/commerce:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/commerce:hacky_product_updates_in_feed-amd64"
},
"composition-federation-2": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "Federation 2 Composition Service for GraphQL Hive.",
          "build-arg:IMAGE_TITLE": "graphql-hive/composition-federation-2",
          "build-arg:PORT": "3069",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/external-composition",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/yajwxc9euudmbnf6etucr7prb",
  "containerimage.config.digest": "sha256:adba9c8598c5f246c61433d0bf624b28fcab42921e589c0c59fda969e64959d1",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:e15a7d6f2a394c46dc8105d4a28e346fe47889b95b4fa85ba8743b1413054051",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:e15a7d6f2a394c46dc8105d4a28e346fe47889b95b4fa85ba8743b1413054051",
  "image.name": "ghcr.io/graphql-hive/composition-federation-2:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/composition-federation-2:hacky_product_updates_in_feed-amd64"
},
"emails": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The emails service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/emails",
          "build-arg:PORT": "3006",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/emails",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/wgzj8dl2t50kevwm0keudphve",
  "containerimage.config.digest": "sha256:bacd29328260c16b787fb965301c9e91ffa5a5928bedcad60f3bb6667f3f3199",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:c983cabdf3f9068ad5b11960a55e098a815fbb287f6248e02316fd905ac1ab31",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:c983cabdf3f9068ad5b11960a55e098a815fbb287f6248e02316fd905ac1ab31",
  "image.name": "ghcr.io/graphql-hive/emails:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/emails:hacky_product_updates_in_feed-amd64"
},
"otel-collector": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "0f2d5c38dd7a4f4f733e688e3a6733cb5ab1ac6e3cb4603a5dd564e5bfb80eed"
        }
      },
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "7d1571fea7cdc08fe7f37d4eacf06dfe5756366acb7bdd33cf26a7c422fed993"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "otel-collector.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:IMAGE_DESCRIPTION": "OTEL Collector for GraphQL Hive.",
          "build-arg:IMAGE_TITLE": "graphql-hive/otel-collector",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dockerfile"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/8cqobci5iuh5sgig24r7tp9gc",
  "containerimage.config.digest": "sha256:afd8fd832d15e025632fdb8ef538b2544e02b5dc9ad3335b1138bbab23f2e81e",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:eb81282cce7ba397a57e3241280083dc6b1094d0b1f8010a1e37cbe60b0e7e0e",
    "size": 1089,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:eb81282cce7ba397a57e3241280083dc6b1094d0b1f8010a1e37cbe60b0e7e0e",
  "image.name": "ghcr.io/graphql-hive/otel-collector:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/otel-collector:hacky_product_updates_in_feed-amd64"
},
"policy": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The policy service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/policy",
          "build-arg:PORT": "3012",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/policy",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/f8e42mv0jpel2diaa4eal5u57",
  "containerimage.config.digest": "sha256:69534ccbe314bb845893b166ae7aee19c65f52822e684ae3044def8aff9e3cc3",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:7bb896a924d71e4d5e65db72b595c524205c27c04a74f7b1bf2d59cf18327ab8",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:7bb896a924d71e4d5e65db72b595c524205c27c04a74f7b1bf2d59cf18327ab8",
  "image.name": "ghcr.io/graphql-hive/policy:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/policy:hacky_product_updates_in_feed-amd64"
},
"schema": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The schema service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/schema",
          "build-arg:PORT": "3002",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/schema",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/e8yld52eomxi3srk94pikr30b",
  "containerimage.config.digest": "sha256:51d1a043d49503ec476124558a08d698d8e51446938d3b08648df092372d750d",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:796cf3333527b0c3e2144e9d0413e5d2ff8afecc666f7222269c1140607c5226",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:796cf3333527b0c3e2144e9d0413e5d2ff8afecc666f7222269c1140607c5226",
  "image.name": "ghcr.io/graphql-hive/schema:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/schema:hacky_product_updates_in_feed-amd64"
},
"server": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The server service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/server",
          "build-arg:PORT": "3001",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/server",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/9yh7d4chx8b7uvi0scuvz40c9",
  "containerimage.config.digest": "sha256:41501da2d7183b6f33424c66b7a576dfe5ef0f462232555bf43ad1e79c84a012",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:c83ba8c5d51c8a9eb98842c6cd337a3d19511baa3c920deeae4ac5fb792d0b8f",
    "size": 2076,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:c83ba8c5d51c8a9eb98842c6cd337a3d19511baa3c920deeae4ac5fb792d0b8f",
  "image.name": "ghcr.io/graphql-hive/server:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/server:hacky_product_updates_in_feed-amd64"
},
"storage": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "migrations.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:IMAGE_DESCRIPTION": "The migrations service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/storage",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/d78mcye0b5cgg6sfqrbsvf13k",
  "containerimage.config.digest": "sha256:997e3281a7b8735401ea32424a15f08b88618f99cf6d02b5eba3f79f52fe29fc",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:8ed1599ce8071e7054cef2e5f9399e129d6854cd8e97f5b639417433d553f134",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:8ed1599ce8071e7054cef2e5f9399e129d6854cd8e97f5b639417433d553f134",
  "image.name": "ghcr.io/graphql-hive/storage:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/storage:hacky_product_updates_in_feed-amd64"
},
"tokens": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The tokens service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/tokens",
          "build-arg:PORT": "3003",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/tokens",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/pm9d4rxowdb1e183v6jy03fk0",
  "containerimage.config.digest": "sha256:af254eb38adc20a11802a94e42c09219d8a32610dc6b2ecb5760644061b19daa",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:596f290b34a4e8dddca77b9edc9d43f5eab709444f3c0230599c42779045e56a",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:596f290b34a4e8dddca77b9edc9d43f5eab709444f3c0230599c42779045e56a",
  "image.name": "ghcr.io/graphql-hive/tokens:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/tokens:hacky_product_updates_in_feed-amd64"
},
"usage": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The usage ingestor service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/usage",
          "build-arg:PORT": "3006",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/usage",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/oj032nz6jhz3ei570gye6bhny",
  "containerimage.config.digest": "sha256:04db10e926303e1a39bd61ae421ebedd2ae6c2b32d706d27a550e33bff664770",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:a3494df5cf6a61cf5a1f6b73975b39f6654d48ada7a9d0168f7076c4ae4352d1",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:a3494df5cf6a61cf5a1f6b73975b39f6654d48ada7a9d0168f7076c4ae4352d1",
  "image.name": "ghcr.io/graphql-hive/usage:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/usage:hacky_product_updates_in_feed-amd64"
},
"usage-ingestor": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The usage ingestor service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/usage-ingestor",
          "build-arg:PORT": "3007",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/usage-ingestor",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/19onxk8gwod3l7z8aghobps3q",
  "containerimage.config.digest": "sha256:81788f004678a90a9f84bba110ac2fa44c5b8660e63de498d252b7466ab98e21",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:a106e05c202dd6a026b000c55d89bc2b3be4f4105df741fb0e919d8694a16633",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:a106e05c202dd6a026b000c55d89bc2b3be4f4105df741fb0e919d8694a16633",
  "image.name": "ghcr.io/graphql-hive/usage-ingestor:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/usage-ingestor:hacky_product_updates_in_feed-amd64"
},
"webhooks": {
  "buildx.build.provenance": {
    "builder": {
      "id": ""
    },
    "buildType": "https://mobyproject.org/buildkit@v1",
    "materials": [
      {
        "uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
        "digest": {
          "sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "services.dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {
          "build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
          "build-arg:IMAGE_DESCRIPTION": "The webhooks ingestor service of the GraphQL Hive project.",
          "build-arg:IMAGE_TITLE": "graphql-hive/webhooks",
          "build-arg:PORT": "3005",
          "build-arg:RELEASE": "fd8f2da3e4923e90840e1f2a6249371844a13bf2",
          "build-arg:SERVICE_DIR_NAME": "@hive/webhooks",
          "context:dist": "local:dist",
          "context:shared": "local:shared",
          "frontend.caps": "moby.buildkit.frontend.contexts+forward",
          "local-sessionid:context": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:dockerfile": "8q260p25juqhrbv8uvvsybihp",
          "local-sessionid:shared": "8q260p25juqhrbv8uvvsybihp"
        },
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dist"
          },
          {
            "name": "dockerfile"
          },
          {
            "name": "shared"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64",
        "ProvenanceCustomEnv": null
      }
    }
  },
  "buildx.build.ref": "builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e/builder-3dce7a3e-ab42-49f1-8104-17c9db4f6f2e0/zi0im7bw1htzhp73e2yg10cme",
  "containerimage.config.digest": "sha256:49df0539098a371b6b41028d415ca7620517bf47fed06642ba3a8b11e65c3352",
  "containerimage.descriptor": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "digest": "sha256:15f631c3933ea8e76962919d10fff60ad3c2fe52a399facc6fa36add09e0765c",
    "size": 2075,
    "platform": {
      "architecture": "amd64",
      "os": "linux"
    }
  },
  "containerimage.digest": "sha256:15f631c3933ea8e76962919d10fff60ad3c2fe52a399facc6fa36add09e0765c",
  "image.name": "ghcr.io/graphql-hive/webhooks:fd8f2da3e4923e90840e1f2a6249371844a13bf2-amd64,ghcr.io/graphql-hive/webhooks:hacky_product_updates_in_feed-amd64"
}
}

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

💻 Website Preview

The latest changes are available as preview in: https://pr-7192.hive-landing-page.pages.dev

@hasparus hasparus requested a review from n1ru4l October 29, 2025 22:17
@n1ru4l
Copy link
Contributor

n1ru4l commented Oct 30, 2025

Should be change the target of this PR to main? We don't have an ETA for approval of the study.

@hasparus hasparus requested a review from Copilot November 3, 2025 14:30
@hasparus
Copy link
Collaborator Author

hasparus commented Nov 3, 2025

/gemini review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces runtime schema validation using Zod across the docs site, replacing type-only TypeScript checks with runtime validation for frontmatter and content types. This ensures MDX files conform to expected schemas at build/runtime, catching errors early. Additionally, it consolidates blog, case studies, and product updates into a unified feed and makes UI improvements.

  • Adds Zod schemas for validating blog posts, case studies, and authors with runtime checks
  • Consolidates blog, case studies, and product updates into RSS feed and blog listing page
  • Removes type guards in favor of schema parsing with helpful error messages

Reviewed Changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds zod 3.25.76 and @next/bundle-analyzer 16.0.0 dependencies
packages/web/docs/package.json Updates dependencies and adds build:analyze script
packages/web/docs/src/mdx-types.ts Adds Zod schema factory and utility functions for page traversal
packages/web/docs/src/lib/parse-schema.ts Implements schema parsing with formatted error messages
packages/web/docs/src/authors/index.ts Converts Author types to Zod schemas
packages/web/docs/src/app/blog/blog-types.ts Converts blog frontmatter to Zod schemas
packages/web/docs/src/app/case-studies/case-study-types.ts Converts case study types to Zod schemas
packages/web/docs/src/components/use-frontmatter.ts Updates hook to require schema parameter
packages/web/docs/src/app/blog/feed.xml/route.ts Consolidates all content types into RSS feed
packages/web/docs/src/app/blog/page.tsx Merges case studies and product updates into blog listing
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- name:
position:
avatar:
date: 2025-01-27
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The date '2025-01-27' is in the future. Verify this is intentional or use the actual publication date.

Suggested change
date: 2025-01-27
date: 2024-06-20

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a great step towards improving type safety and robustness by introducing Zod schemas for MDX frontmatter. The move from simple type guards like isBlogPost to schema parsing with parseSchema will prevent malformed content from being published and provide much better debugging information. The inclusion of case studies and product updates in the main blog feed and RSS is also a great enhancement.

My review includes a few suggestions to further improve consistency and correctness:

  • Ensuring all content types are consistently handled on tag pages.
  • Fixing a potential validation issue in the coerceCaseStudyToBlog function.
  • Applying Zod validation more consistently, for example for dates and in the ProductUpdateHeader component.
  • Some minor code simplifications now possible thanks to the new Zod schemas.

Comment on lines 22 to 27
export async function generateStaticParams() {
const [_meta, _indexPage, ...pageMap] = await getPageMap('/blog');
const allPosts = pageMap.filter(isBlogPost);
const allPosts = pageMap.map(x => parseSchema(x, BlogPostFile));
const tags = allPosts.flatMap(post => post.frontMatter.tags);
const uniqueTags = [...new Set(tags)];
return uniqueTags.map(tag => ({ tag }));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the issue in BlogTagPage, generateStaticParams only considers tags from the /blog directory. To ensure all tags from blog posts, product updates, and case studies are statically generated, this function should also aggregate posts from all sources. Also, since the tags property can be a single string, the flatMap logic should be adjusted to handle this correctly to avoid bugs.

Here's a suggested implementation:

import { getCaseStudies } from '../../../../app/case-studies/get-case-studies';
import { coerceCaseStudiesToBlogs } from '../../../../app/case-studies/coerce-case-studies-to-blogs';

// ...

export async function generateStaticParams() {
  const [_meta, _indexPage, ...pageMap] = await getPageMap('/blog');
  const [, , ...productUpdates] = await getPageMap('/product-updates');

  const caseStudies = await getCaseStudies().then(coerceCaseStudiesToBlogs);

  const allPosts = pageMap
    .map(x => parseSchema(x, BlogPostFile))
    .concat(caseStudies)
    .concat(
      productUpdates
        .map(x => parseSchema(x, BlogPostFile))
        .map(post => ((post.frontMatter.tags ||= ['Product Update']), post)),
    );
  const tags = allPosts.flatMap(post =>
    Array.isArray(post.frontMatter.tags) ? post.frontMatter.tags : [post.frontMatter.tags],
  );
  const uniqueTags = [...new Set(tags)];
  return uniqueTags.map(tag => ({ tag }));
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually we explicitly don't want to do this. The pages are rendered elsewhere, we just link to them from the blog index page.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a great improvement, introducing Zod for robust frontmatter validation and expanding the blog feed to include case studies and product updates. The refactoring makes the codebase more type-safe and maintainable. I've found a critical issue with data coercion that will cause runtime errors, a high-severity issue with test data left in a file, and a few medium-severity issues related to logic correctness and performance. After addressing these points, the PR will be in excellent shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants