Skip to content

Commit

Permalink
Merge pull request #37 from mgeisler/publishing-scripts
Browse files Browse the repository at this point in the history
Automate publishing new releases to crates.io
  • Loading branch information
mgeisler authored Jul 29, 2020
2 parents 49d7c96 + 37fcdf5 commit 2d30aa1
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 0 deletions.
153 changes: 153 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: Prepare Release PR

on:
push:
branches:
- 'release-*'

jobs:
setup:
runs-on: ubuntu-latest
outputs:
name: ${{ steps.vars.outputs.name }}
old-version: ${{ steps.vars.outputs.old-version }}
new-version: ${{ steps.vars.outputs.new-version }}
steps:
- name: Check out repository
uses: actions/checkout@v2

- name: Set variables
id: vars
run: |
NAME=$(cargo metadata -q --no-deps | jq -r '.packages[0].name')
OLD_VERSION=$(cargo metadata -q --no-deps | jq -r '.packages[0].version')
NEW_VERSION=$(echo ${{ github.ref }} | cut -d '-' -f 2-)
echo "Version from Cargo: $OLD_VERSION"
echo "Version from branch: $NEW_VERSION"
echo "::set-output name=name::$NAME"
echo "::set-output name=old-version::$OLD_VERSION"
echo "::set-output name=new-version::$NEW_VERSION"
- name: Verify version format
run: |
echo '${{ steps.vars.outputs.new-version }}' | grep -q '^[0-9]\+\.[0-9]\+\.[0-9]\+$'
pull-request:
needs: setup
if: ${{ needs.setup.outputs.old-version != needs.setup.outputs.new-version }}
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v2

- name: Configure Git user
run: |
git config user.name "Martin Geisler"
git config user.email "martin@geisler.net"
- name: Update changelog for version ${{ needs.setup.outputs.new-version }}
id: changelog
uses: actions/github-script@v2
with:
script: |
var fs = require('fs')
const old_version = '${{ needs.setup.outputs.old-version }}'
const new_version = '${{ needs.setup.outputs.new-version }}'
let cutoff = '1970-01-01'
const releases = await github.repos.listReleases(context.repo)
for (const release of releases.data) {
if (release.tag_name == old_version) {
cutoff = release.published_at
break
}
}
core.info(`Finding merged PRs after ${cutoff}`)
let q = [`repo:${context.repo.owner}/${context.repo.repo}`,
'is:pr', 'is:merged', `merged:>${cutoff}`]
const prs = await github.search.issuesAndPullRequests({
q: q.join(' '),
sort: 'created',
order: 'asc',
})
core.info(`Found ${prs.data.items.length} merged PRs`)
const changelog = prs.data.items.map(
pr => `* [#${pr.number}](${pr.html_url}): ${pr.title}`
).join('\n\n')
core.exportVariable('CHANGELOG', changelog)
var readme = fs.readFileSync('README.md', 'utf8')
const today = new Date().toISOString().split('T')[0]
const heading = `## Version ${new_version} (${today})\n`
if (readme.match('## Unreleased')) {
readme = readme.replace('## Unreleased', `${heading}\n${changelog}`)
} else {
readme = readme.replace('# Changelog', `# Changelog\n\n${heading}\n${changelog}`)
}
fs.writeFileSync('README.md', readme)
- name: Commit changelog
run: |
git commit --all -m "Update changelog for version ${{ needs.setup.outputs.new-version }}"
- name: Update TOML code blocks
run: |
import fileinput, re, sys
NAME = '${{ needs.setup.outputs.name }}'
NEW_VERSION = '${{ needs.setup.outputs.new-version }}'
MAJOR_MINOR = '.'.join(NEW_VERSION.split('.')[:2])
for line in fileinput.input(inplace=True):
line = re.sub(f'{NAME} = "[^"]+"',
f'{NAME} = "{MAJOR_MINOR}"', line)
line = re.sub(f'{NAME} = {{ version = "[^"]+"',
f'{NAME} = {{ version = "{MAJOR_MINOR}"', line)
sys.stdout.write(line)
shell: python3 {0} README.md

- name: Update html_root_url
run: |
import fileinput, re, sys
NAME = '${{ needs.setup.outputs.name }}'
NEW_VERSION = '${{ needs.setup.outputs.new-version }}'
for line in fileinput.input(inplace=True):
sys.stdout.write(
re.sub(f'html_root_url = "https://docs.rs/{NAME}/[^"]+"',
f'html_root_url = "https://docs.rs/{NAME}/{NEW_VERSION}"', line))
shell: python3 {0} src/lib.rs

- name: Update crate version to ${{ needs.setup.outputs.new-version }}
uses: thomaseizinger/set-crate-version@1.0.0
with:
version: ${{ needs.setup.outputs.new-version }}

- name: Build and test
run: |
cargo test
- name: Commit version bump
run: |
git commit --all -m "Bump version to ${{ needs.setup.outputs.new-version }}"
- name: Push version bump
run: git push origin

- name: Create pull request
uses: actions/github-script@v2
with:
script: |
const pr = await github.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
head: 'release-${{ needs.setup.outputs.new-version }}',
base: 'master',
title: 'Release ${{ needs.setup.outputs.new-version }}',
body: process.env.CHANGELOG,
})
core.info(`Created PR: ${pr.data.html_url}`)
63 changes: 63 additions & 0 deletions .github/workflows/publish-crate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Publish Crate

on:
push:
branches:
- master
paths:
- Cargo.toml
repository_dispatch:
types: publish

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v2

- name: Set variables
id: vars
run: |
NAME=$(cargo metadata -q --no-deps | jq -r '.packages[0].name')
VERSION=$(cargo metadata -q --no-deps | jq -r '.packages[0].version')
CHANGELOG=$(awk '/^## Version/ {i++}; i==1 {print}; i>1 {exit}' README.md \
| python3 -c 'import sys, json; print(json.dumps(sys.stdin.read()))')
echo "::set-output name=name::$NAME"
echo "::set-output name=version::$VERSION"
echo "::set-output name=changelog::$CHANGELOG"
echo "Found $NAME-$VERSION"
- name: Lookup ${{ steps.vars.outputs.version }} tag
id: need-release
uses: actions/github-script@v2
with:
script: |
const version = '${{ steps.vars.outputs.version }}'
const tags = await github.repos.listTags(context.repo)
if (tags.data.some(tag => tag.name == version)) {
core.info(`Found ${version} tag -- will skip publish step`)
return false
}
core.info(`Found no ${version} tag -- will proceed with publishing`)
return true
# The result from above is JSON-encoded, meaning that we
# end up with the string 'true', not the Boolean true.
- if: steps.need-release.outputs.result == 'true'
name: Publish crate to crates.io
run: |
echo "Publishing ${{ steps.vars.outputs.name }}-${{ steps.vars.outputs.version }}"
cargo publish --token ${{ secrets.CARGO_TOKEN }}
- if: steps.need-release.outputs.result == 'true'
name: Create GitHub release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.vars.outputs.version }}
release_name: ${{ steps.vars.outputs.name }}-${{ steps.vars.outputs.version }}
body: ${{ fromJson(steps.vars.outputs.changelog) }}
draft: false
prerelease: false

0 comments on commit 2d30aa1

Please sign in to comment.