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
30 changes: 30 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Weekly dependency updates, each opened as a pull request against main that must pass the `build` check
# and is merged like any other change (merge commit). Merging releases nothing: a new module version still
# needs a GitHub Release (see RELEASING.md).
version: 2
updates:
# The workflows pin every action to a commit SHA with a version comment; Dependabot updates both.
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
groups:
github-actions:
patterns: ["*"]
commit-message:
prefix: ci
labels: [dependencies]

# The library itself has no dependencies; this keeps the test tooling (testify) current.
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
day: monday
groups:
gomod-minor-and-patch:
update-types: [minor, patch]
commit-message:
prefix: deps
labels: [dependencies]
154 changes: 154 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Build
run-name: >-
${{ github.event_name == 'pull_request' && format('Checking that #{0} builds', github.event.pull_request.number)
|| format('Building {0}', github.ref_name) }}

# Trunk-based: main is the only long-lived branch. Every pull request and every push to main runs
# `go vet`, `go build` and `go test` on the two latest Go releases. Nothing is released here: a Go module
# version is a v{semver} tag, and tags come only from a GitHub Release (see RELEASING.md and release.yml).
#
# The tests that call the API run against the staging API with the CONVERTAPI_STAGING_TOKEN secret (set for
# Actions and for Dependabot). Where the secret is unavailable (forks) they skip, and the offline tests run.
#
# The required status check is the `build` job, which passes only when every Go version passed.
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
# A newer push to the same pull request cancels the older build; builds of main never cancel each other.
group: build-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.run_id }}
cancel-in-progress: true

jobs:
test:
name: test (Go ${{ matrix.go }})
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
# setup-go's aliases for the latest and the previous Go release, the two the Go team supports.
go: [stable, oldstable]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: ${{ matrix.go }}
cache-dependency-path: go.sum

- name: Check go.mod and go.sum
run: |
set -euo pipefail
go version
go mod verify
go mod tidy -diff

- name: Vet
run: go vet ./...

- name: Build
run: go build ./...

# The staging API answers 503 (no healthy upstream) in bursts of up to a minute, so the suite gets up
# to three attempts, 30 s apart.
- name: Test
env:
CONVERTAPI_TOKEN: ${{ secrets.CONVERTAPI_STAGING_TOKEN }}
CONVERTAPI_BASE_URL: https://stag-v2.convertapi.com
run: |
set -uo pipefail
if [ -z "$CONVERTAPI_TOKEN" ]; then
echo "::notice::CONVERTAPI_STAGING_TOKEN is not available to this run (a fork pull request), so the API tests are skipped."
fi
for attempt in 1 2 3; do
go test -count=1 -race -v ./... && exit 0
echo "::warning::Attempt $attempt: the tests failed, see above"
sleep 30
done
echo "::error::The tests failed three times"
exit 1

build:
name: build
needs: test
if: always()
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Check every Go version passed
env:
RESULT: ${{ needs.test.result }}
run: |
if [ "$RESULT" != success ]; then
echo "::error::The Go version matrix finished with '$RESULT'."
exit 1
fi

- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

# config.Version goes into the User-Agent of every request, and release.yml refuses a tag that does
# not match it. It may run ahead of the latest release, never behind it.
- name: Check the version constant
id: version
run: |
set -euo pipefail
VERSION=$(sed -n 's/^const Version = "\(.*\)".*/\1/p' pkg/config/version.go)
SEMVER='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?$'
if ! [[ "$VERSION" =~ $SEMVER ]]; then
echo "::error file=pkg/config/version.go::config.Version '$VERSION' is not {major}.{minor}.{patch}[-{pre-release}]"
exit 1
fi
# The module path has no /vN suffix, so it can only carry v0 and v1 versions.
if [ "${VERSION%%.*}" -ge 2 ]; then
echo "::error file=pkg/config/version.go::config.Version $VERSION needs the module path github.com/ConvertAPI/convertapi-go/v${VERSION%%.*} (see RELEASING.md)"
exit 1
fi
# The highest v* tag by SemVer precedence, pre-releases included (sort -V does not implement it:
# 1.1.0-beta.2 < 1.1.0, and 1.1.0-beta.10 > 1.1.0-beta.2).
read -r LATEST BEHIND < <(git tag --list 'v*' | python3 -c '
import re, sys
def key(v):
core, _, pre = v.partition("-")
ids = tuple((0, int(i), "") if i.isdigit() else (1, 0, i) for i in pre.split(".")) if pre else ()
return tuple(map(int, core.split("."))), not pre, ids
ok = re.compile(r"^v\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$")
tags = [t[1:] for t in sys.stdin.read().split() if ok.match(t)]
latest = max(tags, key=key, default="")
print(latest or "none", "yes" if latest and key(sys.argv[1]) < key(latest) else "no")
' "$VERSION")
if [ -z "${BEHIND:-}" ]; then
echo "::error::Could not compare config.Version with the v* tags"
exit 1
elif [ "$BEHIND" = yes ]; then
echo "::error file=pkg/config/version.go::config.Version $VERSION is lower than the latest release $LATEST"
exit 1
fi
{
echo "version=$VERSION"
echo "latest=$LATEST"
} >> "$GITHUB_OUTPUT"

- name: Summary
env:
VERSION: ${{ steps.version.outputs.version }}
LATEST: ${{ steps.version.outputs.latest }}
run: |
{
echo "| | |"
echo "|---|---|"
echo "| \`config.Version\` | \`$VERSION\` (latest release: \`$LATEST\`) |"
echo "| Go | stable, oldstable |"
} >> "$GITHUB_STEP_SUMMARY"
Loading
Loading