diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 53ce7d0d..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,140 +0,0 @@ -# GitHub Actions configuration **EXAMPLE**, -# MODIFY IT ACCORDING TO YOUR NEEDS! -# Reference: https://docs.github.com/en/actions - -name: tests - -on: - push: - # Avoid using all the resources/limits available by checking only - # relevant branches and tags. Other branches can be checked via PRs. - branches: [main, hotfix/hackathon] - tags: - - 'v[0-9]+\.[0-9]+\.[0-9]+\.dev[0-9]+' # Match tags that resemble a version - - 'v[0-9]+\.[0-9]+\.[0-9]+' # Match tags that resemble a version - pull_request: # Run in every PR - workflow_dispatch: # Allow manually triggering the workflow - schedule: - # Run roughly every 15 days at 00:00 UTC - # (useful to check if updates on dependencies break the package) - - cron: '0 0 1,16 * *' - -concurrency: - group: >- - ${{ github.workflow }}-${{ github.ref_type }}- - ${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -jobs: - prepare: - runs-on: ubuntu-latest - outputs: - wheel-distribution: ${{ steps.wheel-distribution.outputs.path }} - steps: - - uses: actions/checkout@v3 - with: {fetch-depth: 0} # deep clone for setuptools-scm - - uses: actions/setup-python@v4 - id: setup-python - with: {python-version: "3.11"} - - name: Run static analysis and format checkers - run: pipx run pre-commit run --all-files --show-diff-on-failure - - name: Build package distribution files - run: >- - pipx run --python '${{ steps.setup-python.outputs.python-path }}' - tox -e clean,build - - name: Record the path of wheel distribution - id: wheel-distribution - run: echo "path=$(ls dist/*.whl)" >> $GITHUB_OUTPUT - - name: Store the distribution files for use in other stages - # `tests` and `publish` will use the same pre-built distributions, - # so we make sure to release the exact same package that was tested - uses: actions/upload-artifact@v3 - with: - name: python-distribution-files - path: dist/ - retention-days: 1 - - test: - needs: prepare - strategy: - matrix: - python: - - "3.10" - # - "3.7" # oldest Python supported by PSF - - "3.11" # newest Python that is stable - platform: - - ubuntu-latest - # - macos-latest - # - windows-latest - runs-on: ${{ matrix.platform }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - id: setup-python - with: - python-version: ${{ matrix.python }} - - name: Retrieve pre-built distribution files - uses: actions/download-artifact@v3 - with: {name: python-distribution-files, path: dist/} - - name: Run tests - run: >- - pipx run --python '${{ steps.setup-python.outputs.python-path }}' - tox --installpkg '${{ needs.prepare.outputs.wheel-distribution }}' - -- -rFEx --durations 10 --color yes # pytest args - # - name: Generate coverage report - # run: pipx run coverage lcov -o coverage.lcov - # - name: Upload partial coverage report - # uses: coverallsapp/github-action@master - # with: - # path-to-lcov: coverage.lcov - # github-token: ${{ secrets.GITHUB_TOKEN }} - # flag-name: ${{ matrix.platform }} - py${{ matrix.python }} - # parallel: true - - finalize: - needs: test - runs-on: ubuntu-latest - steps: - - run: echo "Finished checks" - - publish: - needs: finalize - if: ${{ github.event_name == 'push' && contains(github.ref, 'refs/tags/v') }} - runs-on: ubuntu-latest - environment: - name: release - url: https://pypi.org/project/flexmeasures-client/ - permissions: - id-token: write - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: {python-version: "3.11"} - - name: Retrieve pre-built distribution files - uses: actions/download-artifact@v3 - with: {name: python-distribution-files, path: dist/} - - name: Publish Package - uses: pypa/gh-action-pypi-publish@release/v1 - # run: pipx run tox -e publish - - # test-publish: - # needs: finalize - # if: ${{ github.event_name == 'push' && contains(github.ref, 'refs/tags/test') }} - # runs-on: ubuntu-latest - # environment: - # name: testpypi - # url: https://test.pypi.org/project/flexmeasures-client/ - # permissions: - # id-token: write - # steps: - # - uses: actions/checkout@v3 - # - uses: actions/setup-python@v4 - # with: {python-version: "3.11"} - # - name: Retrieve pre-built distribution files - # uses: actions/download-artifact@v3 - # with: {name: python-distribution-files, path: dist/} - # - name: Publish Package - # uses: pypa/gh-action-pypi-publish@release/v1 - # with: - # repository-url: https://test.pypi.org/legacy/ - # # run: pipx run tox -e publish diff --git a/.github/workflows/sync-fork.yml b/.github/workflows/sync-fork.yml new file mode 100644 index 00000000..42ba3805 --- /dev/null +++ b/.github/workflows/sync-fork.yml @@ -0,0 +1,89 @@ +name: Sync fork + +on: + workflow_dispatch: {} + schedule: + - cron: "15 3 * * *" # Run every day at 3:15 UTC + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout fork's default branch + uses: actions/checkout@v4 + with: + fetch-depth: 0 + path: "fork" + token: ${{ secrets.GH_PAT }} + - name: Checkout fork's configuration branch + uses: actions/checkout@v4 + with: + path: "configuration" + ref: "renovate-and-workflow-files" + token: ${{ secrets.GH_PAT }} + - name: Determine Upstream clone URL + id: upstream-repo-clone-url + uses: actions/github-script@v7 + with: + script: | + const { data } = await github.rest.repos.get({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + if (data.fork) { + return data.parent.clone_url; + } else { + throw new Error('This repository is not a fork.'); + } + result-encoding: string + - name: Determine Upstream default branch + id: upstream-repo-default-branch + uses: actions/github-script@v7 + with: + script: | + const { data } = await github.rest.repos.get({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + if (data.fork) { + return data.parent.default_branch; + } else { + throw new Error('This repository is not a fork.'); + } + result-encoding: string + - name: Sync fork with upstream + run: | + set -ex + cd fork + git config --global user.name "github-actions[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git remote add upstream ${{ steps.upstream-repo-clone-url.outputs.result }} + git fetch upstream ${{ steps.upstream-repo-default-branch.outputs.result }} + UPSTREAM_MOST_RECENT_COMMIT_HASH=$(git log upstream/${{ steps.upstream-repo-default-branch.outputs.result }} -n 1 --format="%H") + PREVIOUS_SYNC_COMMIT_HASH=$(cat ../configuration/upstream_commit_hash) + if [ "$PREVIOUS_SYNC_COMMIT_HASH" = "$UPSTREAM_MOST_RECENT_COMMIT_HASH" ]; then + echo "No need to sync, already up-to-date" + exit 0 + fi + + git reset --hard upstream/${{ steps.upstream-repo-default-branch.outputs.result }} + # Enforce the usage of our own config (renovate.json5) + git rm renovate.json* || true + # Avoid problems where an existing .gitignore file would prevent committing our configuration files + git rm .gitignore || true + # Delete existing workflows, we don't need to run them in our fork + rm -rf .github || true + # Instead of using "cp -r", rsync allows us to exclude the .git directory + rsync -av --exclude '.git' ../configuration/ . + rm upstream_commit_hash + git add . + git commit -m "add Renovate and custom workflow files" + git push --force-with-lease + + cd ../configuration + # git config user.name "github-actions[bot]" + # git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + echo $UPSTREAM_MOST_RECENT_COMMIT_HASH > upstream_commit_hash + git add upstream_commit_hash + git commit -m "update commit hash to $UPSTREAM_MOST_RECENT_COMMIT_HASH" + git push diff --git a/.github/workflows/trivy-dependencies-submission.yml b/.github/workflows/trivy-dependencies-submission.yml new file mode 100644 index 00000000..71f59af7 --- /dev/null +++ b/.github/workflows/trivy-dependencies-submission.yml @@ -0,0 +1,27 @@ +name: SBOM upload from Trivy + +on: + workflow_dispatch: {} + schedule: + - cron: "0 9 */5 * *" # Run every fifth day at 9 AM UTC + +jobs: + SBOM-upload: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Run Trivy vulnerability scanner in repo mode + uses: aquasecurity/trivy-action@0.23.0 + with: + scan-type: 'fs' + ignore-unfixed: true + format: 'github' + output: 'trivy-results.gsbom' + github-pat: ${{ secrets.GITHUB_TOKEN }} # this causes a curl call to upload the snapshot + + - name: Upload report file + uses: actions/upload-artifact@v4 + with: + name: trivy-results + path: trivy-results.gsbom diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0bddc39e..00000000 --- a/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -# Temporary and binary files -*~ -*.py[cod] -*.so -*.cfg -!.isort.cfg -!setup.cfg -*.orig -*.log -*.pot -__pycache__/* -.cache/* -.*.swp -*/.ipynb_checkpoints/* -.DS_Store - -# Project files -.ropeproject -.project -.pydevproject -.settings -.idea -.vscode -tags - -# Package files -*.egg -*.eggs/ -.installed.cfg -*.egg-info - -# Unittest and coverage -htmlcov/* -.coverage -.coverage.* -.tox -junit*.xml -coverage.xml -.pytest_cache/ - -# Build and docs folder/files -build/* -dist/* -sdist/* -docs/api/* -docs/_rst/* -docs/_build/* -cover/* -MANIFEST - -# Per-project virtualenvs -.venv*/ -.conda*/ -.python-version - -venv/* diff --git a/renovate.json5 b/renovate.json5 new file mode 100644 index 00000000..53fe2ac3 --- /dev/null +++ b/renovate.json5 @@ -0,0 +1,12 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + ":disableRateLimiting" + ], + "labels": ["dependencies", "depManager:{{{manager}}}"], + "vulnerabilityAlerts": { + "labels": ["security", "dependencies", "depManager:{{{manager}}}"], + }, + "forkProcessing": "enabled" +}