diff --git a/.github/actionlint.yml b/.github/actionlint.yml new file mode 100644 index 0000000..8d37bac --- /dev/null +++ b/.github/actionlint.yml @@ -0,0 +1,5 @@ +--- +paths: + .github/workflows/**/*.{yml,yaml}: + ignore: + - 'shellcheck reported issue in this script: SC1083:.+' diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e454b4f..130cbe0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,23 +1,24 @@ +--- version: 2 updates: -- package-ecosystem: github-actions - directory: "/" - schedule: - interval: daily - time: '04:00' - timezone: Europe/Copenhagen - open-pull-requests-limit: 10 -- package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - time: '04:00' - timezone: Europe/Copenhagen - open-pull-requests-limit: 10 -- package-ecosystem: docker - directory: "/" - schedule: - interval: daily - time: '04:00' - timezone: Europe/Copenhagen - open-pull-requests-limit: 10 + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + time: '04:00' + timezone: Europe/Copenhagen + open-pull-requests-limit: 10 + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + time: '04:00' + timezone: Europe/Copenhagen + open-pull-requests-limit: 10 + - package-ecosystem: docker + directory: "/" + schedule: + interval: daily + time: '04:00' + timezone: Europe/Copenhagen + open-pull-requests-limit: 10 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96bf5c7..cf76e07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,57 +1,49 @@ -on: -- push +--- +on: push name: Build and test permissions: - contents: read + contents: write jobs: - go-version: - name: Lookup go versions + build_and_test: + name: Build and test runs-on: ubuntu-24.04 - outputs: - minimal: ${{ steps.go-version.outputs.minimal }} - matrix: ${{ steps.go-version.outputs.matrix }} steps: - - uses: actions/checkout@v6 - - uses: arnested/go-version-action@v1 - id: go-version - go_generate: - name: Check generated code is up to date - needs: go-version + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Run go test + uses: robherley/go-test-action@v0.7.1 + with: + testArguments: -race -cover -covermode=atomic -coverprofile=coverage.txt ./... + - name: Install changelog management tool + run: go install github.com/goreleaser/chglog/cmd/chglog@main + - name: Build changelog + run: chglog init + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + args: release --snapshot + + nilaway: + name: Nilaway runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 - - name: Install Go ${{ needs.go-version.outputs.minimal }} - uses: actions/setup-go@v6 - with: - go-version: ${{ needs.go-version.outputs.minimal }} - - run: go version - - name: go generate - env: - GO111MODULE: 'on' - run: go generate -x - - name: Diff after go generate - run: git diff --exit-code - build_and_test: - name: Build and test - needs: go-version - runs-on: macos-latest - strategy: - matrix: - go-version: ${{ fromJSON(needs.go-version.outputs.matrix) }} - steps: - - uses: actions/checkout@v6 - - name: Install Go ${{ matrix.go-version }} - uses: actions/setup-go@v6 - with: - go-version: ${{ matrix.go-version }}.x - - run: go version - - name: go test - env: - GO111MODULE: 'on' - # We enable cgo to be able to test with `-race`. - CGO_ENABLED: 1 - run: go test -v -race -cover -covermode=atomic -coverprofile=coverage.txt ./... - - name: Upload coverage report to Codecov - uses: codecov/codecov-action@v5 - with: - flags: go${{ matrix.go-version }} + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Install nilaway + run: go install go.uber.org/nilaway/cmd/nilaway@latest + - name: Run nilaway + run: nilaway ./... diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 4c67c12..91928c2 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,3 +1,4 @@ +--- name: 'Dependency Review' on: [pull_request] diff --git a/.github/workflows/docker-image-security-scan.yml b/.github/workflows/docker-image-security-scan.yml deleted file mode 100644 index 8cbe2fb..0000000 --- a/.github/workflows/docker-image-security-scan.yml +++ /dev/null @@ -1,34 +0,0 @@ -on: push -name: Docker image security scan -permissions: - security-events: write - actions: read -jobs: - security-scan: - name: Docker build and scan - if: '!github.event.deleted' - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v6 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@master - - name: Build Docker image - uses: docker/build-push-action@v6 - with: - builder: ${{ steps.buildx.outputs.name }} - tags: ${{ github.repository }}:test - push: false - load: true - - name: Scan Docker image - uses: anchore/scan-action@v7 - id: scan - with: - image: ${{ github.repository }}:test - acs-report-enable: true - fail-build: true - - name: Upload Anchore scan SARIF report - uses: github/codeql-action/upload-sarif@v4 - if: ${{ always() }} - with: - sarif_file: ${{ steps.scan.outputs.sarif }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5d6e30b..ae56f3c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,3 +1,4 @@ +--- name: Lint on: pull_request @@ -5,6 +6,12 @@ permissions: contents: read jobs: + actionlint: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + - uses: reviewdog/action-actionlint@v1 + dockerfile: name: dockerfile runs-on: ubuntu-24.04 @@ -19,9 +26,9 @@ jobs: name: markdown runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 - - name: Run markdownlint - uses: DavidAnson/markdownlint-cli2-action@v22 + - uses: actions/checkout@v6 + - name: Run markdownlint + uses: DavidAnson/markdownlint-cli2-action@v22 golangci: name: lint @@ -40,3 +47,13 @@ jobs: with: version: latest only-new-issues: true + + yamllint: + name: Yamllint + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + - name: Run Yamllint + uses: frenck/action-yamllint@v1.5.0 + with: + strict: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b67c92d..ba33980 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,4 @@ +--- name: Release on: workflow_run: @@ -15,99 +16,89 @@ jobs: bump-version: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - uses: arnested/go-version-action@v1 - id: go-version - - name: Bump version and push tag - uses: anothrNick/github-tag-action@1.75.0 - id: version - env: - GITHUB_TOKEN: ${{ github.token }} - WITH_V: true - DEFAULT_BUMP: patch - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - - name: Set up Go ${{ steps.go-version.outputs.latest }} - uses: actions/setup-go@v6 - with: - go-version: ${{ steps.go-version.outputs.latest }}.x - - run: go version - - name: Install changelog management tool - run: go install github.com/goreleaser/chglog/cmd/chglog@main - - name: Build changelog - run: chglog init - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6 - with: - version: latest - args: release - env: - GITHUB_TOKEN: ${{ github.token }} - - name: Import GPG signing key - run: | - mkdir -p -m 0700 ~/.gnupg/ - printf -- "${{ secrets.GPG_SIGNING_KEY }}" > ~/.gnupg/private-key.asc - gpg --import --no-tty --batch --yes ~/.gnupg/private-key.asc - - name: Copy deb packages into build area - run: | - mkdir -p site - cp -v dist/*.deb site/ - - name: Scan packages - run: | - apt-ftparchive packages . > Packages - gzip -k -f Packages - working-directory: site - - name: apt-ftparchive release - run: | - apt-ftparchive -o APT::FTPArchive::Release::Origin="Arne Jørgensen" -o APT::FTPArchive::Release::Label="${{ steps.go-version.outputs.module }}" release . > Release - echo "Changelogs: $(gh api /repos/{owner}/{repo}/pages --jq .html_url)changelog?path=@CHANGEPATH@" >> Release - gpg -abs --no-tty --batch --yes -o - Release > Release.gpg - gpg --clearsign --no-tty --batch --yes -o - Release > InRelease - working-directory: site - env: - GH_TOKEN: ${{ github.token }} - - uses: ZacJW/markdown-html-action@1.2.0 - with: - input_files: '[["README.md"]]' - output_files: '["README.html"]' - - name: Fix link / package name in GitHub Pages - run: | - DEB=$(grep linux_amd64.deb dist/checksums.txt | awk '{print $2}') - sed -i "s/system-state_.*_linux_amd64.deb/${DEB}<\/a>/" README.html - sed -i 's///' README.html - cat page/header.html README.html page/footer.html > site/index.html - - name: Add changelog to GitHub Pages - run: chglog format --template deb --output site/changelog - - name: Deploy deb packages - uses: JamesIves/github-pages-deploy-action@v4 - with: - branch: gh-pages - folder: site - clean: true - single-commit: true - - name: Post status to Google Chat - if: ${{ always() }} - uses: containrrr/shoutrrr-action@v1 - with: - url: "${{ secrets.WATCHTOWER_NOTIFICATION_URL }}" - message: "Released `${{ github.repository }}`@`${{ github.sha }}` as ${{ steps.version.outputs.tag }}: *${{ job.status }}*." - docker-build: - name: Docker build and push - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v6 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@master - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} - - name: Build and push Docker images - uses: docker/build-push-action@v6 - with: - builder: ${{ steps.buildx.outputs.name }} - tags: ${{ github.repository }}:latest - push: true + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - uses: arnested/go-version-action@v1 + id: go-version + - name: Bump version and push tag + uses: anothrNick/github-tag-action@1.75.0 + id: version + env: + GITHUB_TOKEN: ${{ github.token }} + WITH_V: true + DEFAULT_BUMP: patch + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + - name: Set up Go ${{ steps.go-version.outputs.go-mod-version }} + uses: actions/setup-go@v6 + with: + go-version: ${{ steps.go-version.outputs.go-mod-version }} + - name: Install changelog management tool + run: go install github.com/goreleaser/chglog/cmd/chglog@main + - name: Build changelog + run: chglog init + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + version: latest + args: release + env: + GITHUB_TOKEN: ${{ github.token }} + - name: Import GPG signing key + run: | + mkdir -p ~/.gnupg/ + chmod 0700 ~/.gnupg/ + printf -- "${{ secrets.GPG_SIGNING_KEY }}" > ~/.gnupg/private-key.asc + gpg --import --no-tty --batch --yes ~/.gnupg/private-key.asc + - name: Copy deb packages into build area + run: | + mkdir -p site + cp -v dist/*.deb site/ + - name: Scan packages + run: | + apt-ftparchive packages . > Packages + gzip -k -f Packages + working-directory: site + - name: apt-ftparchive release + run: | + apt-ftparchive -o APT::FTPArchive::Release::Origin="Arne Jørgensen" -o APT::FTPArchive::Release::Label="${{ steps.go-version.outputs.module }}" release . > Release + echo "Changelogs: $(gh api /repos/{owner}/{repo}/pages --jq .html_url)changelog?path=@CHANGEPATH@" >> Release + gpg -abs --no-tty --batch --yes -o - Release > Release.gpg + gpg --clearsign --no-tty --batch --yes -o - Release > InRelease + working-directory: site + env: + GH_TOKEN: ${{ github.token }} + - uses: ZacJW/markdown-html-action@1.2.0 + with: + input_files: '[["README.md"]]' + output_files: '["README.html"]' + - name: Fix link / package name in GitHub Pages + run: | + DEB=$(grep linux_amd64.deb dist/checksums.txt | awk '{print $2}') + sed -i "s/system-state_.*_linux_amd64.deb/${DEB}<\/a>/" README.html + sed -i 's///' README.html + cat page/header.html README.html page/footer.html > site/index.html + - name: Add changelog to GitHub Pages + run: chglog format --template deb --output site/changelog + - name: Deploy deb packages + uses: JamesIves/github-pages-deploy-action@v4 + with: + branch: gh-pages + folder: site + clean: true + single-commit: true + - name: Post status to Google Chat + if: ${{ always() }} + uses: containrrr/shoutrrr-action@v1 + with: + url: "${{ secrets.WATCHTOWER_NOTIFICATION_URL }}" + message: "Released `${{ github.repository }}`@`${{ github.sha }}` as ${{ steps.version.outputs.tag }}: *${{ job.status }}*." diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 2f8d547..6dca771 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -1,3 +1,4 @@ +--- name: Security Checks on: pull_request: @@ -17,8 +18,6 @@ jobs: gosec: name: Golang Security Checker runs-on: ubuntu-24.04 - env: - GO111MODULE: on steps: - name: Checkout Source uses: actions/checkout@v6 @@ -35,19 +34,19 @@ jobs: name: Govulncheck runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 - - name: Setup Go - uses: actions/setup-go@v6 - with: - go-version-file: go.mod - - name: Run govulncheck - uses: arnested/govulncheck-action@main - with: - output-format: sarif - output-file: results.sarif - setup-go: false - repo-checkout: false - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: results.sarif + - uses: actions/checkout@v6 + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Run govulncheck + uses: arnested/govulncheck-action@main + with: + output-format: sarif + output-file: results.sarif + setup-go: false + repo-checkout: false + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: results.sarif diff --git a/.gitignore b/.gitignore index 638a213..348794a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ /dist/ /systemd-state /systemd-state.test +/deb/systemd-state.asc +/site diff --git a/.goreleaser.yml b/.goreleaser.yml index 55ad6e0..e99316c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,13 +1,18 @@ -before: - hooks: - - go mod download +--- +version: 2 builds: - env: - CGO_ENABLED=0 goos: - linux + flags: + - -trimpath + ldflags: + - -s -w -X main.version={{.Tag}} -X main.Date={{.CommitDate}} + mod_timestamp: '{{.CommitTimestamp}}' archives: - - format: binary + - formats: + - binary name_template: >- {{ .ProjectName }}_ {{- if eq .Os "linux" }}Linux @@ -18,7 +23,7 @@ archives: checksum: name_template: 'checksums.txt' snapshot: - name_template: "{{ .Tag }}-next" + version_template: "{{ .Tag }}-next" changelog: sort: asc filters: @@ -28,6 +33,24 @@ changelog: release: prerelease: auto +dockers_v2: + - images: + - 'arnested/{{ .ProjectName }}' + tags: + - '{{ .Tag }}' + - 'v{{ .Major }}' + - 'latest' + sbom: true + labels: + "org.opencontainers.image.created": "{{.CommitDate}}" + "org.opencontainers.image.revision": "{{.FullCommit}}" + "org.opencontainers.image.source": "https://github.com/arnested/{{.ProjectName}}" + "org.opencontainers.image.title": "systemd state http server" + "org.opencontainers.image.description": "A small HTTP server exposing the overall state of systemd" + "org.opencontainers.image.version": "{{.Version}}" + "org.opencontainers.image.licenses": "MIT" + "org.opencontainers.image.authors": "Arne Jørgensen " + nfpms: - vendor: Arne Jørgensen diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..764b57d --- /dev/null +++ b/.yamllint @@ -0,0 +1,17 @@ +--- +extends: default + +ignore-from-file: + - .gitignore + +rules: + indentation: + spaces: 2 + line-length: disable + truthy: + check-keys: false + braces: + min-spaces-inside: 1 + max-spaces-inside: 1 + min-spaces-inside-empty: 0 + max-spaces-inside-empty: 0 diff --git a/Dockerfile b/Dockerfile index c430a73..264fcb2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,11 @@ -FROM golang:1.25.5-alpine AS build-env - -WORKDIR /build - -ENV GO111MODULE=on -ENV CGO_ENABLED=0 -ENV GOOS=linux - -COPY *.go go.mod go.sum /build/ - -RUN apk --no-cache add git=~2 && \ - go version && \ - go build -ldflags '-s -w' && \ - go test -o ./systemd-state.test -v -cover -ldflags '-s -w' - FROM scratch EXPOSE 80 -ENV PATH=/ +ARG TARGETPLATFORM +COPY $TARGETPLATFORM/systemd-state /systemd-state -COPY --from=build-env /build/systemd-state /systemd-state -COPY --from=build-env /build/systemd-state.test /test HEALTHCHECK CMD ["/systemd-state", "-healthcheck"] -ENTRYPOINT ["systemd-state"] - -LABEL \ - org.opencontainers.image.title="systemd state http server" \ - org.opencontainers.image.description="A small HTTP server exposing the overall state of systemd" \ - org.opencontainers.image.licenses="MIT" \ - org.opencontainers.image.authors="Arne Jørgensen " +ENTRYPOINT ["/systemd-state"] diff --git a/go.mod b/go.mod index c45437d..245b99f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/arnested/systemd-state -go 1.23 +go 1.25.5 require ( github.com/coreos/go-systemd/v22 v22.6.0