Skip to content

Commit

Permalink
Add PGXN and GitHub release workflow
Browse files Browse the repository at this point in the history
Add `CHANGELOG.md` and fill it out for the forthcoming v0.1.0.

Add `.ci/mknotes` to parse `CHANGELOG.md` and generate a change log only
for the current version in `target/release_notes.md` (ported from a
personal Go project).

Add `META.json.in` and a `make` target to generate `META.json` to
release on PGXN.

Add `github/workflows/release.yml` to release to PGXN and GitHub.

Add other `make` targets to build `target/release_notes.md` and a
release Zip file. Although the `pgxn-bundle` script in the workflow does
the same thing, this is useful for testing that the bundle is as it
should be.
  • Loading branch information
theory committed Apr 5, 2024
1 parent b4eca96 commit 6c7b73a
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 3 deletions.
150 changes: 150 additions & 0 deletions .ci/mknotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/usr/bin/env perl

package mknotes;

use strict;
use warnings;
use v5.30;
use Getopt::Long qw(GetOptions);
use File::Path qw(make_path);
use File::Basename qw(dirname);
use utf8;

my $item_regex = qr/^[*-+]\s+/;
my $indent_regex = qr/^\s+/;

sub new {
my $self = {
version => '',
file => '',
repo => '',
output => '',
};

GetOptions(
"f=s" => \$self->{file},
"v=s" => \$self->{version},
"r=s" => \$self->{repo},
"o=s" => \$self->{output},
) or die("Error in command line arguments\n");

if (!$self->{file} || !$self->{version} || !$self->{repo}) {
die "Usage: mknotes -v [VERSION] -f [CHANGELOG] -r [REPO]\n";
}

# Trim a slash from the URI.
$self->{repo} =~ s{/$}{};

bless $self => __PACKAGE__;
}

sub run {
my $self = shift;

open my $fh, '<:encoding(UTF-8)', $self->{file}
or die "Cannot open $self->{file}: $!\n";

# Print to STDOUT by default.
my $out;
if ($self->{output}) {
my $dir = dirname $self->{output};
make_path $dir unless -d $dir;
open $out, '>:encoding(UTF-8)', $self->{output}
or die "Cannot open $self->{output}: $!\n";
} else {
$out = \*STDOUT;
binmode $out, ':encoding(UTF-8)';
}

my $header = "## [v$self->{version}]";
my ($found, $in_item) = (0, 0);

while (my $line = <$fh>) {
if ($line =~ /^\Q$header/) {
# Found the header for this version. Build a regex for its link
# reference.
$found = 1;
my $link_regex = qr/^\s*\Q[v$self->{version}]\E:\s+https:/;

# Continue scanning until we reach the next `## ` header.
while (my $line = <$fh>) {
chomp $line;
return $self->finish_list($out, $line) if $line =~ /^## /;

# Skip the line if it's the link reference for the header.
$in_item = $self->print_line($out, $line, $in_item)
unless $line =~ $link_regex;
}
}
}

# All done!
die "Version $self->{version} not found in $self->{file}\n" unless $found;
}

# Called when the next version header is found in line.
sub finish_list {
my ($self, $out, $line) = @_;
# Next header. Extract its version.

my ($prev) = $line =~ /\[([^]]+)\]/;
die "No version found in $line\n" unless $prev;

# Emit a footer line with a link to the diff for this version.
print {$out} sprintf(
"---\n\n🆚 For more detail compare [changes since %s](%s/compare/%s...%s).\n",
$prev, $self->{repo}, $prev, $self->{version},
);

# All done.
return 1;
}

# Called for a line to print, keeping track of list item status.
sub print_line {
my ($self, $out, $line, $in_item) = @_;
# Convert wrapped list items to single lines.
if ($line =~ $item_regex) {
if ($in_item) {
# Previous item done
print {$out} "\n";
} else {
# We're in an item now.
$in_item = 1
}
# Print the line with no newline.
print {$out} $line;

return $in_item;
}

if ($in_item) {
# In an item, but not starting a new item.
if ($line =~ $indent_regex) {
# Continued item, convert indent to single space.
$line =~ s/$indent_regex/ /g;
# Print without newline.
print {$out} $line;
} else {
# No longer in an item.
$in_item = 0;
# Previous item done; print complete line.
print {$out} "\n", $line, "\n";
}

return $in_item;
}

# Not in an item.
$in_item = 0;
# Print complete line
print {$out} $line, "\n";

return $in_item;
}

package main;

mknotes->new->run;

__END__
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ci export-ignore
.gitignore export-ignore
.gitattributes export-ignore
.github export-ignore
META.json.in export-ignore
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: 🚀 Bundle and Release
on:
push:
# Release on semantic version tag.
tags: ['v[0-9]+.[0-9]+.[0-9]+']
jobs:
release:
name: 🚀 Release on PGXN and GitHub
runs-on: ubuntu-latest
container: pgxn/pgxn-tools
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PGXN_USERNAME: ${{ secrets.PGXN_USERNAME }}
PGXN_PASSWORD: ${{ secrets.PGXN_PASSWORD }}
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Bundle the Release
id: bundle
env: { GIT_BUNDLE_OPTS: --add-file META.json }
run: make META.json && pgxn-bundle
- name: Release on PGXN
run: pgxn-release
- name: Generate Release Changes
run: make target/release-notes.md
- name: Create GitHub Release
id: release
uses: actions/create-release@v1
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body_path: target/release-notes.md
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.release.outputs.upload_url }}
asset_path: ./${{ steps.bundle.outputs.bundle }}
asset_name: ${{ steps.bundle.outputs.bundle }}
asset_content_type: application/zip
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
**/*.rs.bk
Cargo.lock
.vscode/
META.json
jsonschema-*
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Changelog

All notable changes to this project will be documented in this file. It uses the
[Keep a Changelog] format, and this project adheres to [Semantic Versioning].

[Keep a Changelog]: https://keepachangelog.com/en/1.1.0/
[Semantic Versioning]: https://semver.org/spec/v2.0.0.html
"Semantic Versioning 2.0.0"

## [v0.1.0] --- Unreleased

The theme of this release is *learning Rust and pgrx.*

### ⚡ Improvements

* First release, everything is new!
* JSON Schema validation using [boon]
* Fully supports draft 2020-12, draft 2019-09, draft-7, draft-6, and draft-4
* Multi-object schema specification

### 🏗️ Build Setup

* Built with Rust
* Use `make` for most actions

### 📚 Documentation

* Build and install docs in the [README]
* Full [reference documentation]

[v0.1.0]: https://github.com/tembo-io/pg-jsonschema/compare/34d5d49...HEAD
[boon]: https://github.com/santhosh-tekuri/boon
[README]: https://github.com/tembo-io/pg-jsonschema/blob/v0.1.0/README.md
[reference documentation]: https://github.com/tembo-io/pg-jsonschema/blob/v0.1.0/doc/jsonschema.md
47 changes: 47 additions & 0 deletions META.json.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "jsonschema",
"abstract": "JSON Schema validation functions for PostgreSQL",
"description": "The jsonschema extension provides JSON Schema validation functions supporting drafts 2020-12, 2019-09, 7, 6, and 4",
"version": "@CARGO_VERSION@",
"maintainer": [
"David E. Wheeler <david@justatheory.com>",
"Tembo <admin+pgxn@tembo.io>"
],
"license": "mit",
"provides": {
"jsonschema": {
"abstract": "JSON Schema validation functions for PostgreSQL",
"file": "jsonschema.control",
"docfile": "doc/jsonschema.md",
"version": "@CARGO_VERSION@"
}
},
"prereqs": {
"runtime": {
"requires": {
"PostgreSQL": "11.0.0"
}
}
},
"resources": {
"bugtracker": {
"web": "https://github.com/tembo-io/pg-jsonschema/issues/"
},
"repository": {
"url": "git://github.com/tembo-io/pg-jsonschema.git",
"web": "https://github.com/tembo-io/pg-jsonschema/",
"type": "git"
}
},
"generated_by": "David E. Wheeler",
"meta-spec": {
"version": "1.0.0",
"url": "https://pgxn.org/meta/spec.txt"
},
"tags": [
"jsonschema",
"validation",
"pgrx",
"rust"
]
}
23 changes: 20 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
PG_CONFIG ?= $(shell which pg_config)
PGRXV="$(shell perl -nE '/^pgrx\s+=\s"=?([^"]+)/ && do { say $$1; exit }' Cargo.toml)"
PGV=$(shell perl -E 'shift =~ /(\d+)/ && say $$1' "$(shell $(PG_CONFIG) --version)")
DISTNAME = $(shell perl -nE '/^name\s*=\s*"([^"]+)/ && do { say $$1; exit }' Cargo.toml)
DISTVERSION = $(shell perl -nE '/^version\s*=\s*"([^"]+)/ && do { say $$1; exit }' Cargo.toml)
PGRXV = $(shell perl -nE '/^pgrx\s+=\s"=?([^"]+)/ && do { say $$1; exit }' Cargo.toml)
PGV = $(shell perl -E 'shift =~ /(\d+)/ && say $$1' "$(shell $(PG_CONFIG) --version)")

.DEFAULT_GOAL: package # Build jsonshcmea for the PostgreSQL cluster identified by pg_config.
package:
Expand Down Expand Up @@ -29,6 +31,21 @@ pgrx-version:
pg-version: Cargo.toml
@echo $(PGV)

## cleaan: Remove build artifacts and intermediate files.
## clean: Remove build artifacts and intermediate files.
clean: target
@cargo clean
@rm -rf META.json $(DISTNAME)-$(DISTVERSION).zip

# Create the PGXN META.json file.
META.json: META.json.in Cargo.toml
@sed "s/@CARGO_VERSION@/$(DISTVERSION)/g" $< > $@

# Create a PGXN-compatible zip file.
$(DISTNAME)-$(DISTVERSION).zip: META.json
git archive --format zip --prefix $(DISTNAME)-$(DISTVERSION)/ --add-file $< -o $(DISTNAME)-$(DISTVERSION).zip HEAD

## pgxn-zip: Create a PGXN-compatible zip file.
pgxn-zip: $(DISTNAME)-$(DISTVERSION).zip

target/release-notes.md: CHANGELOG.md .ci/mknotes
@./.ci/mknotes -v $(DISTVERSION) -f $< -r https://github.com/$(or $(GITHUB_REPOSITORY),tembo-io/pg-jsonschema) -o $@
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ JSON Schema Postgres Extension
[![Build Status](https://github.com/tembo-io/pg-jsonschema/actions/workflows/lint-and-test.yml/badge.svg)](https://github.com/tembo-io/pg-jsonschema/actions/workflows/lint-and-test.yml "🧪 Lint and Test")
[![Code Coverage](https://codecov.io/gh/tembo-io/pg-jsonschema/graph/badge.svg?token=DIFED324ZY)](https://codecov.io/gh/tembo-io/pg-jsonschema "📊 Code Coverage")

[Change Log](CHANGELOG.md) | [Documentation](doc/jsonschema.md)

This library provides the `jsonschema` extension for validating JSON and JSONB
against a [JSON Schema] in Postgres. It supports the following [specification
drafts] as validated by the [JSON-Schema-Test-Suite] excluding optional
Expand Down

0 comments on commit 6c7b73a

Please sign in to comment.