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
31 changes: 31 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# shellcheck shell=bash
set -euo pipefail

# Rejects pushing non-standard tags. Release tags must be SemVer with a 'v' prefix:
# vX.Y.Z (production, e.g. v0.4.0)
# vX.Y.Z-<pre> (pre-release, e.g. v0.4.0-beta.1 — normally created by CI)
# Examples REJECTED: X.Y.Z, X.Y, vX.Y, 1.0, v1.
#
# Enable once per clone: git config core.hooksPath .githooks

pattern='^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$'
zero='0000000000000000000000000000000000000000'
status=0

while read -r _local_ref _local_sha remote_ref remote_sha; do
case "$remote_ref" in
refs/tags/*)
[ "$remote_sha" = "$zero" ] && continue || true
tag="${remote_ref#refs/tags/}"
if ! printf '%s' "$tag" | grep -qE "$pattern"; then
echo "✖ Refused to push tag '$tag'." >&2
echo " Release tags must be SemVer with a 'v' prefix, e.g. v0.4.0 (or v0.4.0-beta.1)." >&2
echo " Rejected forms: X.Y.Z, X.Y, vX.Y, bare numbers." >&2
status=1
fi
;;
esac
done

exit $status
66 changes: 66 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Release
on:
push:
branches:
- main
- 'release/**'

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Build bundle (smoke test)
run: |
corepack enable
yarn install --frozen-lockfile
yarn package

- name: Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
BRANCH="${GITHUB_REF_NAME}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

STABLE="$(git tag --list 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1)"
if [ -z "$STABLE" ]; then
echo "::error::No stable vX.Y.Z tag found. Push the release tag (e.g. v0.4.0) first."
exit 1
fi
echo "Latest stable tag: $STABLE"

if [ "$BRANCH" = "main" ]; then
if gh release view "$STABLE" >/dev/null 2>&1; then
echo "Release $STABLE already exists — nothing to do."
exit 0
fi
echo "Production release: $STABLE"
gh release create "$STABLE" --title "$STABLE" --generate-notes --latest
MAJOR="${STABLE%%.*}"
git tag -f "$MAJOR" "$STABLE"
git push origin -f "refs/tags/$MAJOR"
echo "Moved major alias $MAJOR -> $STABLE"
elif [[ "$BRANCH" == release/* ]]; then
LAST="$(git tag --list "${STABLE}-beta.*" | sed -E 's/.*-beta\.([0-9]+)$/\1/' | sort -n | tail -1)"
N=$(( ${LAST:-0} + 1 ))
TAG="${STABLE}-beta.${N}"
echo "Beta release: $TAG (base $STABLE)"
git tag "$TAG"
git push origin "refs/tags/$TAG"
gh release create "$TAG" --title "$TAG" --generate-notes --prerelease
else
echo "Branch '$BRANCH' is not configured for release — skipping."
fi
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ flexibility, enhanced security, and a streamlined workflow.
- macos-14 (arm64)
- Ubuntu-22.04

Note: Currently, plugins are only compatible to use with Appcircle Cloud.
Self-hosted support will be available in future releases.
Note: Both Appcircle Cloud and self-hosted Appcircle installations are supported.
See [Self-Hosted Appcircle](#self-hosted-appcircle) below to configure custom
endpoints.

![Enterprise App Store Dashboard](images/ent_app_store.png)

Expand Down Expand Up @@ -93,6 +94,39 @@ To generate a Personal API Token:
- `publishType`: Specifies the publishing status as either none, beta, or live,
and must be assigned the values "0", "1", or "2" accordingly.

### Self-Hosted Appcircle

If you run a self-hosted Appcircle installation, point the action to your own
servers with the optional `authEndpoint` and `apiEndpoint` inputs. When omitted,
they default to the Appcircle cloud (`https://auth.appcircle.io` and
`https://api.appcircle.io`), so existing cloud workflows keep working without any
change.

```yml
- name: Publish App to Appcircle Enterprise App Store
uses: appcircleio/appcircle-enterprise-app-store-githubaction
with:
personalAPIToken: ${{ secrets.AC_PERSONAL_API_TOKEN }}
appPath: APP_PATH
summary: SUMMARY
releaseNotes: RELEASE_NOTES
publishType: PUBLISH_TYPE # "0": None, "1": Beta, "2": Live
authEndpoint: https://auth.your-appcircle-domain.com
apiEndpoint: https://api.your-appcircle-domain.com
```

- `authEndpoint`: Base URL of the self-hosted Appcircle authentication server.
Optional; defaults to `https://auth.appcircle.io`.
- `apiEndpoint`: Base URL of the self-hosted Appcircle API server. Optional;
defaults to `https://api.appcircle.io`.

> **Self-signed or private CA certificates:** If your self-hosted Appcircle server
> uses a self-signed certificate (or one issued by a private/internal CA), requests
> will fail certificate validation. The action does not disable TLS verification.
> Trust the server's CA on the runner — set the `NODE_EXTRA_CA_CERTS` environment
> variable to a PEM file containing the CA certificate, or add the CA to the system
> certificate store.

### Leveraging Environment Variables

Utilize environment variables seamlessly by substituting the parameters with
Expand Down
16 changes: 14 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,22 @@ inputs:
description:
'Provide Appcircle Personal API Token to authenticate Appcircle services.'
required: true
authEndpoint:
description:
'Optional: Authentication endpoint URL for self-hosted Appcircle
installations. Defaults to the Appcircle cloud.'
required: false
default: 'https://auth.appcircle.io'
apiEndpoint:
description:
'Optional: API endpoint URL for self-hosted Appcircle installations.
Defaults to the Appcircle cloud.'
required: false
default: 'https://api.appcircle.io'
appPath:
description:
'Specify the path to your application file. For iOS, this can be a .ipa or
.xcarchive file path. For Android, specify the .apk or .appbundle file
'Specify the path to your application file. For iOS, this can be a .ipa
file path. For Android, specify the .apk or .aab file
path'
required: true
summary:
Expand Down
Loading
Loading