{"id":58080,"date":"2019-11-13T09:00:20","date_gmt":"2019-11-13T17:00:20","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/devops\/?p=58080"},"modified":"2019-11-12T12:54:01","modified_gmt":"2019-11-12T20:54:01","slug":"uploading-to-codecov-just-got-easier","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/uploading-to-codecov-just-got-easier\/","title":{"rendered":"Uploading to Codecov just got easier"},"content":{"rendered":"<p>How do you know your tests actually exercise your code? Perhaps you&#8217;re using a code coverage tool like <a href=\"https:\/\/coverage.readthedocs.io\/en\/v4.5.x\/\">coverage.py<\/a> or the <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/test\/using-code-coverage-to-determine-how-much-code-is-being-tested\">tools built into Visual Studio<\/a>. <a href=\"https:\/\/codecov.io\">Codecov<\/a> helps you track code coverage: how much of your code is covered, and are you getting more coverage over time? By integrating Codecov into your continuous integration (CI) pipeline, you&#8217;ll get great reports that help you improve your coverage. You can read more about Codecov on their <a href=\"https:\/\/codecov.io\/#features\">features page<\/a>.<\/p>\n<h2>Using Codecov<\/h2>\n<p>It&#8217;s really easy to get started. Codecov offers a <a href=\"https:\/\/docs.codecov.io\/docs\/about-the-codecov-bash-uploader\">results uploader<\/a> you can run without having to install any additional tools. The script figures out what language your project is written in, where the coverage results are, and how to get them to the service. Typically when you integrate outside services into your CI pipeline, you also need to manage one or more secrets. These secrets &#8211; think passwords and certificates &#8211; are required to securely talk to the outside service.<\/p>\n<p>Codecov has a clever feature in their Bash uploader: tokenless upload for public pipelines. By doing a little extra validation on their side, Codecov saves users the trouble of managing secrets. This only works for public projects on specific CI providers, and I&#8217;m happy to announce that now, <a href=\"https:\/\/azure.com\/pipelines\">Azure Pipelines<\/a> is one of them. (If you have private pipelines on Azure Pipelines or anyplace else, you can still use Codecov and will need to manage a token.)<\/p>\n<h2>Connecting with Azure Pipelines<\/h2>\n<p>To give it a try for yourself, clone one of Codecov&#8217;s <a href=\"https:\/\/docs.codecov.io\/docs\/supported-languages\">example repos<\/a>. I like <a href=\"https:\/\/github.com\/codecov\/example-python\">Python<\/a>, so that&#8217;s where I started. It&#8217;s a toy Python project with two methods and one test. You&#8217;ll have to change two things about that example repo:<\/p>\n<ol>\n<li>Replace .travis.yml with an Azure Pipelines YAML definition. <\/li>\n<li>Instead of using the Python <code>codecov<\/code> uploader, rely on the Bash uploader. <\/li>\n<\/ol>\n<p>Here&#8217;s my example Azure Pipelines file:<\/p>\n<pre><code class=\"yaml\">trigger:\n- master\n\npool:\n  vmImage: 'ubuntu-latest'\nstrategy:\n  matrix:\n    Python35:\n      python.version: '3.5'\n    Python36:\n      python.version: '3.6'\n    Python37:\n      python.version: '3.7'\n\nsteps:\n- task: UsePythonVersion@0\n  inputs:\n    versionSpec: '$(python.version)'\n  displayName: 'Use Python $(python.version)'\n\n- script: |\n    python -m pip install --upgrade pip\n    pip install coverage\n  displayName: 'Install coverage'\n\n- script: |\n    coverage run tests.py\n  displayName: 'Run tests'\n\n- script: |\n    bash &lt;(curl -s https:\/\/codecov.io\/bash)\n  displayName: 'Upload to codecov.io'\n<\/code><\/pre>\n<h2>Showing it off<\/h2>\n<p>After I install the Codecov GitHub app and run this pipeline, Codecov handles the rest for me. Here&#8217;s an example of the graphs it generates:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/codecov-screen.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/codecov-screen-1024x670.png\" alt=\"Screen shot of the Codecov dashboard\" width=\"640\" height=\"419\" class=\"alignnone size-large wp-image-58081\" srcset=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/codecov-screen-1024x670.png 1024w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/codecov-screen-300x196.png 300w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/codecov-screen-768x502.png 768w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2019\/11\/codecov-screen.png 1162w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>I get ongoing coverage reports without having to add or manage secrets in my pipeline. Thanks to the folks over at Codecov for adding Azure Pipelines to their tokenless upload infrastructure.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Codecov.io added tokenless uploading of coverage results for public Azure Pipelines.<\/p>\n","protected":false},"author":719,"featured_media":58085,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[224,226],"tags":[],"class_list":["post-58080","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-ci"],"acf":[],"blog_post_summary":"<p>Codecov.io added tokenless uploading of coverage results for public Azure Pipelines.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/58080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/719"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=58080"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/58080\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/58085"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=58080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=58080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=58080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}