{"id":28495993,"url":"https://github.com/sonarsource/pycon-sonar-workshop","last_synced_at":"2025-07-02T10:31:16.748Z","repository":{"id":41804328,"uuid":"480728100","full_name":"SonarSource/pycon-sonar-workshop","owner":"SonarSource","description":"PyCon US Sonar Workshop","archived":false,"fork":false,"pushed_at":"2025-05-09T13:06:40.000Z","size":35,"stargazers_count":7,"open_issues_count":1,"forks_count":59,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-06-08T11:51:23.258Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SonarSource.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-04-12T08:53:35.000Z","updated_at":"2025-05-09T13:06:44.000Z","dependencies_parsed_at":"2024-08-23T14:15:56.154Z","dependency_job_id":"8db2b9cc-3b45-4fdf-9983-a93bd95284b1","html_url":"https://github.com/SonarSource/pycon-sonar-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SonarSource/pycon-sonar-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SonarSource%2Fpycon-sonar-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SonarSource%2Fpycon-sonar-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SonarSource%2Fpycon-sonar-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SonarSource%2Fpycon-sonar-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SonarSource","download_url":"https://codeload.github.com/SonarSource/pycon-sonar-workshop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SonarSource%2Fpycon-sonar-workshop/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263120611,"owners_count":23416855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-08T11:38:23.810Z","updated_at":"2025-07-02T10:31:16.739Z","avatar_url":"https://github.com/SonarSource.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Overview\n\nThis is a simple demo project to highlight the analysis of Python on SonarCloud.\n\n## Running the webapp\n\nPython 3 and flask need to be installed in the environment. You can run the following command to install the required dependencies:\n\n```pip install -r requirements.txt```\n\n- Initialize the database with `python init_db.py` (optional: a `database.db` file is already committed in the repository)\n- `cd pokedex` and then simply run the webapp with `flask run`\n\n# Sonar Workshop\n\nWe're going to set up a SonarCloud analysis on this project. We'll visualise issues on the main branch and on pull requests and see how PRs get decorated automatically.\n\nWe'll then set up a CI-based analysis and import code coverage information into the SonarCloud UI.\n\nUseful link: https://docs.sonarcloud.io/\n\n## Getting started\n\n- Fork this repository.\n- A basic workflow which will act as our CI already exists in `.github/workflows/python-app.yml`. It is disabled by default. Go to `Actions` and enable GitHub Actions to activate it.\n- Go to `Pull requests-\u003eNew pull request` and open a pull request from the `add-feature` branch to the `main` branch of your fork. Be careful that, by default, the PR targets the upstream repository.\n- The GitHub Action should run and succeed.\n\n\n## First analysis on SonarCloud\n\nWe'll see how to enable SonarCloud analysis without making any changes to our CI pipeline.\n\n- Go to https://sonarcloud.io/sessions/new and sign up using your GitHub account.\n- Create a new organization under your name and give SonarCloud permission to see the forked repository. \n- Go to `Analyze new project` and select the forked repository.\n\nThe first analysis should execute on the main branch first, then on the pull request. \nThe pull request should be decorated with the analysis result.\n\n## Adding code coverage to the analysis result\n\nBy default, source code is analyzed automatically by SonarCloud. \nAs it is a static analysis tool, it does not execute tests and is not able to compute code coverage by itself.\nYou'll need to generate code coverage information and run the analysis in your CI to be able to import it.\n\n**Note:** for simplicity, the branch `enable-ci-analysis` is already created in this repository with the required changes. From this branch, you only need to:\n* Define a `SONAR_TOKEN` secret in your GitHub repository with a token created in SonarCloud (see [here](#enable-ci-based-analysis)).\n* Replace the placeholders in the `sonar-project.properties` file with your project information.\n* Merge the `enable-ci-analysis` in your main branch, then rebase the feature branch.\n\n### Generate coverage information\nTo generate coverage information, the `.github/workflow/python-app.yml` file should be updated. We'll also need to make sure file paths are set to be relative to avoid any issue when importing the report.\n\n- Clone the repository and open it in your favorite IDE.\n- At the root of the repository, create a `.coveragerc` file containing the following:\n```\n[run]\nsource = pokedex\nbranch = True\nrelative_files = True\n```\n- In the `.github/workflow/python-app.yml`, replace the `pytest` command with:\n \n```pytest --cov --cov-report xml:cov.xml --cov-config=.coveragerc```\n\n\n### Enable CI-based analysis\nWe'll then enable CI-based analysis using the [SonarCloud GitHub Action](https://github.com/marketplace/actions/sonarcloud-scan):\n\n- Go to the overview of your project in SonarCloud.\n- Under `Administration-\u003eAnalysis Method`, turn Automatic Analysis off. \n- Under `GitHub Actions`, click `Follow the tutorial`.\n- Create a `SONAR_TOKEN` in your GitHub repository settings then click `Continue`.\n- To the question \"What option best describes your build?\", select `Other`.\n- Update the `.github/workflow/python-app.yml` file to include the SonarCloud scan. For simplicity, the final file should look like this:\n\n```\n# This workflow will install Python dependencies, run tests and lint with a single version of Python\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions\n\nname: Python application\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\npermissions:\n  contents: read\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v3\n      with:\n        fetch-depth: 0\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v3\n      with:\n        python-version: \"3.10\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install flake8\n        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n    - name: Lint with flake8\n      run: |\n        # stop the build if there are Python syntax errors or undefined names\n        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics\n        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide\n        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics\n    - name: Test with pytest\n      run: |\n        pytest --cov --cov-report xml:cov.xml --cov-config=.coveragerc\n    - name: SonarCloud Scan\n      uses: SonarSource/sonarcloud-github-action@master\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any\n        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}\n```\n\nWe still need to create the analysis configuration file:\n\n- Create a `sonar-project.properties` file the root of the repository. You can copy and paste the following (replace the placeholders with your project and organization keys)\n\n```\nsonar.projectKey={{YOUR_PROJECT_KEY}}\nsonar.organization={{YOUR_ORGANIZATION_KEY}}\n\nsonar.sources=pokedex\nsonar.tests=tests\nsonar.python.coverage.reportPaths=cov.xml\n```\n\nLet's commit this on the main branch and push it by running:\n`git add .` then `git commit -m \"Add CI analysis and coverage\"` and `git push`.\n\nLet's also rebase our PR immediately by running: \n`git checkout add-feature`, `git rebase main` and `git push --force`.\n\nA new analysis should have been triggered for the main branch as well as the pull request. When it's done, we should see the overall coverage for our project as well as the one for our PR.\n\n## (Extra: import Flake8 reports into SonarCloud)\n\nYou're already using tools like Flake8 in your CI and want to visualize its report in the SonarCloud UI?\n\nThis is possible by redirecting flake8 output to a file: `flake8 --output-file=flake8report.txt` and then adding the property\n`sonar.python.flake8.reportPaths=flake8report.txt` to your `sonar-project.properties` file. Note that the report will be displayed as-is and it will not be possible to silence issues from SonarCloud UI.\n\n\n# SonarLint: Fix issues before they exist\n\nIn your IDE, you can install the SonarLint plugin to detect issues before even committing them.\n\n\n## Synchronize issues between SonarCloud and SonarLint\n\nBy default, SonarLint analyses the currently opened file with its default configuration.\nIt means that if you are using a different quality profile on SonarCloud, decided to silence some issues, or have an older version of the analyzer than what is available on SonarCloud there may be discrepancies between the two tools.\n\nTo remedy to that, you can use SonarLint connected mode, which will retrieve your quality profile as well as the silenced issues from SonarCloud to offer you a consistent experience.\n\nFor more information about SonarLint and its connected mode, you can visit the [SonarLint website](https://docs.sonarcloud.io/improving/sonarlint/) as well as the [SonarCloud documentation](https://docs.sonarcloud.io/improving/sonarlint/).\n\n# Final words\n\nThank you for following this workshop!\n\nIf you'd like to know more, feel free to visit [our website](https://sonarsource.com/) or our [community forum](https://community.sonarsource.com/). \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonarsource%2Fpycon-sonar-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsonarsource%2Fpycon-sonar-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonarsource%2Fpycon-sonar-workshop/lists"}