{"id":446509,"date":"2024-02-29T15:27:58","date_gmt":"2024-02-29T14:27:58","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=dotnet&#038;p=446509"},"modified":"2024-03-11T23:54:44","modified_gmt":"2024-03-11T22:54:44","slug":"boost-code-quality-with-qodana-and-github-actions","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2024\/02\/29\/boost-code-quality-with-qodana-and-github-actions","title":{"rendered":"Boost Code Quality with Qodana and GitHub Actions"},"content":{"rendered":"\n<p>It\u2019s been roughly half a year since we introduced Qodana to .NET in our blog post about <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2023\/06\/29\/elevating-csharp-code-quality-with-qodana-a-journey-towards-perfection\">how to elevate your C# code quality with Qodana.<\/a> Since then, we\u2019ve been quite busy! Qodana went <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/qodana\/2023\/07\/qodana-is-out-of-preview-with-first-class-jetbrains-ide-integration\">out of preview and into GA<\/a>. Furthermore, we <a href=\"https:\/\/blog.jetbrains.com\/qodana\/2023\/09\/code-quality-under-pressure-supporting-developers-with-qodana-integration-in-intellij-based-ides\/\">greatly improved the integration with our IDEs<\/a>, providing an effortless <a href=\"https:\/\/www.jetbrains.com\/help\/qodana\/qodana-ide-plugin.html#ide-plugin-run-qodana\" target=\"_blank\" rel=\"noopener\">Try Qodana<\/a> experience directly on your local machine. We\u2019ve also <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/qodana\/2023\/11\/visual-studio-code-analysis\">released a plugin for Visual Studio Code<\/a>. And lastly, we\u2019ve taken your feedback on board and started to discuss <a href=\"https:\/\/www.jetbrains.com\/qodana\/buy\/?billing=yearly\" target=\"_blank\" rel=\"noopener\">custom On-Premises plans<\/a> with interested teams.<\/p>\n\n\n\n<p>Still haven\u2019t heard about Qodana? Our new code quality platform helps various stakeholders in your company improve code quality, comply with license requirements, spot security issues, and deliver a better product! In the realm of open source, Qodana has already proven to <a href=\"https:\/\/github.com\/fluentassertions\/fluentassertions\/pull\/2292\" target=\"_blank\" rel=\"noopener\">ensure<\/a> and <a href=\"https:\/\/github.com\/fluentassertions\/fluentassertions\/pull\/2394\" target=\"_blank\" rel=\"noopener\">encourage<\/a> qualitative pull requests.<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/qodana-in-action.png\"\n        alt=\"Qodana in Action\"\n        width=\"1002\"\/>\n    <figcaption class=\"wp-element-caption\">Qodana in Action<\/figcaption>\n<\/figure>\n\n\n\n<p>In this blog post, we will dive deeper into the topic of integrating Qodana with your GitHub Actions infrastructure to maintain your team\u2019s software engineering standards.<\/p>\n\n\n    <div class=\"buttons\">\n        <div class=\"buttons__row\">\n                                                <a href=\"https:\/\/www.jetbrains.com\/qodana\/\" class=\"btn\" target=\"\" rel=\"noopener\">Try Qodana with your .NET projects<\/a>\n                                                    <\/div>\n    <\/div>\n\n\n\n\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Setting up a Qodana Project<\/h2>\n\n\n\n<p>Head over to <a href=\"https:\/\/qodana.cloud\/\" target=\"_blank\" rel=\"noopener\">Qodana Cloud<\/a> or your On-Premises solution, and create a new project that links to one of your GitHub repositories:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/creating-a-new-qodana-project-with-https-address.png\"\n        alt=\"Creating a new Qodana project with an HTTPS address\"\n        width=\"853\"\/>\n    <figcaption class=\"wp-element-caption\">Creating a new Qodana project with an HTTPS address<\/figcaption>\n<\/figure>\n\n\n\n<p>Once you\u2019ve gone through all the setup steps, Qodana will present your personal access token:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/confirmation-after-the-qodana-project-has-been-created.png\"\n        alt=\"Confirmation after the Qodana project has been created\"\n        width=\"854\"\/>\n    <figcaption class=\"wp-element-caption\">Confirmation after the Qodana project has been created<\/figcaption>\n<\/figure>\n\n\n\n<p>You can copy the Qodana token right away, but you\u2019ll also get another chance while we\u2019re setting up the configuration and workflow files in the next step!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Adding a GitHub Actions workflow file<\/h2>\n\n\n\n<p>As already mentioned, our Qodana team has put a lot of effort into IDE integration and your first-time experience. Bring up the <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Searching_Everywhere.html\" target=\"_blank\" rel=\"noopener\"><em>Search Everything<\/em> popup<\/a> and search for the <em>Add Qodana to CI Pipeline<\/em> action:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/adding-qodana-to-a-ci-pipeline.png\"\n        alt=\"Adding Qodana to a CI pipeline\"\n        width=\"655\"\/>\n    <figcaption class=\"wp-element-caption\">Adding Qodana to a CI pipeline<\/figcaption>\n<\/figure>\n\n\n\n<p>Assuming you haven\u2019t tried Qodana yet, the dialog will first prompt you to add a <code>qodana.yml<\/code> file based on a template with standard defaults for your .NET solution:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/adding-the-.png\"\n        alt=\"Adding the qodana.yml configuration file\"\n        width=\"714\"\/>\n    <figcaption class=\"wp-element-caption\">Adding the <code>qodana.yml<\/code> configuration file<\/figcaption>\n<\/figure>\n\n\n\n<p>From the colorization, you might have guessed it already, but this is not just a simple multiline textbox but rather an embedded editor with full <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/YAML.html\" target=\"_blank\" rel=\"noopener\">YAML support<\/a>! So you can take advantage of code completion, formatting, and validation when editing the file. For instance, you can see which <a href=\"https:\/\/www.jetbrains.com\/help\/qodana\/inspection-profiles.html\" target=\"_blank\" rel=\"noopener\">inspection profiles<\/a> are included out of the box:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/yaml-support-in-.png\"\n        alt=\"YAML support in qodana.yml\"\n        width=\"712\"\/>\n    <figcaption class=\"wp-element-caption\">YAML support in <code>qodana.yml<\/code><\/figcaption>\n<\/figure>\n\n\n\n<p>Once you confirm the <code>qodana.yml<\/code> file, the wizard will continue with a list of all the major CI\/CD services and tools. As you may have gathered, we\u2019ll be focusing on Qodana\u2019s <a href=\"https:\/\/www.jetbrains.com\/help\/qodana\/github.html\" target=\"_blank\" rel=\"noopener\">integration with GitHub Actions<\/a> in this blog post. The workflow template comes with all the most important bits, including when to trigger the analysis, how to checkout the repository (do not shallow clone!), the actual analysis invocation through <code><a href=\"https:\/\/github.com\/JetBrains\/qodana-action\" target=\"_blank\" rel=\"noopener\">qodana-action<\/a><\/code>, and the <code>QODANA_TOKEN<\/code> as an environment variable:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/adding-a-github-actions-workflow-file.png\"\n        alt=\"Adding a GitHub Actions workflow file\"\n        width=\"714\"\/>\n    <figcaption class=\"wp-element-caption\">Adding a GitHub Actions workflow file<\/figcaption>\n<\/figure>\n\n\n\n<p><em>By default, the action will use the same version as the current version of your IDE. You can also change it to <code>JetBrains\/qodana-action@main<\/code> to always use the latest version.<\/em><\/p>\n\n\n\n<p>Before you confirm to add the <code>qodana.yaml<\/code> and workflow file to your repository, it\u2019s a good idea to click the <em>Get token<\/em> link and grab the Qodana token for your project:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/grabbing-the-qodana-token.png\"\n        alt=\"Grabbing the Qodana Token\"\n        width=\"690\"\/>\n    <figcaption class=\"wp-element-caption\">Grabbing the Qodana Token<\/figcaption>\n<\/figure>\n\n\n\n<p>This <code>QODANA_TOKEN<\/code> needs to be added as a secret to your GitHub repository so that Qodana can upload analysis results to your Qodana Cloud or On-Premises solution:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/adding-the-qodana-token-to-a-github-repository.png\"\n        alt=\"Adding the Qodana Token to a GitHub repository\"\n        width=\"801\"\/>\n    <figcaption class=\"wp-element-caption\">Adding the Qodana Token to a GitHub repository<\/figcaption>\n<\/figure>\n\n\n\n<p>Now you can finally confirm the Qodana wizard and push the <code>qodana.yml<\/code> and GitHub Actions workflow file to your repository:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/qodana-setup-confirmation.png\"\n        alt=\"Qodana setup confirmation\"\n        width=\"412\"\/>\n    <figcaption class=\"wp-element-caption\">Qodana setup confirmation<\/figcaption>\n<\/figure>\n\n\n\n<p>Your GitHub repository will take it from here and run the workflow through GitHub Actions. In the meantime, you might want to log in to Qodana in your IDE under <em>Settings | Tools | Qodana<\/em> so that we can download and inspect analysis results in the next part:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/logging-into-qodana-in-the-ide.png\"\n        alt=\"Logging into Qodana in the IDE\"\n        width=\"810\"\/>\n    <figcaption class=\"wp-element-caption\">Logging in to Qodana in the IDE<\/figcaption>\n<\/figure>\n\n\n\n<p>Get ready, we\u2019re about to enter the really interesting part!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Inspecting Qodana results for GitHub Actions<\/h2>\n\n\n\n<p>Before inspecting your first run results, you need to link the local repository to the Qodana project. Under the <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Problems_Tool_Window.html\" target=\"_blank\" rel=\"noopener\"><em>Problems<\/em> tool window<\/a>, you can find the <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Problems_Tool_Window.html#qodana\" target=\"_blank\" rel=\"noopener\"><em>Server-Side Analysis<\/em> tab<\/a>. If Qodana hasn\u2019t linked your project automatically yet, you can perform this step manually from here:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/linking-a-qodana-project-in-the-ide.png\"\n        alt=\"Linking a Qodana project in the IDE\"\n        width=\"666\"\/>\n    <figcaption class=\"wp-element-caption\">Linking a Qodana project in the IDE<\/figcaption>\n<\/figure>\n\n\n\n<p>Once the project is linked, you will see the first analysis results inside your IDE. The report includes all important information about the workflow run, branch, number of issues, their classifications, and severities:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/inspecting-qodana-results-in-the-ide.png\"\n        alt=\"Inspecting Qodana results in the IDE\"\n        width=\"810\"\/>\n    <figcaption class=\"wp-element-caption\">Inspecting Qodana results in the IDE<\/figcaption>\n<\/figure>\n\n\n\n<p>Double-clicking an issue quickly navigates you to the location in your repository. It\u2019s also worth noting that from the context menu, not only can you navigate to the report in Qodana Cloud but also to the workflow run in GitHub Actions:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/navigation-to-qodana-cloud-and-the-github-actions-workflow-run.png\"\n        alt=\"Navigation to Qodana Cloud and the GitHub Actions workflow run\"\n        width=\"602\"\/>\n    <figcaption class=\"wp-element-caption\">Navigation to Qodana Cloud and the GitHub Actions workflow run<\/figcaption>\n<\/figure>\n\n\n\n<p>Another great strength of Qodana is that it doesn\u2019t just provide its analysis results through our IDEs and Qodana web interface but also directly through <a href=\"https:\/\/docs.github.com\/en\/actions\/using-workflows\/workflow-commands-for-github-actions#using-workflow-commands-to-access-toolkit-functions\" target=\"_blank\" rel=\"noopener\">both annotations<\/a> and <a href=\"https:\/\/docs.github.com\/en\/actions\/using-workflows\/workflow-commands-for-github-actions#adding-a-job-summary\" target=\"_blank\" rel=\"noopener\">job summaries<\/a> under workflow runs. That means even contributors who don\u2019t use JetBrains IDEs or don\u2019t have access to your Qodana project can take advantage of Qodana\u2019s first-class analysis reports:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/github-actions-annotations-with-qodana-results.png\"\n        alt=\"GitHub Actions annotations with Qodana results\"\n        width=\"795\"\/>\n    <figcaption class=\"wp-element-caption\">GitHub Actions annotations with Qodana results<\/figcaption>\n<\/figure>\n\n\n\n<p><em>This is a little reminder that we also built an <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/qodana\/2023\/11\/visual-studio-code-analysis\">extension for Visual Studio Code<\/a>.<\/em><\/p>\n\n\n\n<p>In case you don\u2019t want to see any annotations, you can opt out via the <code>use-annotations<\/code> property:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">- name: Qodana Scan\n  uses: JetBrains\/qodana-action@main\n\twith:\n\t  use-annotations: false\n<\/pre>\n\n\n\n<p>In contrast to our demo project in this blog post, your solution might show significantly more code inspections and problems. This is expected, and you shouldn\u2019t feel discouraged by it. Our goal with Qodana is to help you <strong>improve your code quality in an incremental and flexible way<\/strong>, which can be achieved by <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2023\/06\/29\/elevating-csharp-code-quality-with-qodana-a-journey-towards-perfection#qodana-scans-in-cicd-environments\">moving existing problems to the baseline and configuring a fail threshold as a quality gate<\/a>.<\/p>\n\n\n\n<p>In the following sections, we\u2019ll dive into the <a href=\"https:\/\/www.jetbrains.com\/help\/qodana\/github.html\" target=\"_blank\" rel=\"noopener\">GitHub-specific aspects of Qodana<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Qodana results in GitHub Pull Requests<\/h2>\n\n\n\n<p>In order to make Qodana work properly with pull requests, you need to set the <code>ref<\/code> and <code>fetch-depth<\/code> properties on the <code>checkout<\/code> action as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">- uses: actions\/checkout@v4\n  with:\n    ref: ${{ github.event.pull_request.merge_commit_sha }}\n    fetch-depth: 0\n<\/pre>\n\n\n\n<p>Without any additional effort, Qodana can post analysis results on GitHub pull requests. This enables contributors to react promptly to potential bugs and quality degradation. At the same time, it gives repository owners more confidence when it comes to merging pull requests:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/qodana-results-as-a-comment-in-a-github-pull-request.png\"\n        alt=\"Qodana results as a comment in a GitHub pull request\"\n        width=\"777\"\/>\n    <figcaption class=\"wp-element-caption\">Qodana results as a comment in a GitHub pull request<\/figcaption>\n<\/figure>\n\n\n\n<p>This analysis report is updated as more commits are pushed to the branch.<\/p>\n\n\n\n<p>If you prefer not to post any updates on pull requests, you can opt out via the <code>post-pr-comment<\/code> property:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">- name: Qodana Scan\n  uses: JetBrains\/qodana-action@main\n\twith:\n\t  post-pr-comment: false\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Uploading Qodana results as artifacts<\/h2>\n\n\n\n<p>By default, Qodana will upload analysis results only to Qodana Cloud. Under certain circumstances, you might also want to upload them as artifacts. This could be to update the <code>qodana.sarif.json<\/code> baseline file by simply downloading and replacing it in your repository or to allow contributors to investigate a report directly in their IDE without having to link the project:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/load-a-qodana-report-locally-in-the-ide.png\"\n        alt=\"Load a Qodana report locally in the IDE\"\n        width=\"828\"\/>\n    <figcaption class=\"wp-element-caption\">Load a Qodana report locally in the IDE<\/figcaption>\n<\/figure>\n\n\n\n<p>In order to opt into uploading the Qodana report as an artifact, you can use the <code>upload-result<\/code> and <code>artifact-name<\/code> properties:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">- name: Qodana Scan\n  uses: JetBrains\/qodana-action@main\n\twith:\n\t  upload-result: ${{ github.ref_name == 'main' }}\n\t\tartifact-name: qodana-report\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Adding a Qodana status badge<\/h2>\n\n\n\n<p>After all that work of integrating Qodana into your repository, what could be better than adding a lovely little badge to show that it\u2019s in good shape? Just head over to one of the workflow runs and grab it from the menu in the upper right-hand corner:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/02\/adding-a-qodana-status-badge.png\"\n        alt=\"Adding a Qodana status badge\"\n        width=\"792\"\/>\n    <figcaption class=\"wp-element-caption\">Adding a Qodana status badge<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Over recent months, Qodana has made significant strides in seamlessly integrating with your GitHub repositories, diligently monitoring code quality with each commit and pull request. Through this integration, maintainers and contributors can swiftly pinpoint defects, whether within their IDEs\/editors or directly within the GitHub UI. <a href=\"https:\/\/qodana.cloud\/\" target=\"_blank\" rel=\"noopener\"><strong>Register on Qodana Cloud today<\/strong><\/a> and experience the enhancement of code quality in GitHub firsthand!<\/p>\n\n\n\n<p>As always, let us know what you think and what features you\u2019d like to see in the future!<\/p>\n\n\n\n<p><em><sub>Image credits: <\/sub><\/em><sub><em><a href=\"https:\/\/unsplash.com\/photos\/a-toy-is-floating-in-the-air-on-a-rocket-mriVu-dK9Ho\" data-type=\"link\" data-id=\"https:\/\/unsplash.com\/photos\/a-toy-is-floating-in-the-air-on-a-rocket-mriVu-dK9Ho\" target=\"_blank\" rel=\"noopener\">Andy Hermawan<\/a><\/em><\/sub><\/p>\n","protected":false},"author":553,"featured_media":446517,"comment_status":"closed","ping_status":"closed","template":"","categories":[4992,1401,6924],"tags":[228,6470,6359,1978],"cross-post-tag":[6687],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/446509"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/553"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=446509"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/446509\/revisions"}],"predecessor-version":[{"id":456357,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/446509\/revisions\/456357"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media\/446517"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=446509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=446509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=446509"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=446509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}