Skip to content
Merged
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
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: CI

on:
push:
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Test
run: go test ./...

- name: Vet
run: go vet ./...
21 changes: 21 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Smoke Tests

on:
workflow_dispatch:
inputs:
base_url:
description: "Base URL for deployed endpoint (example: https://geps.dev)"
required: true
type: string

jobs:
smoke:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Run smoke tests
env:
BASE_URL: ${{ inputs.base_url }}
run: bash ./scripts/smoke.sh
2 changes: 2 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tools]
go = "1.24"
42 changes: 42 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Contributing

## Prerequisites

- `mise`
- `git`
- `make`

## Setup

```bash
mise trust .mise.toml
mise install
mise exec -- make setup
```

## Local workflow

Run app:

```bash
mise exec -- make run
```

Run checks before opening a PR:

```bash
mise exec -- make fmt
mise exec -- make check
```

## Smoke tests for deployed endpoint

```bash
BASE_URL=https://YOUR_DOMAIN_OR_FUNCTION_URL mise exec -- make smoke
```

## Pull requests

- Keep changes focused and small.
- Include tests for behavioral changes.
- Update `README.md` when API behavior changes.
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
GO ?= go

.PHONY: setup run test vet fmt tidy check smoke

setup:
$(GO) mod download

run:
$(GO) run ./cmd/main.go

test:
$(GO) test ./...

vet:
$(GO) vet ./...

fmt:
$(GO) fmt ./...

tidy:
$(GO) mod tidy

check: test vet

smoke:
@test -n "$(BASE_URL)" || (echo "BASE_URL is required"; exit 1)
bash ./scripts/smoke.sh
130 changes: 99 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,47 @@
Progress bars for markdown.

Have you ever wanted to track some progress in your markdown documents?
Well, I do, and I used `progressed.io` before but it was shutted down.
Well, I do, and I used `progressed.io` before but it was shut down.

So I decided to recreate it.

## Usage

Add it as an image in your favorite markdown document, like this github readme, and change the progress number at the end.

![](https://geps.dev/progress/10)
```md
![](https://geps.dev/progress/10)
```

> **Note**
> I'll try to keep this domain name up as much as possible, so wish me a long life 😁
> I'll try to keep this domain name up as much as possible, so wish me a long life 🙂

## API Contract

### Endpoint

- `GET /progress/{percentage}`
- `HEAD /progress/{percentage}`

`percentage` must be an integer and is clamped to `0..100`.

### Query params

- `dangerColor`
- `warningColor`
- `successColor`

All color values must be 6-character hex values without `#` (example: `ff9900`).

### Response behavior

- `200 OK`: valid request, returns SVG.
- `400 Bad Request`: invalid percentage or color format.
- `405 Method Not Allowed`: any method different from `GET` or `HEAD`.
- `500 Internal Server Error`: template parse/render failure.

Headers for successful responses:

- `Content-Type: image/svg+xml`
- `Cache-Control: public, max-age=300`

## Examples

Expand All @@ -24,54 +53,93 @@ Add it as an image in your favorite markdown document, like this github readme,

![](https://geps.dev/progress/75)

### Custom colors?
### Custom colors

If you want to customize the colors you can use this query params:
You can customize colors through query params:

dangerColor
warningColor
successColor
- `dangerColor`
- `warningColor`
- `successColor`

It will look like this:

![](https://geps.dev/progress/32?dangerColor=800000&warningColor=ff9900&successColor=006600)

And the results will look like this:
```md
![](https://geps.dev/progress/32?dangerColor=800000&warningColor=ff9900&successColor=006600)
```

Rendered examples:

![](https://geps.dev/progress/10?dangerColor=800000&warningColor=ff9900&successColor=006600)

![](https://geps.dev/progress/50?dangerColor=800000&warningColor=ff9900&successColor=006600)

![](https://geps.dev/progress/75?dangerColor=800000&warningColor=ff9900&successColor=006600)

## Deploy
## Local Development

### Prerequisites

- `mise` installed

### Setup

```bash
mise install
mise exec -- make setup
```

Run locally:

```bash
mise exec -- make run
```

Try it in a browser:

```text
http://localhost:8080/progress/76
```

### Quality checks

```bash
mise exec -- make test
mise exec -- make vet
mise exec -- make check
```

So if you want to host it and have your own domain, you can just deploy it on your preferred cloud.
### Smoke tests against deployed URL

It's straight forward for GCP but with some little changes you can do the same for any cloud since this is a simple function (or lambda).
```bash
BASE_URL=https://geps.dev mise exec -- make smoke
```

### Google Cloud
The smoke test validates status codes, headers, and basic content contract.

Login and set the project in `gcloud` if you are not already logged in.
## Deploy (Google Cloud)

gcloud auth login
gcloud config set project THE_PROJECT_NAME
Set your project first:

Deploy it as an HTTP Cloud Function with the `Progress` entrypoint.
```bash
gcloud auth login
gcloud config set project THE_PROJECT_NAME
```

gcloud functions deploy progress --runtime go119 --entry-point Progress --trigger-http --memory 128MB --allow-unauthenticated
Deploy as an HTTP function with `Progress` as entrypoint:

## Test it locally
```bash
gcloud functions deploy progress --gen2 --runtime go124 --entry-point Progress --trigger-http --allow-unauthenticated --region us-central1
```

Build the project so it downloads the dependencies
After deploy, run smoke tests:

go build
```bash
BASE_URL=https://YOUR_DOMAIN_OR_FUNCTION_URL mise exec -- make smoke
```

Run it
## CI

go run cmd/main.go
- `CI` workflow runs `go test` and `go vet` on pushes and PRs.
- `Smoke Tests` workflow can be run manually (`workflow_dispatch`) with a `base_url` input.

You can visit the endpoint in your favorite browser, for example:
## Contributing

http://localhost:8080/progress/76
See `CONTRIBUTING.md`.
15 changes: 10 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package main

import (
"log"
"net/http"
"os"

// Blank-import the function package so the init() runs
_ "geps.dev/progress"
"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
"geps.dev/progress"
)

func main() {
Expand All @@ -15,7 +14,13 @@ func main() {
if envPort := os.Getenv("PORT"); envPort != "" {
port = envPort
}
if err := funcframework.Start(port); err != nil {
log.Fatalf("funcframework.Start: %v\n", err)

mux := http.NewServeMux()
mux.HandleFunc("/progress/", progress.Progress)

addr := ":" + port
log.Printf("Listening on %s", addr)
if err := http.ListenAndServe(addr, mux); err != nil {
log.Fatalf("http.ListenAndServe: %v\n", err)
}
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
module geps.dev/progress

go 1.19
go 1.24

require github.com/GoogleCloudPlatform/functions-framework-go v1.6.1
require github.com/GoogleCloudPlatform/functions-framework-go v1.9.2

require (
cloud.google.com/go/functions v1.0.0 // indirect
github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.10.0 // indirect
golang.org/x/time v0.8.0 // indirect
)
Loading