From 7e8f879a4664b749a98298d03901056411dd4fcc Mon Sep 17 00:00:00 2001 From: Hugo Hakim Damer Date: Wed, 18 Dec 2024 15:11:40 +0100 Subject: [PATCH] feat(ci): build and deploy docs, update READMEs accordingly --- .github/workflows/report.yml | 196 +++++++++++++++++++---------------- .github/workflows/test.yml | 9 +- README.md | 7 +- libcoap-sys/README.md | 5 + libcoap/README.md | 30 +----- 5 files changed, 122 insertions(+), 125 deletions(-) mode change 100644 => 120000 libcoap/README.md diff --git a/.github/workflows/report.yml b/.github/workflows/report.yml index 5d5d03d3..bbc31e00 100644 --- a/.github/workflows/report.yml +++ b/.github/workflows/report.yml @@ -1,9 +1,9 @@ -name: Generate and Provide Reports +name: Docs, Coverage Report and PR updates # WARNING: This Workflow is executed with the workflow_run trigger, which means that # it is run in the context of the target/upstream repository and granted *write access* # to the target/upstream repository. -# It should *only* be used for actions that require write access (e.g., to generate/deploy +# It *should only* be used for actions that require write access (e.g., to generate/deploy # the documentation/coverage report to GitHub Pages or to create a PR comment) and *must # never* execute code contained in the repository. @@ -19,81 +19,83 @@ env: RUST_TEST_TIME_UNIT: 60,120 RUST_TEST_TIME_INTEGRATION: 60,120 RUST_TEST_TIME_DOCTEST: 60,120 + BRANCH: |- + ${{ + (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) + && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) + || github.event.workflow_run.head_branch + }} + HEAD_REF: ${{ github.event.workflow_run.head_sha }} + REPO_URL: "${{ github.server_url }}/${{ github.repository }}" + +concurrency: + # env context is not available here, so i just copied the code for env.BRANCH. + group: ${{ github.workflow }}-${{ + (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) + && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) + || github.event.workflow_run.head_branch + }} + cancel-in-progress: true jobs: - #lint: - # name: lint - # runs-on: ubuntu-latest - # env: - # BRANCH: |- - # ${{ - # (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) - # && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) - # || github.event.workflow_run.head_branch - # }} - # strategy: - # matrix: - # crate: [ libcoap-sys, libcoap-rs ] - # steps: - # - uses: actions/checkout@v4 - # with: - # submodules: true - # ref: ${{ env.BRANCH }} - # - uses: reviewdog/action-setup@v1 - # with: - # reviewdog_version: latest - # - uses: dtolnay/rust-toolchain@stable - # with: - # components: clippy - # - uses: baptiste0928/cargo-install@v3 - # with: - # crate: clippy-reviewdog-filter - # - env: - # REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # run: reviewdog -reporter=github-pr-check -fail-level=any - #fmt: - # name: rustfmt - # runs-on: ubuntu-latest - # env: - # BRANCH: |- - # ${{ - # (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) - # && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) - # || github.event.workflow_run.head_branch - # }} - # strategy: - # fail-fast: false - # matrix: - # crate: [ libcoap-sys, libcoap-rs ] - # steps: - # - uses: actions/checkout@v4 - # with: - # ref: ${{ env.BRANCH }} - # - uses: dtolnay/rust-toolchain@stable - # with: - # components: rustfmt - # - run: cargo fmt -p ${{ matrix.crate }} - # - name: Generate PR suggestions from rustfmt changes - # uses: reviewdog/action-suggester@v1 - # with: - # tool_name: rustfmt - # fail_on_error: true - # reviewdog_args: -reporter=github-pr-check + docs: + runs-on: ubuntu-latest + outputs: + docs_dl: ${{ format('{0}/actions/runs/{1}/artifacts/{2}', env.REPO_URL, github.run_id, steps.upload-docs.outputs.artifact-id) }} + docs_url: |- + ${{ + (github.event.workflow_run.head_repository.owner.login == github.event.workflow_run.repository.owner.login) + && format('{0}/docs/{1}/libcoap_rs/', vars.DOCS_AND_COV_URL, env.BRANCH) + || '' + }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + ref: ${{ env.HEAD_REF }} + # --all-features uses GNUTLS as backend, must provide it. + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: libgnutls28-dev libgnutls30 + version: 1.0 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rustc + - name: Build documentation + run: cargo doc --all-features --no-deps --workspace + - uses: actions/upload-artifact@v4 + id: upload-docs + with: + name: docs + path: | + ./target/doc + # Deploy to GitHub Pages only if the PR is not from a forked repository. + # For security reasons, we don't want PRs from forks to upload coverage data to our GitHub Pages. + - if: ${{ github.event.workflow_run.head_repository.owner.login == github.event.workflow_run.repository.owner.login }} + uses: peaceiris/actions-gh-pages@v4 + with: + publish_dir: ./target/doc + publish_branch: main + external_repository: ${{ vars.DOCS_AND_COV_REPO }} + personal_token: ${{ secrets.DOCS_AND_COV_REPO_TOKEN }} + destination_dir: docs/${{ env.BRANCH }} coverage-report: name: coverage-report runs-on: ubuntu-latest - env: + env: LLVM_PROFILE_FILE: './coverage-data/coverage/libcoap-rs-%p-%m.profraw' - BRANCH: |- - ${{ - (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) - && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) - || github.event.workflow_run.head_branch - }} outputs: report: ${{ steps.cov-report.outputs.summary }} + report_dl: ${{ format('{0}/actions/runs/{1}/artifacts/{2}', env.REPO_URL, github.run_id, steps.upload-cov-report.outputs.artifact-id) }} + report_url: |- + ${{ + (github.event.workflow_run.head_repository.owner.login == github.event.workflow_run.repository.owner.login) + && format('{0}/coverage/{1}', vars.DOCS_AND_COV_URL, env.BRANCH) + || '' + }} + badge_url: ${{ format('{0}/coverage/{1}/badges/flat.svg', vars.DOCS_AND_COV_URL, env.BRANCH) }} permissions: actions: write contents: write @@ -101,7 +103,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - ref: ${{ env.BRANCH }} + ref: ${{ env.HEAD_REF }} - uses: actions/download-artifact@v4 with: pattern: test-coverage-data-* @@ -127,47 +129,58 @@ jobs: echo "$EOF" } >> "$GITHUB_OUTPUT" - uses: actions/upload-artifact@v4 + id: upload-cov-report with: name: coverage-report path: | ./coverage # Deploy to GitHub Pages only if the PR is not from a forked repository. - # For security reasons, we don't want PRs from forked PRs to upload coverage data to our GitHub Pages. + # For security reasons, we don't want PRs from forks to upload coverage data to our GitHub Pages. - if: ${{ github.event.workflow_run.head_repository.owner.login == github.event.workflow_run.repository.owner.login }} uses: peaceiris/actions-gh-pages@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./coverage/html - publish_branch: _gh_pages + publish_branch: main + external_repository: ${{ vars.DOCS_AND_COV_REPO }} + personal_token: ${{ secrets.DOCS_AND_COV_REPO_TOKEN }} destination_dir: coverage/${{ env.BRANCH }} + # For PRs from forks, only upload the generated badge. + - if: ${{ github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login }} + uses: peaceiris/actions-gh-pages@v4 + with: + publish_dir: ./coverage/html/badges + publish_branch: main + external_repository: ${{ vars.DOCS_AND_COV_REPO }} + personal_token: ${{ secrets.DOCS_AND_COV_REPO_TOKEN }} + destination_dir: coverage/${{ env.BRANCH }}/badges pr-comment: name: pr-comment runs-on: ubuntu-latest + # All other jobs here should also run on a push to main. This one is specific to pull requests, however. if: ${{ always() && github.event.workflow_run.event == 'pull_request' }} - needs: [ fmt ] + needs: [ coverage-report, docs ] env: COV_OUTPUT: ${{ needs.coverage-report.outputs.report }} + COV_DL: ${{ needs.coverage-report.outputs.report_dl }} + COV_BADGE: ${{ needs.coverage-report.outputs.badge_url }} + DOCS_DL: ${{ needs.docs.outputs.docs_dl }} + COV_URL: ${{ needs.coverage-report.outputs.report_url }} + DOCS_URL: ${{ needs.docs.outputs.docs_url }} + # Token required for GH CLI: + GH_TOKEN: ${{ github.token }} + # Best practice for scripts is to reference via ENV at runtime. Avoid using the expression syntax in the script content directly: + PR_TARGET_REPO: ${{ github.repository }} steps: + - uses: actions/checkout@v4 + with: + submodules: false # See https://github.com/orgs/community/discussions/25220#discussioncomment-11316244 - name: 'Get PR context' id: pr-context - env: - # Token required for GH CLI: - GH_TOKEN: ${{ github.token }} - # Best practice for scripts is to reference via ENV at runtime. Avoid using the expression syntax in the script content directly: - PR_TARGET_REPO: ${{ github.repository }} - PR_TARGET_REPO_URL: ${{ github.server_url }}/${{ github.repository }} - # If the PR is from a fork, prefix it with `:`, otherwise only the PR branch name is relevant: - PR_BRANCH: |- - ${{ - (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) - && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) - || github.event.workflow_run.head_branch - }} # Query the PR number by repo + branch, then assign to step output: run: | - gh pr view --repo "${PR_TARGET_REPO}" "${PR_BRANCH}" \ + gh pr view --repo "${PR_TARGET_REPO}" "${BRANCH}" \ --json 'number' --jq '"number=\(.number)"' \ >> "${GITHUB_OUTPUT}" - name: "Generate Markdown Report" @@ -179,12 +192,19 @@ jobs: echo "# Workflow Status Report" echo "Generated for commit ${{ github.sha }} on `date -u`." echo "" - echo "[![Test and Analyze](${PR_TARGET_REPO_URL}/actions/workflows/test.yml/badge.svg?branch=${GITHUB_HEAD_REF}&hash=${{ github.sha }})](${PR_TARGET_REPO_URL}/actions/workflows/test.yml?query=branch%3A${PR_BRANCH})" + echo "[![Test and Analyze](${REPO_URL}/actions/workflows/test.yml/badge.svg?branch=${GITHUB_HEAD_REF}&hash=${{ github.sha }})](${REPO_URL}/actions/workflows/test.yml?query=branch%3A${BRANCH})" + echo "[![Docs, Coverage Report and PR Updates](${REPO_URL}/actions/workflows/report.yml/badge.svg?branch=${GITHUB_HEAD_REF}&hash=${{ github.sha }})](${REPO_URL}/actions/workflows/report.yml?query=branch%3A${BRANCH})" echo "" echo "In case of failure, clippy warnings and rustfmt changes (if any) will be indicated as CI check warnings in the file comparison view." echo "" + echo "Documentation: ${{ (env.DOCS_URL != '') && format('[Read Online]({0})', env.DOCS_URL) || '' }} [Download](${DOCS_DL})" + echo "" + echo "Coverage Report: ${{ (env.COV_URL != '') && format('[Read Online]({0})', env.COV_URL) || '' }} [Download](${COV_DL})" + echo "" + echo "Note: Online versions of documentation and coverage reports may not be available indefinitely, especially after the pull request was merged." + echo "" echo "## Code Coverage Report" - echo "[![Coverage](https://namib-project.github.io/libcoap-rs/coverage/${{ github.event.workflow_run.head_branch }}/badges/flat.svg?hash=${{ github.sha }})](https://namib-project.github.io/libcoap-rs/coverage/${{ github.event.workflow_run.head_branch }})" + echo "[![Coverage](${COV_BADGE}?hash=${{ github.sha }})](${{ (env.COV_URL == '') && env.COV_DL || env.COV_URL}})" echo "" echo "Coverage target is 80%." echo "" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 75af9529..8a821aba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,12 +21,9 @@ jobs: strategy: fail-fast: false matrix: - crate: [libcoap-rs] - dtls_backend: [gnutls] - rust_version: [nightly] - #crate: [ libcoap-sys, libcoap-rs ] - #dtls_backend: [ openssl, gnutls, tinydtls, mbedtls ] - #rust_version: [ msrv, stable, nightly ] + crate: [ libcoap-sys, libcoap-rs ] + dtls_backend: [ openssl, gnutls, tinydtls, mbedtls ] + rust_version: [ msrv, stable, nightly ] env: LLVM_PROFILE_FILE: "${{ github.workspace }}/coverage-data/coverage/libcoap-rs-%p-%m.profraw" RUSTFLAGS: "${{ matrix.rust_version == 'nightly' && '-Cinstrument-coverage -Cpanic=abort -Zpanic_abort_tests' || ' ' }}" diff --git a/README.md b/README.md index 9e2efb6f..f5d4a6c4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # libcoap-rs -[![CI Status](https://github.com/namib-project/libcoap-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/namib-project/libcoap-rs/actions/workflows/ci.yml) -![Coverage](https://namib-project.github.io/libcoap-rs/coverage/main/badges/flat.svg) +[![latest release on crates.io](https://img.shields.io/crates/v/libcoap_rs)](https://crates.io/crates/libcoap-rs) +[![Documentation (latest release)](https://img.shields.io/badge/docs-latest_release-blue)](https://docs.rs/libcoap_rs/) +[![Documentation (main)](https://img.shields.io/badge/docs-main-blue)](https://namib-project.github.io/libcoap-rs-docs/docs/main/libcoap_rs/) +[![Test and Analyze CI Status](https://github.com/namib-project/libcoap-rs/actions/workflows/test.yml/badge.svg)](https://github.com/namib-project/libcoap-rs/actions/workflows/test.yml) +[![Coverage (main)](https://namib-project.github.io/libcoap-rs-docs/coverage/main/badges/flat.svg)](https://namib-project.github.io/libcoap-rs-docs/coverage/main/) Raw binding and safe wrapper for the [libcoap CoAP libary](https://github.com/obgm/libcoap). diff --git a/libcoap-sys/README.md b/libcoap-sys/README.md index b334dfa8..37bfa91c 100644 --- a/libcoap-sys/README.md +++ b/libcoap-sys/README.md @@ -1,4 +1,9 @@ # libcoap-sys - Raw bindings for libcoap +[![latest release on crates.io](https://img.shields.io/crates/v/libcoap_sys)](https://crates.io/crates/libcoap-sys) +[![Documentation (latest release)](https://img.shields.io/badge/docs-latest_release-blue)](https://docs.rs/libcoap_sys/) +[![Documentation (main)](https://img.shields.io/badge/docs-main-blue)](https://namib-project.github.io/libcoap-rs-docs/docs/main/libcoap_sys/) +[![Test and Analyze CI Status](https://github.com/namib-project/libcoap-rs/actions/workflows/test.yml/badge.svg)](https://github.com/namib-project/libcoap-rs/actions/workflows/test.yml) +[![Coverage (main)](https://namib-project.github.io/libcoap-rs-docs/coverage/main/badges/flat.svg)](https://namib-project.github.io/libcoap-rs-docs/coverage/main/) This crate contains raw unsafe bindings for the [libcoap CoAP libary](https://github.com/obgm/libcoap), which are generated using bindgen. diff --git a/libcoap/README.md b/libcoap/README.md deleted file mode 100644 index fc458407..00000000 --- a/libcoap/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# libcoap-rs - -Idiomatic wrapper around the [libcoap CoAP libary](https://github.com/obgm/libcoap) for Rust. - -## License - -Matching the license of the libcoap C library, the libcoap crate is licensed under the -2-Clause/Simplified BSD License ([LICENSE-BSD-2-Clause](LICENSE-BSD-2-CLAUSE) -or https://opensource.org/licenses/BSD-2-Clause). - -### Note on Third-Party-Code - -Note that for the libcoap-sys binding and generated binaries, the license terms of the libcoap C library as well as -linked dependencies (e.g. TLS libraries) may apply. -See https://github.com/obgm/libcoap/blob/develop/LICENSE as well as the licenses of dependency crates for more -information and terms. - -## Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, shall be licensed as above, without any additional terms or conditions. - -## Maintainers - -This project is currently maintained by the following developers: - -| Name | Email Address | GitHub Username | -|:----------------:|:--------------------:|:--------------------------------------------:| -| Hugo Hakim Damer | hdamer@uni-bremen.de | [@pulsastrix](https://github.com/pulsastrix) | diff --git a/libcoap/README.md b/libcoap/README.md new file mode 120000 index 00000000..32d46ee8 --- /dev/null +++ b/libcoap/README.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file