Skip to content

Commit

Permalink
Binary release creation workflows (#262)
Browse files Browse the repository at this point in the history
* Binary release creation workflows

This PR adds the ability to upload release artifact via XCHammer's github
CI and it creates a release when pushing a tag to v*

The github actions API doesn't play well with per commit artifacts. For
now we create a release when pushing a tag.

Consuming the per commit artifacts w/o the github actions API is blocked
by this: actions/upload-artifact#50
  • Loading branch information
jerrymarino authored Oct 1, 2020
1 parent 25266d7 commit e72c823
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 32 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,39 @@ jobs:
- name: workspace_v2
run: make workspace_v2

# This uploads `xchammer.zip` as an artifact to github actions
# For issues mentioned here
# https://github.com/actions/upload-artifact/issues/50
# The Github URL can't be used with Bazel directly in an `http_archive`
# At the time of writing the only way to consume it is to:
# - get the release URL with the github actions API which is valid for 1 minute
# - pull the zip from that URL and re-host it: or somehow use it locally.
# - it'd probably be possible to impalement as a github actions repository
# and that's a lot of unwarranted complexity to integrate XCHammer.
#
# See README.md of how to use the artifact with Bazel
make_release:
name: make_release
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: bazel_cache_release
uses: actions/cache@v2
env:
cache-name: bazel-cache-release
with:
path: ~/Library/Caches/Bazel
key: ${{ runner.os }}-build-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}-

- name: make_release
run: |
make release
# Set the BAZEL_BIN env var to the realpath
# Note: actions/upload-artifact@v2 at time of writing is falling
# apart when we give it a symlink base path
echo ::set-env name=BAZEL_BIN::$(readlink bazel-bin)
- uses: actions/upload-artifact@v2
with:
name: xchammer
path: ${{ env.BAZEL_BIN }}/xchammer_dist_repo.zip
36 changes: 36 additions & 0 deletions .github/workflows/ci_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,39 @@ jobs:
- name: workspace_v2
run: make workspace_v2

# This uploads `xchammer.zip` as an artifact to github actions
# For issues mentioned here
# https://github.com/actions/upload-artifact/issues/50
# The Github URL can't be used with Bazel directly in an `http_archive`
# At the time of writing the only way to consume it is to:
# - get the release URL with the github actions API which is valid for 1 minute
# - pull the zip from that URL and re-host it: or somehow use it locally.
# - it'd probably be possible to impalement as a github actions repository
# and that's a lot of unwarranted complexity to integrate XCHammer.
#
# See README.md of how to use the artifact with Bazel
make_release:
name: make_release
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: bazel_cache_release
uses: actions/cache@v2
env:
cache-name: bazel-cache-release
with:
path: ~/Library/Caches/Bazel
key: ${{ runner.os }}-build-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}-

- name: make_release
run: |
make release
# Set the BAZEL_BIN env var to the realpath
# Note: actions/upload-artifact@v2 at time of writing is falling
# apart when we give it a symlink base path
echo ::set-env name=BAZEL_BIN::$(readlink bazel-bin)
- uses: actions/upload-artifact@v2
with:
name: xchammer
path: ${{ env.BAZEL_BIN }}/xchammer_dist_repo.zip
55 changes: 55 additions & 0 deletions .github/workflows/upload_release_artifact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This workflow cuts a per commit binary release of XCHammer and uploads
# the binary release WORKSPACE for later consumption.
#
# Basically push a tag to github for the commit and this will append the
# release artifact
#
# Ideally we'd create a Bazel consumeable artifact per commit but using github
# actions w/o any other systems it's not so possible
# https://github.com/actions/upload-artifact/issues/50
on:
push:
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

name: Upload Release Artifact

jobs:
build:
name: create_release
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: bazel_cache_release
uses: actions/cache@v2
env:
cache-name: bazel-cache-release
with:
path: ~/Library/Caches/Bazel
key: ${{ runner.os }}-build-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}-

- name: make_release
run: make release
- name: create_release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: false
- name: upload_release_asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: bazel-bin/xchammer_dist_repo.zip
asset_name: xchammer.zip
asset_content_type: application/zip


6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY : test workspace archive install compile_commands debug run run_force test build build build-release
.PHONY : test workspace release install compile_commands debug run run_force test build build build-release

ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

Expand All @@ -24,10 +24,10 @@ workspace_v2:
clean:
$(ROOT_DIR)/tools/bazelwrapper clean

archive: build-release
release: build-release

# Brew support
install: archive
install: release
mkdir -p $(PREFIX)/bin
ditto $(XCHAMMER_APP) $(PREFIX)/bin/$(PRODUCT)
ln -s $(PREFIX)/bin/$(PRODUCT)/Contents/MacOS/xchammer $(PREFIX)/bin/xchammer
Expand Down
93 changes: 64 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,77 @@ XCHammer see [Introducing
XCHammer](Docs/FastAndReproducibleBuildsWithXCHammer.md) and [Pinterest Focused
Xcode Projects](PinterestFocusedXcodeProjects.md)_

### Installation
### Bazel build Xcode projects

Build and install to `/usr/local/bin/`
First, pull XCHammer into the `WORKSPACE` file:

```bash
make install
_Ideally, pull in a release optimized binary build to keep XCHammer's
dependencies, Swift version, Xcode version, compiler flags, Bazel version, and
build time outside of the main iOS/macOS application's WORKSPACE. To easily
achieve this, GitHub CI creates a binary release artifact on receiving a new
tag._

```py
# WORKSPACE
# Recommended approach - the CI auto releases when you push a tag matching `v*`
# The release prefix is the _tested_ bazel version, and XCHammer is often
# forwards and backwards compatible
http_archive(
name = "xchammer",
urls = [ "https://github.com/pinterest/xchammer/releases/download/v3.4.1.0/xchammer.zip" ],
)

# Download, unzip, and vendor a binary release of XCHammer from a GitHub
# action `artifact` on a PR
# https://github.com/pinterest/xchammer/pull/262/checks?check_run_id=1195532626
#
# Note: the URL of these artifacts is directly consumeable with http_archive due
# to https://github.com/actions/upload-artifact/issues/50
# local_repository(
# name = "xchammer",
# path = "tools/xchammer"
# )

# Pull from source
# git_repository(
# name = "xchammer",
# remote = "https://github.com/pinterest/xchammer.git",
# commit = "[COMMIT_SHA]"
# )
```
_note: for development, `make build` and the `xchammer_dev_repo` target allow a
WORKSPACE to consume XCHammer built out of tree but point to the latest build,
symlinked in `bazel-bin`:
`--override_repository=xchammer=/path/to/xchammer/bazel-bin/xchammer_dev_repo`.
It's also possible to use `local_repository` and override it using
`--override_repository=xchammer=/path/to/xchammer`_

Next, create an `xcode_project` target including targets:
```
# BUILD.Bazel
load("@xchammer//:xcodeproject.bzl", "xcode_project")
xcode_project(
name = "MyProject",
targets = [ "//ios-app:ios-app" ],
paths = [ "**" ],
)
```

_Pinterest vendors XCHammer.app for reproducibility and simplicity._
Finally, build the project with Bazel
```bash
bazel build MyProject
```

### CLI Usage ( Non Bazel built projects )

### Configuration
XCHammer also works as a standalone project generator. kirst build XCHammer and
install to the path:

Generate using a [XCHammerConfig](Sources/XCHammer/XCHammerConfig.swift).
```bash
# Installs to `/usr/local/bin/`
make install
```
Then, generate using a [XCHammerConfig](Sources/XCHammer/XCHammerConfig.swift).

```bash
xchammer generate <configPath>
Expand Down Expand Up @@ -78,28 +135,6 @@ _To learn about how Pinterest uses XCHammer with Bazel locally check out [Pinter
- [a Swift iOS app](sample/Tailor)
- [a Swift macOS app](BUILD.bazel)
## Bazel build Xcode projects
XCHammer additionally supports Bazel building Xcode projects, which enables
remote caching and other features. This feature is experimental.
```py
# WORKSPACE
# TODO: binary releases will soon be created by the CI see
# https://github.com/pinterest/xchammer/pull/258 for more details.
http_archive(
name = "xchammer",
urls = [ "https://github.com/pinterest/xchammer/releases/download/${RELEASE}/TBD.zip" ],
)

# BUILD.Bazel
load("@xchammer//:xcodeproject.bzl", "xcode_project")
xcode_project(
name = "MyProject",
targets = [ "//ios-app:ios-app" ],
paths = [ "**" ],
)
```
### Xcode progress bar integration
Expand Down

0 comments on commit e72c823

Please sign in to comment.