Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/cli-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---

name: CLI Integration Tests
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
merge_group:
types: [ checks_requested ]

permissions:
contents: read

jobs:
cli-smoke-test:
name: CLI smoke tests
runs-on: ubuntu-latest

container: ghcr.io/redhat-plumbers-in-action/differential-shellcheck/test:latest

permissions:
packages: read

steps:
- name: Repository checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
submodules: recursive

- name: Test --help
run: ./src/cli.sh --help

- name: Test --version
run: ./src/cli.sh --version

- name: Test differential scan with explicit commits
run: ./src/cli.sh --base HEAD~2 --head HEAD || true

- name: Test full scan with file arguments
run: ./src/cli.sh --full-scan src/index.sh || true

- name: Test --severity and --display-engine options
run: ./src/cli.sh --severity warning --display-engine csgrep --base HEAD~1 --head HEAD || true
38 changes: 38 additions & 0 deletions .github/workflows/man-page.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---

name: Man Page Build
on:
pull_request:
branches: [ main ]
paths:
- 'docs/differential-shellcheck.1.md'
- 'Makefile'
push:
branches: [ main ]
paths:
- 'docs/differential-shellcheck.1.md'
- 'Makefile'

permissions:
contents: read

jobs:
build-man-page:
name: Build man page from Markdown
runs-on: ubuntu-latest

steps:
- name: Repository checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install pandoc
run: sudo apt-get update && sudo apt-get install -y pandoc

- name: Build man page
run: make man

- name: Verify man page was generated
run: test -f docs/differential-shellcheck.1

- name: Display rendered man page
run: man -l docs/differential-shellcheck.1
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ coverage
.vscode

*.sarif

# Generated man page (built from .md via pandoc)
docs/differential-shellcheck.1
2 changes: 2 additions & 0 deletions .markdownlintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Man page source uses # headings as required by pandoc man page format
docs/differential-shellcheck.1.md
8 changes: 8 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- id: differential-shellcheck
name: Differential ShellCheck
description: Differential static analysis for shell scripts
entry: src/cli.sh
language: script
types: [shell]
require_serial: true
verbose: true
47 changes: 46 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# Docker is default tool for running containers
CONTAINER_TOOL := docker

PREFIX ?= /usr
LIBEXECDIR ?= $(PREFIX)/libexec/differential-shellcheck
BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man/man1
DOCDIR ?= $(PREFIX)/share/doc/differential-shellcheck
LICENSEDIR ?= $(PREFIX)/share/licenses/differential-shellcheck

all: build-test check

podman: CONTAINER_TOOL = podman
Expand All @@ -24,7 +31,7 @@ check-docker:
.PHONY: check check-podman check-docker

# coverage: clean coverage-$(CONTAINER_TOOL)
# Use ulimit -n 524288 as work-around for issue when kcov was using `ulimit -a`: "open files (-n) 1073741816" isntead of "-n: file descriptors 524288"
# Use ulimit -n 524288 as work-around for issue when kcov was using `ulimit -a`: "open files (-n) 1073741816" instead of "-n: file descriptors 524288"
# coverage-podman: CONTAINER_TOOL = podman
# coverage-podman:
# $(CONTAINER_TOOL) container rm -f diff-shellcheck-test
Expand Down Expand Up @@ -62,3 +69,41 @@ clean-podman: CONTAINER_TOOL = podman
clean-podman: clean

.PHONY: clean clean-podman

# --- Man page ---

man: docs/differential-shellcheck.1

docs/differential-shellcheck.1: docs/differential-shellcheck.1.md
pandoc -s -t man $< -o $@

.PHONY: man

# --- Install ---

install: man
install -d $(DESTDIR)$(LIBEXECDIR)
install -m 755 src/index.sh $(DESTDIR)$(LIBEXECDIR)/
install -m 644 src/functions.sh $(DESTDIR)$(LIBEXECDIR)/
install -m 644 src/setup.sh $(DESTDIR)$(LIBEXECDIR)/
install -m 644 src/validation.sh $(DESTDIR)$(LIBEXECDIR)/
install -m 644 src/summary.sh $(DESTDIR)$(LIBEXECDIR)/
install -d $(DESTDIR)$(BINDIR)
install -m 755 src/cli.sh $(DESTDIR)$(BINDIR)/differential-shellcheck
install -d $(DESTDIR)$(MANDIR)
install -m 644 docs/differential-shellcheck.1 $(DESTDIR)$(MANDIR)/
install -d $(DESTDIR)$(DOCDIR)
install -m 644 README.md $(DESTDIR)$(DOCDIR)/
install -d $(DESTDIR)$(LICENSEDIR)
install -m 644 LICENSE $(DESTDIR)$(LICENSEDIR)/
install -d $(DESTDIR)$(DOCDIR)
install -m 644 VERSION $(DESTDIR)$(DOCDIR)/

uninstall:
rm -f $(DESTDIR)$(BINDIR)/differential-shellcheck
rm -rf $(DESTDIR)$(LIBEXECDIR)
rm -f $(DESTDIR)$(MANDIR)/differential-shellcheck.1
rm -rf $(DESTDIR)$(DOCDIR)
rm -rf $(DESTDIR)$(LICENSEDIR)

.PHONY: install uninstall
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,65 @@ jobs:

* more examples - [here](https://github.com/redhat-plumbers-in-action/differential-shellcheck/network/dependents?package_id=UGFja2FnZS0yOTkzNjMxNzI2)

## CLI Usage

Differential ShellCheck can also be used as a standalone command-line tool outside of GitHub Actions.

### Installation

**Fedora:**

```bash
dnf install differential-shellcheck
```

**From source:**

```bash
git clone https://github.com/redhat-plumbers-in-action/differential-shellcheck.git
cd differential-shellcheck
sudo make install
```

### Dependencies

`shellcheck`, `csdiff` (provides `csgrep`, `cshtml`), `jq`, `git`

Optional: `sarif-fmt` (alternative display engine)

### Quick Start

```bash
# Scan changes not yet in upstream (auto-detects remote)
differential-shellcheck

# Scan changes between two commits
differential-shellcheck --base main --head feature-branch

# Scan only warnings and errors
differential-shellcheck --severity warning

# Full scan of specific files
differential-shellcheck --full-scan myscript.sh

# Use with pre-commit (files passed as arguments)
differential-shellcheck script1.sh script2.sh
```

### Pre-commit Integration

Add to your `.pre-commit-config.yaml`:

```yaml
repos:
- repo: https://github.com/redhat-plumbers-in-action/differential-shellcheck
rev: v5.6.0
hooks:
- id: differential-shellcheck
```

For the full list of CLI options, run `differential-shellcheck --help` or see `man differential-shellcheck`.

## Configuration options

Action currently accepts following options:
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5.6.0
61 changes: 61 additions & 0 deletions differential-shellcheck.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-3.0-or-later

Name: differential-shellcheck
Version: 5.6.0
Release: 1%{?dist}
Summary: Differential static analysis for shell scripts

License: GPL-3.0-or-later
URL: https://github.com/redhat-plumbers-in-action/%{name}
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz

BuildArch: noarch

BuildRequires: pandoc
BuildRequires: make

Requires: ShellCheck
Requires: csdiff
Requires: jq
Requires: git-core
Requires: bash

Recommends: sarif-fmt

%description
Differential ShellCheck performs differential ShellCheck scans on shell
scripts in a git repository. It identifies new defects introduced by
recent changes and fixes that were resolved, making it easy to focus on
newly introduced issues without being overwhelmed by pre-existing problems.

It can be used as a standalone CLI tool, a pre-commit hook, or a GitHub
Action.

%prep
%autosetup -n %{name}-%{version}

%build
%make_build man

%install
%make_install PREFIX=%{_prefix}

%check
# Run unit tests if bats is available
%if 0%{?fedora} || 0%{?rhel} >= 9
bats test/*.bats
%endif

%files
%license LICENSE
%doc README.md
%doc VERSION
%{_bindir}/%{name}
%{_libexecdir}/%{name}/
%{_mandir}/man1/%{name}.1*

%changelog
* Thu Apr 17 2026 Jan Macku <jamacku@redhat.com> - 5.6.0-1
- Add CLI interface for standalone usage outside GitHub Actions
- Add pre-commit hook support
- Add man page
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Next release

* Add standalone CLI interface for running outside GitHub Actions
* Add pre-commit hook support
* Add man page (`man differential-shellcheck`)
* Add RPM spec file for Fedora packaging
* Add `make install` target for system-wide installation

## v5.5.1

* Include git-lfs in image to avoid issues with projects using it
Expand Down
Loading
Loading