Repository navigation
Add initial Go package and release automation #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| name: Go CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, master] | ||
| paths: | ||
| - 'minipdf-go/**' | ||
| - '.github/workflows/go-ci.yml' | ||
| - '.github/workflows/go-release.yml' | ||
| pull_request: | ||
| branches: [main, master] | ||
| paths: | ||
| - 'minipdf-go/**' | ||
| - '.github/workflows/go-ci.yml' | ||
| - '.github/workflows/go-release.yml' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| quality: | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: minipdf-go | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: '1.22.x' | ||
| cache: false | ||
|
|
||
| - name: Check formatting | ||
| shell: bash | ||
| run: test -z "$(gofmt -l .)" | ||
|
|
||
| - name: Vet | ||
| run: go vet ./... | ||
|
|
||
| - name: Test | ||
| run: go test ./... | ||
|
|
||
| windows-test: | ||
| runs-on: windows-latest | ||
| defaults: | ||
| run: | ||
| working-directory: minipdf-go | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: '1.22.x' | ||
| cache: false | ||
|
|
||
| - name: Test | ||
| run: go test ./... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| name: Go Release | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - 'minipdf-go/v*' | ||
| workflow_dispatch: | ||
| inputs: | ||
| tag: | ||
| description: Existing Go module tag to release (for example, minipdf-go/v0.1.0) | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| concurrency: | ||
| group: go-release-${{ github.ref_name }}-${{ inputs.tag }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| release: | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: minipdf-go | ||
| env: | ||
| RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }} | ||
|
|
||
| steps: | ||
| - name: Checkout release tag | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }} | ||
|
|
||
| - name: Setup Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: '1.22.x' | ||
| cache: false | ||
|
|
||
| - name: Validate release tag | ||
| id: version | ||
| shell: bash | ||
| run: | | ||
| if [[ ! "$RELEASE_TAG" =~ ^minipdf-go/v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then | ||
| echo "::error::Tag '$RELEASE_TAG' must match minipdf-go/v<semver>." | ||
| exit 1 | ||
| fi | ||
| MODULE_PATH="$(go list -m -f '{{.Path}}')" | ||
| if [ "$MODULE_PATH" != "github.com/mini-software/MiniPdf/minipdf-go" ]; then | ||
| echo "::error::Unexpected Go module path '$MODULE_PATH'." | ||
| exit 1 | ||
| fi | ||
| VERSION="${RELEASE_TAG#minipdf-go/}" | ||
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Check formatting | ||
| shell: bash | ||
| run: test -z "$(gofmt -l .)" | ||
|
|
||
| - name: Vet | ||
| run: go vet ./... | ||
|
|
||
| - name: Test | ||
| run: go test ./... | ||
|
|
||
| - name: Build release archives | ||
| shell: bash | ||
| env: | ||
| VERSION: ${{ steps.version.outputs.version }} | ||
| run: | | ||
| mkdir -p dist | ||
| targets=( | ||
| windows/amd64 | ||
| windows/arm64 | ||
| linux/amd64 | ||
| linux/arm64 | ||
| darwin/amd64 | ||
| darwin/arm64 | ||
| ) | ||
| for target in "${targets[@]}"; do | ||
| IFS=/ read -r goos goarch <<< "$target" | ||
| archive="minipdf_${VERSION}_${goos}_${goarch}" | ||
| binary="minipdf" | ||
| if [ "$goos" = "windows" ]; then | ||
| binary="minipdf.exe" | ||
| fi | ||
| mkdir -p "dist/$archive" | ||
| CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" go build \ | ||
| -trimpath \ | ||
| -ldflags="-s -w -X main.version=$VERSION" \ | ||
| -o "dist/$archive/$binary" \ | ||
| ./cmd/minipdf | ||
| if [ "$goos" = "windows" ]; then | ||
| (cd "dist/$archive" && zip -q "../$archive.zip" "$binary") | ||
| else | ||
| tar -C "dist/$archive" -czf "dist/$archive.tar.gz" "$binary" | ||
| fi | ||
| rm -rf "dist/$archive" | ||
| done | ||
| (cd dist && sha256sum minipdf_* > checksums.txt) | ||
|
|
||
| - name: Verify embedded version | ||
| shell: bash | ||
| env: | ||
| VERSION: ${{ steps.version.outputs.version }} | ||
| run: | | ||
| actual="$(go run -ldflags="-X main.version=$VERSION" ./cmd/minipdf --version)" | ||
| if [ "$actual" != "minipdf $VERSION" ]; then | ||
| echo "::error::CLI reported '$actual'." | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Create GitHub release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| tag_name: ${{ env.RELEASE_TAG }} | ||
| name: MiniPdf Go ${{ steps.version.outputs.version }} | ||
| generate_release_notes: true | ||
| files: | | ||
| minipdf-go/dist/*.zip | ||
| minipdf-go/dist/*.tar.gz | ||
| minipdf-go/dist/checksums.txt | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| # MiniPdf for Go | ||
|
|
||
| The experimental native Go implementation of MiniPdf. It provides a reusable | ||
| `minipdf` package and a dependency-free command-line application. | ||
|
|
||
| [Project portal](../README.md) | [Rust implementation](../minipdf-rs/README.md) | | ||
| [.NET implementation](../documents/README.nuget.md) | ||
|
|
||
| > The Go implementation is an early foundation and is not feature-equivalent | ||
| > with MiniPdf for .NET or Rust. It currently renders basic text from XLSX, | ||
| > DOCX, and PPTX packages. Complex Office layout is not yet supported. | ||
|
|
||
| ## Requirements | ||
|
|
||
| - Go 1.22 or later | ||
| - No Microsoft Office, LibreOffice, Adobe Acrobat, or .NET runtime at runtime | ||
|
|
||
|
|
||
| ## Library | ||
|
|
||
| ```go | ||
| package main | ||
|
|
||
| import minipdf "github.com/mini-software/MiniPdf/minipdf-go" | ||
|
|
||
| func main() { | ||
| if err := minipdf.ConvertToPDF("report.docx", "report.pdf"); err != nil { | ||
| panic(err) | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Convert in-memory Office package bytes: | ||
|
|
||
| ```go | ||
| pdf, err := minipdf.ConvertBytesToPDF(input) | ||
| ``` | ||
|
|
||
| Override the output page size: | ||
|
|
||
| ```go | ||
| size, err := minipdf.NewPageSize(400, 500) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| pdf, err := minipdf.ConvertBytesToPDFWithOptions(input, minipdf.ConversionOptions{ | ||
| PageSize: &size, | ||
| }) | ||
| ``` | ||
|
|
||
| ## Command Line | ||
|
|
||
| ```powershell | ||
| go install github.com/mini-software/MiniPdf/minipdf-go/cmd/minipdf@latest | ||
| minipdf report.docx | ||
| minipdf data.xlsx -o data.pdf | ||
| minipdf slides.pptx --paper-size a4 | ||
| minipdf convert report.docx --page-width 400 --page-height 500 | ||
| ``` | ||
|
|
||
| ## Current Scope | ||
|
|
||
| | Capability | Go status | | ||
| |---|---| | ||
| | XLSX to PDF | Basic cell text and shared strings | | ||
| | DOCX to PDF | Basic paragraphs, tabs, line breaks, and explicit page breaks | | ||
| | PPTX to PDF | Basic slide text | | ||
| | PDF output | Dependency-free PDF 1.4 writer | | ||
| | Page size | Office geometry, A4/Letter presets, or custom points | | ||
| | Fonts | Registration API reserved; embedding is not implemented yet | | ||
| | Interfaces | Go package and native CLI | | ||
|
|
||
| The initial renderer deliberately does not claim support for Office styles, | ||
| images, tables, charts, themes, formulas, merged cells, or font embedding. | ||
|
|
||
| ## Development | ||
|
|
||
| ```powershell | ||
| cd minipdf-go | ||
| go fmt ./... | ||
| go vet ./... | ||
| go test ./... | ||
| go run ./cmd/minipdf path\to\input.docx | ||
| ``` | ||
|
|
||
| ## Publishing | ||
|
|
||
| Go modules are published from Git tags rather than uploaded to a package | ||
| registry. Because this module is in the `minipdf-go` repository subdirectory, | ||
| its tags must include that prefix. | ||
|
|
||
| After the release change has been merged to `main`, create and push a semantic | ||
| version tag from the release commit: | ||
|
|
||
| ```powershell | ||
| git tag minipdf-go/v0.1.0 | ||
| git push origin minipdf-go/v0.1.0 | ||
| ``` | ||
|
|
||
| The [Go Release workflow](../.github/workflows/go-release.yml) validates the | ||
| module, builds Windows, Linux, and macOS CLI archives for AMD64 and ARM64, | ||
| writes SHA-256 checksums, and creates the GitHub Release. No package registry | ||
| token is required. The public Go module proxy discovers the library from the | ||
| same tag. | ||
|
|
||
| Verify the published module: | ||
|
|
||
| ```powershell | ||
| go list -m github.com/mini-software/MiniPdf/minipdf-go@v0.1.0 | ||
| go install github.com/mini-software/MiniPdf/minipdf-go/cmd/minipdf@v0.1.0 | ||
| minipdf --version | ||
| ``` | ||
|
|
||
| The workflow can also be run manually for an existing tag. It intentionally | ||
| does not create tags, so a manual run cannot publish an untagged Go module. | ||
|
|
||
| ## License | ||
|
|
||
| [Apache License 2.0](../LICENSE). | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: mini-software/MiniPdf
Length of output: 6445
🤖 get_repo_knowledge executed:
get_repo_knowledge mini-software/MiniPdf /tmp/coderabbit-repo-knowledge/mini-software-minipdf-2049b7d3/conventionsLength of output: 1948
🌐 Web query:
actions/checkout v6 persist-credentials default true README💡 Result:
In
actions/checkoutv6, thepersist-credentialsinput defaults totrue[1][2][3]. This setting controls whether the repository's authentication token or SSH key is configured in the local git configuration [1][2]. When set totrue(the default), the action configures the token or SSH key, allowing your workflow scripts to run authenticated git commands (e.g.,git fetch,git push) [2][3]. The action automatically removes these credentials during the post-job cleanup process [2][3]. Starting with v6, thepersist-credentialsfunctionality was improved to store credentials in a separate file located under$RUNNER_TEMPrather than directly within the repository's.git/configfile, providing enhanced security [2][3]. To opt out of this behavior, you can explicitly setpersist-credentials: falsein your workflow configuration [2][3].Citations:
🌐 Web query:
actions/checkout v6 credential helper RUNNER_TEMP persist-credentials source local git configuration💡 Result:
In
actions/checkoutv6, the behavior of thepersist-credentialsinput was updated to improve security by removing sensitive credentials from the local.git/configfile [1][2]. Instead of writing credentials directly into the repository's.git/config, the action now stores them in a separate file located in the directory specified by theRUNNER_TEMPenvironment variable [1][2]. The action then configures Git to use these credentials via anincludeIfdirective in the local.git/config, which points to this external file [3]. Key implications of this change include: * Enhanced Security: Storing credentials inRUNNER_TEMPreduces the risk of accidentally leaking sensitive tokens through workspace archiving, such as when usingupload-artifactor creating cache entries [2]. * Runner Requirements: For Docker container actions, a minimum Actions Runner version of v2.329.0 is required to properly access the credentials in their new location [1][4]. If you are using Docker container actions, you must ensure the runner has access to this path, often by mounting$RUNNER_TEMPinto the container (e.g.,-v "$RUNNER_TEMP:/github/runner_temp") [5]. * Git Worktrees: Early versions of v6 experienced issues where theincludeIfdirective failed to match Git worktrees, causing authentication failures [3]. This was addressed in v6.0.1 by adding a broaderincludeIfpattern that includes subdirectories for worktrees [3]. This process remains transparent for most standard workflows; no changes to workflow YAML files are required for typical repository checkouts [1][2]. You can still disable this behavior entirely by settingpersist-credentials: falsein your workflow configuration [1][6].Citations:
Disable persisted checkout credentials before running repository code.
Each
actions/checkout@v6step leaves the checkout token available to later Git commands by default. In v6, Git uses anincludeIfentry in.git/configthat points to a credential file underRUNNER_TEMP. Setpersist-credentials: falseon all three checkout steps, especially in the release workflow withcontents: write.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 31-34: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
📍 Affects 2 files
.github/workflows/go-release.yml#L31-L34(this comment).github/workflows/go-ci.yml#L28-L29.github/workflows/go-ci.yml#L54-L55🤖 Prompt for AI Agents
Source: Linters/SAST tools