diff --git a/.github/actions/build-chisel/action.yml b/.github/actions/build-chisel/action.yml new file mode 100644 index 000000000..c519bc2ca --- /dev/null +++ b/.github/actions/build-chisel/action.yml @@ -0,0 +1,30 @@ +name: "Build chisel" +description: > + Generates the version file and builds chisel from the current project directory. + + The build can be configured via Go environment variables. +outputs: + CHISEL_VERSION: + description: "The chisel version" + value: ${{ steps.build.outputs.chisel-version }} +runs: + using: "composite" + steps: + - id: build + shell: bash + run: | + echo "Generating version file" + go generate ./cmd/ + + echo "Building for $GOOS $GOARCH" + go build -trimpath -ldflags='-s -w' ./cmd/chisel + + # Get version via "chisel version" to ensure it matches that exactly + CHISEL_VERSION=$(GOOS=linux GOARCH=amd64 go run ./cmd/chisel version) + echo "Version: $CHISEL_VERSION" + + # Version should not be "unknown" + [ "$CHISEL_VERSION" != "unknown" ] || exit 1 + + # Share variables with subsequent steps + echo "chisel-version=${CHISEL_VERSION}" >>$GITHUB_OUTPUT diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3d7ed64c..6bcdeb8f8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,28 +51,13 @@ jobs: with: go-version-file: 'go.mod' - - name: Build Chisel for linux/${{ matrix.arch }} + - uses: ./.github/actions/build-chisel/ + name: Build Chisel for linux/${{ matrix.arch }} id: build env: GOOS: "linux" GOARCH: ${{ matrix.arch }} CGO_ENABLED: "0" - run: | - echo "Generating version file" - go generate ./cmd/ - - echo "Building for $GOOS $GOARCH" - go build -trimpath -ldflags='-s -w' ./cmd/chisel - - # Get version via "chisel version" to ensure it matches that exactly - CHISEL_VERSION=$(GOOS=linux GOARCH=amd64 go run ./cmd/chisel version) - echo "Version: $CHISEL_VERSION" - - # Version should not be "unknown" - [ "$CHISEL_VERSION" != "unknown" ] || exit 1 - - # Share variables with subsequent steps - echo "CHISEL_VERSION=${CHISEL_VERSION}" >>$GITHUB_OUTPUT - name: Test if is executable run: test -x ./chisel diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0f2e0425c..d664557c6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,6 +1,23 @@ name: Tests on: + workflow_call: + inputs: + repository: + description: 'Repository name (with owner) to clone' + required: true + type: string + ref: + description: 'The branch, tag or SHA to checkout' + required: true + type: string + outputs: + test-coverage-file: + description: 'The name of the coverage report file' + value: ${{ jobs.unit-tests.outputs.test-coverage-file }} + test-coverage-artifact: + description: 'The name used to upload the coverage file as a GH artifact' + value: ${{ jobs.unit-tests.outputs.test-coverage-artifact }} workflow_dispatch: push: paths-ignore: @@ -14,9 +31,16 @@ jobs: name: Unit Tests env: TEST_COVERAGE_FILE: test-coverage.out + TEST_COVERAGE_ARTIFACT: chisel-test-coverage TEST_COVERAGE_HTML_FILE: test-coverage.html + outputs: + test-coverage-file: ${{ env.TEST_COVERAGE_FILE }} + test-coverage-artifact: ${{ env.TEST_COVERAGE_ARTIFACT }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + ref: ${{ github.event_name == 'workflow_call' && inputs.ref || '' }} + repository: ${{ github.event_name == 'workflow_call' && inputs.repository || '' }} - uses: actions/setup-go@v3 with: @@ -36,13 +60,13 @@ jobs: -o=${TEST_COVERAGE_HTML_FILE} fi - - name: Upload HTML test coverage - uses: actions/upload-artifact@v3 + - name: Upload test coverage + uses: actions/upload-artifact@v4 if: always() continue-on-error: true with: - name: chisel-test-coverage.html - path: ./*.html + name: ${{ env.TEST_COVERAGE_ARTIFACT }} + path: ./test-coverage* real-archive-tests: # Do not change to newer releases as "fips" may not be available there. diff --git a/.github/workflows/tics.yml b/.github/workflows/tics.yml new file mode 100644 index 000000000..bed2a25af --- /dev/null +++ b/.github/workflows/tics.yml @@ -0,0 +1,113 @@ +name: TiCS + +on: + workflow_dispatch: + push: + branches: [main] + # Running on pull_request_target instead of pull_request because this workflow + # uses secrets, and thus we need to ensure it runs under this project's code base. + pull_request_target: + branches: [main] + schedule: + - cron: '0 10 * * *' + +jobs: + set-project: + # This is needed because pull_request_target events will run workflows in + # the context of the base repository (the repository receiving the pull request). + # + # This means that, for such events, we need to explicitly tell the job to + # "action/checkout" the forked repository/ref (aka source of the PR). + name: Set project environment + runs-on: ubuntu-latest + outputs: + ref: ${{ steps.get-ref.outputs.ref }} + repo: ${{ steps.get-repo.outputs.repo }} + steps: + - id: get-ref + run: echo "ref=${{ github.event_name == 'pull_request_target' && github.head_ref || '' }}" >> $GITHUB_OUTPUT + + - id: get-repo + run: echo "repo=${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name || '' }}" >> $GITHUB_OUTPUT + + tics-static-code-analysis: + runs-on: ubuntu-24.04 + name: TiCS Static Code Analysis + needs: [set-project] + permissions: + pull-requests: write + env: + TICS_FILELIST: tics-filelist + TICSPROJECT: chisel + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.set-project.outputs.ref }} + repository: ${{ needs.set-project.outputs.repo }} + + - name: Check changed paths in PR + id: changed-paths + if: github.event_name == 'pull_request_target' + uses: dorny/paths-filter@v3 + with: + filters: | + any: + - "**/*" + list-files: csv + + - id: get-filelist + name: List of files to analyze + run: | + if [[ "${{ github.event_name }}" == "pull_request_target" ]] + then + echo "${{ steps.changed-paths.outputs.any_files }}" | tr "," "\n" > ${TICS_FILELIST} + else + echo "." > ${TICS_FILELIST} + fi + + - uses: actions/setup-go@v4 + with: + go-version-file: 'go.mod' + + - name: Install dependencies + run: | + go install honnef.co/go/tools/cmd/staticcheck@v0.5.1 + go install github.com/axw/gocov/gocov@v1.1.0 + go install github.com/AlekSi/gocov-xml@v1.1.0 + + # We could store a report from the "tests" run, but this is cheap to do and keeps this isolated. + - name: Test and generate coverage report + run: | + go test -coverprofile=coverage.out ./... + gocov convert coverage.out > coverage.json + # The coverage.xml file needs to be in a .coverage folder. + mkdir .coverage + gocov-xml < coverage.json > .coverage/coverage.xml + + - name: Run TiCS client analysis + uses: tiobe/tics-github-action@v3 + if: github.event_name == 'pull_request_target' + with: + mode: 'client' + codetype: 'TESTCODE' + project: ${{ env.TICSPROJECT }} + filelist: ${{ env.TICS_FILELIST }} + branchname: ${{ github.head_ref }} + viewerUrl: 'https://canonical.tiobe.com/tiobeweb/TICS/api/cfg?name=default' + displayUrl: 'https://canonical.tiobe.com/tiobeweb/TICS' + ticsAuthToken: ${{ secrets.TICSAUTHTOKEN }} + installTics: true + + - name: Run TiCS server analysis + uses: tiobe/tics-github-action@v3 + if: github.event_name != 'pull_request_target' + with: + mode: 'qserver' + codetype: 'PRODUCTION' + project: ${{ env.TICSPROJECT }} + branchdir: . + filelist: ${{ env.TICS_FILELIST }} + viewerUrl: 'https://canonical.tiobe.com/tiobeweb/TICS/api/cfg?name=default' + displayUrl: 'https://canonical.tiobe.com/tiobeweb/TICS' + ticsAuthToken: ${{ secrets.TICSAUTHTOKEN }} + installTics: true diff --git a/README.md b/README.md index 14ce897f9..7ad60e2a2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + [![chisel](https://snapcraft.io/chisel/badge.svg)](https://snapcraft.io/chisel) [![Snap](https://github.com/canonical/chisel/actions/workflows/snap.yml/badge.svg?event=release)](https://github.com/canonical/chisel/actions/workflows/snap.yml) [![Build](https://github.com/canonical/chisel/actions/workflows/build.yml/badge.svg)](https://github.com/canonical/chisel/actions/workflows/build.yml) diff --git a/cmd/chisel/cmd_info.go b/cmd/chisel/cmd_info.go index 6c53e4e3d..ce3d64df8 100644 --- a/cmd/chisel/cmd_info.go +++ b/cmd/chisel/cmd_info.go @@ -11,6 +11,7 @@ import ( "github.com/canonical/chisel/internal/setup" ) +// TODO Add --format flag var shortInfoHelp = "Show information about package slices" var longInfoHelp = ` The info command shows detailed information about package slices. diff --git a/internal/fsutil/create.go b/internal/fsutil/create.go index 92b1592fd..9cfd12cd8 100644 --- a/internal/fsutil/create.go +++ b/internal/fsutil/create.go @@ -11,6 +11,7 @@ import ( "path/filepath" ) +// asdasdasdasd type CreateOptions struct { Path string Mode fs.FileMode diff --git a/internal/fsutil/suite_test.go b/internal/fsutil/suite_test.go index 4f90e3952..ea0c21509 100644 --- a/internal/fsutil/suite_test.go +++ b/internal/fsutil/suite_test.go @@ -12,6 +12,7 @@ func Test(t *testing.T) { TestingT(t) } type S struct{} +// asdasdsad var _ = Suite(&S{}) func (s *S) SetUpTest(c *C) {