# Appcircle Documentation
> Enterprise-grade mobile CI/CD platform documentation for iOS, Android, React Native, and Flutter.
## My Account / My Organization
## [My Account](/account/my-account)
Manage personal settings and access control for your Appcircle account.
### [Sign Up / Login](/account/my-account/sign-up-login)
Begin by signing up for a new account or logging into your existing account.
### [Account Management](/account/my-account/account-management)
Update your personal details, change your password, and manage your account settings.
## [My Organization](/account/my-organization)
Configure and manage organization-level settings and security in Appcircle.
### [Profile and Team](account/my-organization/profile-and-team)
The Organization and Team Management section provides comprehensive tools to structure and manage your teams effectively within Appcircle. Here, you can define roles, assign permissions, and organize team members according to your project needs.
### [Security](account/my-organization/security)
The "Security" section in Appcircle connects essential tools and services like Authentication, Authorization, Credentials Security.
### [Notifications](account/my-organization/notifications)
Set up notifications to keep your team updated on the build and release processes.
### [Artifacts](account/my-organization/artifacts)
Manage the artifacts generated from your build processes.
---
## Delete Account
Accounts can only be deleted by the owner.
- Please log in to your account navigate to **My Account**.
- Click **Delete Account** link and confirm the dialog.
## FAQ
### Why am I seeing 'Account is disabled, please contact your administrator' error in Appcircle, how to fix this error?
If an account is deleted in Appcircle, it is first deactivated for 24 hours. After this period, the account will be permanently deleted.
During this time, if you try to re-invite the user to an organization or if the user attempts to log in again, they will see the following error message: "Account is disabled, please contact your administrator." To restore access with the same email, please wait 24 hours before re-inviting them.
---
## Device Activity
The **Device Activity** section allows you to monitor and manage all devices currently signed in to your account. This helps you keep track of active sessions and remotely sign out of any unfamiliar devices for security purposes.
## Viewing Device Activity
When you navigate to the **Device Activity** page, you will see a list of devices that are currently signed in to your account.
For each device, the following information is displayed:
- **Device & Browser**: Shows the operating system and browser version (e.g., *Windows 10 / Chrome 139.0.0*).
- **IP Address**: The IP address used during the session.
- **Started**: The date and time the session began.
- **Last Accessed**: The most recent time the device accessed your account.
- **Expires**: The time when the session will expire if not renewed.
- **Clients**: The services or consoles linked with the active session.
### Current Session
Your current session will be highlighted with a **Current session** label. This indicates the device and browser you are actively using.
### Remote Sign Out
If you see a device that you do not recognize or wish to end a session, you have two options:
- **Sign out individual devices**:
Use the **Sign out** button next to a specific device entry to terminate only that session.
- **Sign out all devices**:
Click **Sign out all devices** at the top of the page to immediately terminate all active sessions across all devices, except your current session.
---
## Account Management
In the Account Management section, you have comprehensive control over your account's security and personal information settings.
## [Device Activity](/account/my-account/account-management/device-activity)
View and manage all active sessions to understand where your account is currently logged in.
## [Signing In](/account/my-account/account-management/signing-in)
Secure your account by regularly updating your password through this option. Also, enhance account security by setting up two-factor authentication, adding an extra layer of protection.
## [Delete Account](/account/my-account/account-management/delete-account)
If you need to, you can initiate the process to permanently delete your account from here.
Each section provides the necessary tools to ensure your account remains secure, and is tailored to your preferences.
---
## Signing In
The **Signing In** section allows you to manage how you access your account. You can update your password for basic authentication and enable **Two-Factor Authentication (2FA)** for an extra layer of security.
## Basic Authentication
Your account is protected by a password, which you can update at any time.
- **Password**: Sign in by entering your account password.
- **Created**: Displays the date and time when the password was last set or updated.
- **Update**: Use the **Update** button to change your password.
## Two-Factor Authentication (2FA)
For improved security, you can set up **Two-Factor Authentication** using an authenticator application.
- **Authenticator application**: When enabled, you will be asked to provide a verification code from your authenticator app (such as Google Authenticator, Microsoft Authenticator and FreeOTP) each time you sign in.
- **Set up Authenticator application**: Click this link to configure 2FA for your account.
- **Status**: When enabled, you will see the name you have provided during the authenticator configuration. If not configured, it will show *"Authenticator application is not set up."*
:::tip
You can use any other authenticator service which supports generation of SHA1 OTP codes.
:::
- Click on the **Set up Authenticator Application**.
- Scan the QR Code with your selected Authenticator Application. However, if you can't scan the QR code, you can also select **Unable to scan?** field and fill the information accordingly.
- After the code is successfully entered, assign it a friendly name and click on **Save.**
- The newly created OTP will be under effect the next time you login. Your current login session will not be terminated(you will not be logged out).
#### CLI Log In with 2FA
Currently, CLI does not support 2FA connection. You can use the CLI without 2FA connection, even if you have 2FA set up in your account.
:::info Locked out of your Account?
If you have lost your one time password or locked out of your 2FA provider, you can contact us for recovery of your account.
:::
---
## In-app Notifications
In-app notifications in Appcircle keep you informed about important actions within the platform. You can easily view and filter the in-app notifications from the notifications window in the bottom-right corner to stay updated.
Next to the notifications icon, you can see the current number of notifications and unread notifications, displayed as **unread / total**.
## In-app Notifications Actions
By clicking on the icons next to the in-app notification, you can:
- View the relevant documentation
- Copy the notification text
- Delete the notification
If the notification indicates an error, you can also:
- Copy the trace ID
## Filtering In-app Notifications
You can filter in-app notifications by date, module (Build, Signing Identities, etc.), type (Success, Info, Warning, Error), and organization by clicking the filter icon and selecting your filtering method.
You can add multiple filters and remove them by clicking the × icon next to each one.
## Clearing In-app Notifications
You can clear all notifications by clicking **Clear All**. If a filter is active when you click **Clear All**, only the filtered notifications will be deleted.
---
## My Account
The "My Account" screen is accessible from the bottom left hover menu and it contains all operations to manage your personal account details including account security.
Current headlines and the actions you can complete are listed below:
- [Device Activity](/account/my-account/account-management/device-activity)
- [Signing In](/account/my-account/account-management/signing-in)
- [Delete Account](/account/my-account/account-management/delete-account)
In order to see the details, check the submenu of this documentation page.
---
## Sign Up / Login
Getting started with Appcircle is easy. To sign up for or log into Appcircle, go to [my.appcircle.io](https://my.appcircle.io).
To log into Appcircle, you only need to provide your registered email address and password. No additional permissions are required beyond accessing the email. Simply enter your credentials on the login screen, and upon successful authentication, you'll gain access to your account and its features.
## Signing Up
For registration, click on the **Sign up with Company E-mail** button.
Fill in the required information and verify your email address. Follow the instructions sent to your email address to complete the registration.
:::caution
You cannot use common and disposable email domains for registration; instead, please register using your company email account.
:::
## Logging In
To log in, go to [my.appcircle.io](https://my.appcircle.io) and either click on a linked login provider for one-click login or type in your email address and password and click **Log in**.
If you forget your password, you can request a new one by clicking on the **Forgot Password** link and entering your email address.
:::caution
The social login feature **has been deprecated**. Only **previously registered** users can use it.
:::
### Linking a New Login Provider from Login
If the selected account from a login provider has an email address that already exists in Appcircle, you will be prompted to link this account with the current one. When you press the **Add to existing account** button, an email will be sent to the email address to confirm the account linking.
---
## Build Cache
The Artifacts section also allows you to manually clear cached files created during the build process. This helps resolve unexpected caching issues or reduce storage usage.
:::danger Cache Deletion Scope
Clearing caches from a main organization also removes all associated caches from its sub-organizations.
If you only want to remove caches for a specific sub-organization, make sure to perform the action within that sub-organization.
This helps prevent unintended data removal across related organizations.
:::
Clearing the cache only removes temporary build data. It does not affect build artifacts, logs, or published applications.
:::info Permission Required
Only users with **Manager** or **Owner** roles in the build can use the Clean Build Caches feature. For more information, please refer to the [Role Management](/account/my-organization/profile-and-team/role-management#build-permissions) documentation.
:::
:::tip Cache Limit by Plan
The build cache limit shown on the screen is determined by your subscription plan. For example:
- **Starter**: 5GB
- **Developer**: 10GB
- **Professional**: 20GB
- **Enterprise**: 30GB
- **Self-hosted**: Customizable (see the [documentation](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/cache-size-configuration))
:::
For more detailed information on how to use **Cache Pull** and **Cache Push** in Appcircle builds, please refer to the following documentation:
- [Cache Pull](/workflows/common-workflow-steps/build-cache/cache-pull)
- [Cache Push](/workflows/common-workflow-steps/build-cache/cache-push)
Regularly clearing your build cache can help maintain a healthy and efficient build environment.
## FAQ
### Why am I seeing a "cache limit exceeded" error even though my cache usage is not full?
Even if your sub-organization has not used the entire cache limit, other sub-organizations or the main organization may have. The cache limit is shared across the entire organization.
To view the full cache usage and identify which part of the organization is consuming the cache, please visit the **main organization**.
#### Example:
- Your sub-organization may show low usage:
- But the main organization may show that the overall limit has been reached:
---
## Artifacts
The Artifacts section allows you to manage the retention periods of artifacts generated by your Build, Publish, Testing Distribution, and Enterprise App Store modules, as well as clear cache files created by your build profiles.
Current headlines and the actions you can complete are listed below:
- [**Retention Period**](/account/my-organization/artifacts/retention-period)
- [**Build Cache**](/account/my-organization/artifacts/build-cache)
---
## Retention Period
The **Retention Period** feature allows you to define how long Appcircle should retain artifacts generated by different modules : **Build**, **Testing Distribution**, **Publish to Stores**, and **Enterprise App Store**.
## Overview
- **Starter Organizations** use default retention settings and **cannot modify** retention rules.
By default, all artifacts are automatically removed **every month**.
- **Enterprise Organizations** can **fully customize** the retention rules for each module.
Available retention periods include:
- **1 week**
- **1 month**
- **2 months**
- **3 months**
- **6 months**
- **1 year**
- **2 years**
- **Never delete**
## Build Module
The **Build** section provides advanced artifact cleanup rules:
#### Delete Successful Build Artifacts
Automatically removes artifacts generated from **successful builds** that are older than the configured retention period.
#### Delete Failed Build Artifacts
Deletes artifacts produced by **failed builds** that exceed the retention period.
#### Delete Artifacts Matching the Keyword
Removes build artifacts that contain a **specific file extension** in their name.
Example: `.ipa`, `.apk`, `.txt`
#### Keep Artifacts Matching the Keyword
Preserves build artifacts that match specific file extention.
Example: Keep all `.ipa` files while deleting other formats.
:::info Build Retention Rules
- **Delete Artifacts Matching the Keyword** and **Keep Artifacts Matching the Keyword** cannot contain the same values.
- Both fields cannot be empty at the same time, Appcircle will **not delete any build artifacts**.
- **Delete Artifacts Matching the Keyword** setting cannot be empty.
- Only **Keep Artifacts Matching the Keyword** can be empty if you would like to delete all build artifacts or just some specific file types.
:::
:::tip Build Activity Log
Artifacts that were deleted by the Retention Period actions will also be displayed within the Build Activity Log.
:::
## Testing Distribution
The **Testing Distribution** module retention rules include:
#### Delete Distributed Artifacts
Automatically removes **distributed artifacts** that are older than the configured retention period.
#### Delete Undistributed Artifacts
Automatically deletes **undistributed artifacts** that exceed the defined retention period.
:::info Profiles with Distribution Links
Please note that if a Testing Distribution profile has **Distribution Link** option enabled, all binaries within the profile will be considered as 'Distributed artifacts'.
:::
## Publish to Stores
**Publish to Stores** module includes specific rules for artifacts:
#### Delete Publish Module Artifacts
Automatically deletes artifacts within the Publish to Stores module profiles that are older than the retention period.
#### Keep if Marked as RC
When enabled, preserves artifacts marked as **Release Candidate (RC)** even if they exceed the retention period.
#### Keep if Published to Store
Retains artifacts already **released to stores** such as:
- Apple App Store
- Google Play Store
- Huawei AppGallery
- Microsoft Intune
## Enterprise App Store
The **Enterprise App Store** module supports the following retention rule:
#### Delete Enterprise App Store Artifacts
Automatically deletes Enterprise App Store artifacts that exceed the configured retention period.
:::info
Artifacts already **published to the Enterprise Portal** via **Beta** or **Live** channels are **not deleted**, even if they surpass the defined retention period.
:::
:::tip
If an app version with an upload date that exceeds the allowed retention period was recently unpublished from Enterprise Portal channels, it will not be deleted, as it was previously used in the Portal within the allowed retention period.
:::
## Artifacts Reports
The **Artifacts Reports** section provides a detailed overview of artifacts that were **automatically** deleted based on your configured **Retention Period** rules. It will also display the artifacts that were manually deleted by the users.
This report helps organizations monitor and verify which artifacts have been removed, when the deletion occurred, and which rule or trigger caused it.
### Overview
Each row in the report represents a deleted artifact and includes key details such as:
| Column | Description |
|---------|----------------------------------------------------------------------------------------------------------------------------------------------|
| **Org Name** | Displays the organization name that owned the deleted artifact. |
| **Module** | Indicates which Appcircle module the artifact belonged to — *Build*, *Testing Distribution*, *Publish to Stores*, or *Enterprise App Store*. |
| **File Type** | Shows the type of file deleted (e.g., `.ipa`, `.apk`, `.png`). |
| **Size** | Displays the original size of the deleted artifact. |
| **Rule** | Describes the applied retention rule (e.g., *excluding RC*, *excluding sent-to-store*, *delete failed builds*, etc.). |
| **Days** | Indicates the configured retention period for that rule (e.g., 1 month, 6 months). |
| **Description** | Provides the name or description of the deleted artifact for easy identification. |
| **Physically Delete** | Shows whether the artifact was permanently deleted from storage. |
| **Triggered By** | Shows the user email address that deleted the artifact. If it was an automatic process, it would display 'System' . |
| **Job Triggered By** | Specifies the retention job type — |
| **Delete At** | Displays the exact timestamp when the deletion occurred. |
### Filtering Options
You can use the filtering tools at the top of the report to narrow down results:
- **Filter by Date** — View deleted artifacts within a specific time frame (e.g., *Last 7 Days*, *Last Month*).
- **Filter by Module** — Focus on deletions from a particular module such as *Build*, *Publish to Stores*, or *Enterprise App Store*.
- **Filter by Organization** — Display deleted artifacts for your root organization or sub-organizations.
---
## Billing
The Billing section allows you to monitor your usage summary, including builds, publishes, team members, and other module usages. You can also view your license plan and renewal date of your account.
## Usage Summary
- **[Builds](/build/build-process-management/manual-builds)** : Number of builds initiated from the build module in a single billing cycle.
- **[Code Push Updates](/code-push)** : The number of devices receiving CodePush updates within a single billing cycle.
- **[Testing Distribution](/testing-distribution/testing-portal)** : Number of app downloads from the Testing Portal in a single billing cycle.
- **[Publishes](/publish-to-stores-module)** : Number of publishes initiated from the Publish module in a single billing cycle.
- **[Enterprise App Store](/enterprise-app-store/enterprise-portal)** : Number of app downloads from the Enterprise App Store in a single billing cycle.
- **[Team Members](/account/my-organization/profile-and-team/team-management)** : Number of team members allowed in a single organization.
- **[Artifact Storage](/account/my-organization/artifacts)** : Total storage size for all the build and distribution artifacts across the platform.
- **[Build Concurrency](/build/build-process-management/manual-builds)** : Number of builds that can run simultaneously.
- **[Build Time Limit](/build/build-process-management/manual-builds)** : Number of minutes allowed per build and publish before it is automatically cancelled with a timeout status.
- **[Machine Plan](/infrastructure/machine-plans)** : Indicates the Machine Plan assigned to the organization.
:::info Usage Count
Please note that the module usage counts displayed here, such as builds, testing distribution, and publishes, represent the combined totals for the organization and its sub-organizations.
:::
:::warning Limit Warnings
When the usage limits exceed 85% of the allocated quota, notification emails will be sent to the organization’s Owner and the Billing Manager.
:::
### Sub-Organization Usage
The Billing page for a Sub-Organization displays the same summary metrics as the root organization, except for:
- **Team Members**
- **Artifact Storage**
:::warning
The usage counts shown on this page reflect only the usage of the Sub-Organization. To view overall usage against limits, please refer to the Billing page of the root organization.
:::
---
## My Organization
The "My Organization" section is your central hub for managing everything related to your organization within Appcircle. Here, you can oversee all projects, manage user roles, and control access levels to ensure that each team member has the right permissions. This area also allows you to monitor activity, configure organization-wide settings, and streamline collaboration across your teams. Whether you're adding new members or adjusting permissions, the "My Organization" section gives you complete control over your organization’s structure and workflow.
Current headlines and the actions you can complete are listed below:
- [**Profile and Team**](/account/my-organization/profile-and-team)
- [**Security**](/account/my-organization/security)
- [**Notifications**](/account/my-organization/notifications)
- [**Artifacts**](/account/my-organization/artifacts)
- [**Organization Activity**](/account/my-organization/profile-and-team/organization-activity)
In order to see the details, check the submenu of this documentation page.
---
## Email Notifications
# Email Notifications and Subscription Management
This feature allows users with specified email addresses to be notified by email of the actions specified in Appcircle (starting a build, adding an IOS certificate, the store submission process, etc.).
:::info
Appcircle email notification can work independently for each module. For example, you can send notifications to different people for events under the Build module and to different people for store submission operations.
You can also define more than one email address for a module and send notifications. Scroll down and check out the other modules that you can tweak.
:::
:::info
After completing the specified action in Appcircle, you have the option to share release notes via email.
To enable this feature, ensure you include the [**Publish Release Notes**](https://docs.appcircle.io/workflows/common-workflow-steps/publish-release-notes/) step in your workflow.
Additionally, note that you can access download links for the release notes for a duration of 90 days.
:::
:::info
After completing the specified action in Appcircle, you have the option to share the test results via email.
To enable this feature, ensure you include the [**Test Reports**](https://docs.appcircle.io/continuous-testing/running-ios-unit-and-ui-tests#generating-test-report) step in your workflow.
:::
## Available Notification Events by Module
Appcircle allows you to configure email notifications separately for each module. Each module supports a set of predefined events that can trigger email notifications. You can subscribe one or more email addresses to these events based on your needs.
Below is a high-level overview of the notification event categories per module. You can customize the event list according to your workflow and organizational requirements.
### Build Module
The Build module can send notifications for key build lifecycle events, such as:
#### Build Events
- Build Started
- Build Success
- Build Complete with Warnings
- Build Failed
- Build Canceled
- Build Timeout
- Fetch Started
- Test Report Created
- Build Cache Cleared
#### License Events
- Retention Policy Updated
#### CodePush Events
- CodePush App Created
- CodePush Deployment Created
- CodePush App Deleted
- CodePush Deployment Channel Deleted
- New CodePush Release Published
- CodePush Release Disabled
- CodePush Release Enabled
- CodePush Release Rolled Back
- CodePush Rollout Updated
### Signing Identity
Notifications related to certificate, keystore, and provisioning profile operations, such as:
- iOS Certificate Added
- iOS Certificate Deleted
- iOS Certificate Expiration Reminder
- iOS Provisioning Profile Added
- iOS Provisioning Profile Deleted
- iOS Provisioning Profile Expiration Reminder
- Android Keystore Created
- Android Keystore Uploaded
- Android Keystore Deleted
- Android Keystore Expiration Reminder
- Apple Device List Fetch Success
- Apple Device Registered
- Apple Device Updated
- Apple Multiple Devices Updated
- Apple Multiple Devices Registered
- Apple Device Provisioned
- Apple Device Unregistered
- Apple Identifier Created
- Apple Identifier Deleted
- Apple Identifier Created in Apple Developer Portal
- Apple Identifier Updated in Apple Developer Portal
### Testing Distribution
Notifications for Testing Distribution related events such as:
- New Version Added for Distribution
- New Version Uploaded for Distribution
- App Shared for Testing Distribution
### Publish to Stores
Notifications for Publish to Stores related events such as:
- Store Status Changed
- New Version Deployed to Publish
- New Version uploaded to Publish
- A Version is Rejected on Publish
- Publish Step is Starting
- Publish Step is Restarting
- Publish Step Started
- Publish Step Succeeded
- Publish Flow Updated
- Publish Step Failed
- Publish Step Canceled
- Publish Step Timed Out
- Publish Flow Failed
- Publish Flow Canceled
- Publish Flow Timed Out
- Publish Flow Succeeded
### Enterprise App Store
Notifications for Enterprise App Store related events such as:
- New Version Deployed to the Enterprise Store
- New Version Uploaded to the Enterprise Store
- App Shared on Enterprise Store
### Re-sign
Notifications for binary re-sign actions throughout each supporting module.
- Initializing Re-sign
- Re-sign Successful
- Re-sign Failed
- Re-sign Canceled
## Email Notifications: Unsubscribe
To cancel email notifications, you can click the unsubscribe button in the notification email, or you can delete the email address for the relevant module by following the steps below:
**My Organization -> Notifications -> Email -> Manage**
:::info
If the user unsubscribes via email, the relevant email will be deleted directly from the module. If you want to send notifications, you will need to add the email address again.
:::
---
## Notification Integrations
The "Notification Integrations" section lets you connect Appcircle with your preferred communication tools, like Slack and email, to keep your team informed. Easily configure notifications to ensure that important updates and alerts reach the right people at the right time, enhancing collaboration and response times across your projects.
Current headlines and the actions you can complete are listed below:
- [**Email Notifications**](/account/my-organization/notifications/email-connection)
- [**Microsoft Teams Notifications**](/account/my-organization/notifications/teams-notifications)
- [**Slack Notifications**](/account/my-organization/notifications/slack-notifications)
- [**Webhook Configurations**](/account/my-organization/notifications/webhooks)
---
## Slack Notifications
Appcircle supports sending notifications to Slack for the major events in all modules. You can connect Appcircle to your Slack workspace to set up module based event notifications to be sent to the selected channels.
:::info
There is currently no Slack integration available on the self-hosted Appcircle. However, we are actively working on it and it will be available for use on the self-hosted Appcircle in the near future.
:::
### Connecting Appcircle to Slack
An Appcircle organization can be associated with a single Slack workspace. To start, go to [My Organization](/account/my-organization) > Notifications screen and press the **Connect** button next to Slack under the **Notification Providers** section.
Provide permission to the Appcircle app on Slack so that the channel list can be fetched for selection and the status can be sent as a message.
You will then see that Slack is connected. To manage the notification settings or to disconnect, press the "Manage" button.
### Setting Up Module-Based Notifications in the Slack Settings
You can set up notifications for the major events in each module (Build, Signing Identities, Distribute and Store Submission).
To enable notifications for a specific event, first select the Slack channel that will receive the notifications for the specific module and then use the toggle to enable the event notifications.
:::caution
Due to a technical limitation, subscribing events to a private Slack channel(s) is not possible at this moment.
:::
:::info
You can customize which Slack events to get by selecting or deselecting specific events. You can also set different Slack channels for different kinds of events.
Keep scrolling down on Appcircle to see the full list of events.
:::
:::info
After completing the specified action in Appcircle, you have the option to share release notes via Slack.
To enable this feature, ensure you include the [**Publish Release Notes**](https://docs.appcircle.io/workflows/common-workflow-steps/publish-release-notes/) step in your workflow.
Additionally, note that you can access download links for the release notes for a duration of 90 days.
:::
:::info
After completing the specified action in Appcircle, you have the option to share the test results via Slack.
To enable this feature, ensure you include the [**Test Reports**](https://docs.appcircle.io/continuous-testing/running-ios-unit-and-ui-tests#generating-test-report) step in your workflow.
:::
## Available Notification Events by Module
Appcircle allows you to configure Slack notifications separately for each module. Each module supports a set of predefined events that can trigger Slack notifications. You can subscribe different Slack Channels for each module to receive these events based on your needs.
Below is a high-level overview of the notification event categories per module. You can customize the event list according to your workflow and organizational requirements.
### Build Module
The Build module can send notifications for key build lifecycle events, such as:
#### Build Events
- Build Started
- Build Success
- Build Complete with Warnings
- Build Failed
- Build Canceled
- Build Timeout
- Fetch Started
- Test Report Created
- Build Cache Cleared
#### License Events
- Retention Policy Updated
#### CodePush Events
- CodePush App Created
- CodePush Deployment Created
- CodePush App Deleted
- CodePush Deployment Channel Deleted
- New CodePush Release Published
- CodePush Release Disabled
- CodePush Release Enabled
- CodePush Release Rolled Back
- CodePush Rollout Updated
### Signing Identity
Notifications related to certificate, keystore, and provisioning profile operations, such as:
- iOS Certificate Added
- iOS Certificate Deleted
- iOS Certificate Expiration Reminder
- iOS Provisioning Profile Added
- iOS Provisioning Profile Deleted
- iOS Provisioning Profile Expiration Reminder
- Android Keystore Created
- Android Keystore Uploaded
- Android Keystore Deleted
- Android Keystore Expiration Reminder
- Apple Device List Fetch Success
- Apple Device Registered
- Apple Device Updated
- Apple Multiple Devices Updated
- Apple Multiple Devices Registered
- Apple Device Provisioned
- Apple Device Unregistered
- Apple Identifier Created
- Apple Identifier Deleted
- Apple Identifier Created in Apple Developer Portal
- Apple Identifier Updated in Apple Developer Portal
### Testing Distribution
Notifications for Testing Distribution related events such as:
- New Version Added for Distribution
- New Version Uploaded for Distribution
- App Shared for Testing Distribution
### Publish to Stores
Notifications for Publish to Stores related events such as:
- Store Status Changed
- New Version Deployed to Publish
- New Version uploaded to Publish
- A Version is Rejected on Publish
- Publish Step is Starting
- Publish Step is Restarting
- Publish Step Started
- Publish Step Succeeded
- Publish Flow Updated
- Publish Step Failed
- Publish Step Canceled
- Publish Step Timed Out
- Publish Flow Failed
- Publish Flow Canceled
- Publish Flow Timed Out
- Publish Flow Succeeded
### Enterprise App Store
Notifications for Enterprise App Store related events such as:
- New Version Deployed to the Enterprise Store
- New Version Uploaded to the Enterprise Store
- App Shared on Enterprise Store
### Re-sign
Notifications for binary re-sign actions throughout each supporting module.
- Initializing Re-sign
- Re-sign Successful
- Re-sign Failed
- Re-sign Canceled
## Disconnecting Slack
If you want to disconnect or reauthorize the Slack connection, scroll down to the end of the management screen and press the "Disconnect" button.
---
## Microsoft Teams Notifications
Appcircle supports sending notifications to Microsoft Teams for the major events in all modules. You can connect Appcircle to your Microsoft Team channel to set up module-based event notifications to be sent to the selected channel.
## Connecting Microsoft Teams via Workflows
Microsoft now recommends using **Workflows-based webhooks** instead of the legacy Incoming Webhook connector.
This new approach provides a secure and scalable way to send notifications to Teams channels.
To connect Appcircle using Workflows:
1. Open the target Teams channel.
2. Click the **••• (More options)** menu.
3. Select **Workflows**.
4. Choose the template **Send Webhook alerts to a channel**.
5. Select the Team and Channel where notifications should be posted.
6. Add the workflow and copy the generated webhook URL.
7. Paste this URL into Appcircle when configuring notification webhooks (for example via the *Send webhook alerts to channel* workflow step).
When a notification payload is sent to this workflow URL, Microsoft Teams processes the request and posts the message to the configured channel.
## Adding Incoming Webhook to Microsoft Teams
:::warning Incoming Webhook Retirement Notice
Microsoft is retiring **Office 365 Connectors**, including the **Incoming Webhook** integration used by Microsoft Teams.
The migration deadline has been extended, and organizations must transition to the new workflow-based webhook model **by April 30, 2026** to avoid service disruption.
If you are using the Incoming Webhook integration in Appcircle, we strongly recommend migrating to the new workflow-based webhook connection method as soon as possible.
:::
In order to get notifications, the administrator of the channel should add an incoming webhook to the given channel.
- Click the ••• button to the right of `General` under the channel and then click `Manage Channel` [2].
- On the openned screen, click on the `Edit` button under the `Connector` header [3].
- Search for **Incoming Webhook** and click Configure.
- Give your webhook a name and save it. It will give you a webhook URL.
### Connecting Appcircle to Microsoft Teams
An Appcircle organization can be associated with a single Teams channel. To start, go to [My Organization](/account/my-organization) > Notifications screen and press the "Connect" button next to Microsoft Teams under the "Notification Providers" section.
Write the webhook URL that you created in the previous step and select the events you want to receive. You can set up notifications for the major events in each module (Build, Signing Identities, Distribute and Store Submission).
:::info
After completing the specified action in Appcircle, you have the option to share release notes via Microsoft Teams.
To enable this feature, ensure you include the [**Publish Release Notes**](https://docs.appcircle.io/workflows/common-workflow-steps/publish-release-notes/) step in your workflow.
Additionally, note that you can access download links for the release notes for a duration of 90 days.
:::
:::info
After completing the specified action in Appcircle, you have the option to share the test results via Microsoft Teams.
To enable this feature, ensure you include the [**Test Reports**](https://docs.appcircle.io/continuous-testing/running-ios-unit-and-ui-tests#generating-test-report) step in your workflow.
:::
## Available Notification Events by Module
Appcircle allows you to configure Teams notifications separately for each module. Each module supports a set of predefined events that can trigger Slack notifications. You can subscribe different Teams Channels for each module to receive these events based on your needs.
Below is a high-level overview of the notification event categories per module. You can customize the event list according to your workflow and organizational requirements.
### Build Module
The Build module can send notifications for key build lifecycle events, such as:
#### Build Events
- Build Started
- Build Success
- Build Complete with Warnings
- Build Failed
- Build Canceled
- Build Timeout
- Fetch Started
- Test Report Created
- Build Cache Cleared
#### License Events
- Retention Policy Updated
#### CodePush Events
- CodePush App Created
- CodePush Deployment Created
- CodePush App Deleted
- CodePush Deployment Channel Deleted
- New CodePush Release Published
- CodePush Release Disabled
- CodePush Release Enabled
- CodePush Release Rolled Back
- CodePush Rollout Updated
### Signing Identity
Notifications related to certificate, keystore, and provisioning profile operations, such as:
- iOS Certificate Added
- iOS Certificate Deleted
- iOS Certificate Expiration Reminder
- iOS Provisioning Profile Added
- iOS Provisioning Profile Deleted
- iOS Provisioning Profile Expiration Reminder
- Android Keystore Created
- Android Keystore Uploaded
- Android Keystore Deleted
- Android Keystore Expiration Reminder
- Apple Device List Fetch Success
- Apple Device Registered
- Apple Device Updated
- Apple Multiple Devices Updated
- Apple Multiple Devices Registered
- Apple Device Provisioned
- Apple Device Unregistered
- Apple Identifier Created
- Apple Identifier Deleted
- Apple Identifier Created in Apple Developer Portal
- Apple Identifier Updated in Apple Developer Portal
### Testing Distribution
Notifications for Testing Distribution related events such as:
- New Version Added for Distribution
- New Version Uploaded for Distribution
- App Shared for Testing Distribution
### Publish to Stores
Notifications for Publish to Stores related events such as:
- Store Status Changed
- New Version Deployed to Publish
- New Version uploaded to Publish
- A Version is Rejected on Publish
- Publish Step is Starting
- Publish Step is Restarting
- Publish Step Started
- Publish Step Succeeded
- Publish Flow Updated
- Publish Step Failed
- Publish Step Canceled
- Publish Step Timed Out
- Publish Flow Failed
- Publish Flow Canceled
- Publish Flow Timed Out
- Publish Flow Succeeded
### Enterprise App Store
Notifications for Enterprise App Store related events such as:
- New Version Deployed to the Enterprise Store
- New Version Uploaded to the Enterprise Store
- App Shared on Enterprise Store
### Re-sign
Notifications for binary re-sign actions throughout each supporting module.
- Initializing Re-sign
- Re-sign Successful
- Re-sign Failed
- Re-sign Canceled
## Disconnecting Microsoft Teams
If you want to disconnect or reauthorize the Microsoft Teams connection, scroll down to the end of the management screen and press the "Disconnect" button.
## Troubleshooting & FAQ
### Notifications are not delivered when using self-hosted Appcircle.
If your Microsoft Teams notifications are not delivered while using the self-hosted Appcircle, there can be 3 reasons for this to check.
**1.** Proxy Requirement
If you are using a proxy to connect to the internet on the host, the proxy must also be enabled for the Appcircle services too, that is, in the containers. You can refer to the [**Proxy Configuration**](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration.md) documentation to see how to configure proxy for the self-hosted Appcircle server.
**2.** Network Access
The Appcircle server may not have network access to the Microsoft Teams webhook URL you provided. For example, if you are using a firewall or proxy, you must have permission to access this URL. Please contact your network administrator for the required network access permission.
**3.** Untrusted SSL Certificate
When the Appcircle server sends a request to the webhook URL through the proxy, it might encounter an error due to the untrusted SSL certificate of the proxy. In this case, you should refer to the [**Connecting External Services**](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration.md#external-services) section in the self-hosted Appcircle documents to see how to trust your self-signed certificates.
---
## Webhooks Configuration
Appcircle will notify external services via webhooks when a certain event occurs. When the events you specified happen, we'll send a POST request in JSON format to the URLs you
provide.
### Creating Webhook
Multiple webhooks can be created for different events and build profiles. To start, go to [My Organization](/account/my-organization) Notifications screen and press the **Manage** button next to Webhook under the **Notification Providers** section.
- Click Add Webhook button to create your webhook
- Fill in the details of your webhook
## Available Notification Events by Module
The following scopes are supported for Webhooks.
**Profile:** Most scopes support getting events for the selected profile (Build, Testing Distribution, Publish to Stores, Enterprise app Store). You can choose the profile from the list to get notified for that specific module profile.
### Build Module
The Build module can send notifications for key build lifecycle events, such as:
#### Build Events
- Build Started
- Build Success
- Build Complete with Warnings
- Build Failed
- Build Canceled
- Build Timeout
- Fetch Started
- Test Report Created
#### License Events
- Retention Policy Updated
### Signing Identity
Notifications related to certificate, keystore, and provisioning profile operations, such as:
- iOS Certificate Added
- iOS Certificate Deleted
- iOS Certificate Expiration Reminder
- iOS Provisioning Profile Added
- iOS Provisioning Profile Deleted
- iOS Provisioning Profile Expiration Reminder
- Android Keystore Created
- Android Keystore Uploaded
- Android Keystore Deleted
- Android Keystore Expiration Reminder
- Apple Device List Fetch Success
- Apple Device Registered
- Apple Device Updated
- Apple Multiple Devices Updated
- Apple Multiple Devices Registered
- Apple Device Provisioned
- Apple Device Unregistered
- Apple Identifier Created
- Apple Identifier Deleted
- Apple Identifier Created in Apple Developer Portal
- Apple Identifier Updated in Apple Developer Portal
### Testing Distribution
Notifications for Testing Distribution related events such as:
- New Version Added for Distribution
- New Version Uploaded for Distribution
- App Shared for Testing Distribution
### Publish to Stores
Notifications for Publish to Stores related events such as:
- Store Status Changed
- New Version Deployed to Publish
- New Version uploaded to Publish
- A Version is Rejected on Publish
- Publish Step is Starting
- Publish Step is Restarting
- Publish Step Started
- Publish Step Succeeded
- Publish Flow Updated
- Publish Step Failed
- Publish Step Canceled
- Publish Step Timed Out
- Publish Flow Failed
- Publish Flow Canceled
- Publish Flow Timed Out
- Publish Flow Succeeded
### Enterprise App Store
Notifications for Enterprise App Store related events such as:
- New Version Deployed to the Enterprise Store
- New Version Uploaded to the Enterprise Store
- App Shared on Enterprise Store
**Payload URL:**
Appcircle will post events to this URL. It is highly recommended to choose the HTTPS URL.
**Secret:**
To verify that a Webhook post is coming from Appcircle, you may use this secret to verify the message body. **HMAC-SHA256** of payload with your secret key should be the same as the hexadecimal signature you get in the `ac_signature` header
For example, if you used **test** as your secret and Appcircle sends you a webhook with following body,
```
{"deliveryId":"ee81f55b-fd14-4f95-9e1f-f5bce3ad29e4","timestamp":"2022-10-26T14:55:08.4622757+00:00","action":"Build|BuildStart","message":"Build started for the develop branch for the profile pr_mr_tag_test https://my.appcircle.io/build/detail/7f17fdb4-46e7-40c3-a01d-1ef18de06890","title":"Build Started","item":{"id":"9e3c7dcd-d292-4144-9844-ca07df6a8924","agentId":"4026b6f2-d298-4b54-aa31-64726ad076fc","organizationId":"6fbd094c-18cb-4bcd-bc6f-cf2aee752982","userId":"6320a79e-d1f0-45d0-a38e-920dc4c30644","profileId":"7f17fdb4-46e7-40c3-a01d-1ef18de06890","branchId":"3779c7d2-c826-4596-95f2-52486bf75471","buildId":"00000000-0000-0000-0000-000000000000","commitId":"ba50d2d6-bfcc-49a1-8fa6-6e00711b4d5b","taskId":"9e3c7dcd-d292-4144-9844-ca07df6a8924","purpose":1,"triggerReason":0,"cancelling":false,"queueItemStatus":1,"xcodeVersion":""},"links":{"detail":"https://my.appcircle.io/build/detail/7f17fdb4-46e7-40c3-a01d-1ef18de06890","viewlogs":"https://my.appcircle.io/build/detail/7f17fdb4-46e7-40c3-a01d-1ef18de06890?modal=/build/modal/Logs&profileId=7f17fdb4-46e7-40c3-a01d-1ef18de06890&commitId=ba50d2d6-bfcc-49a1-8fa6-6e00711b4d5b&buildId=9e3c7dcd-d292-4144-9844-ca07df6a8924&scope=build&method=get"}}
```
Calculating HMAC-256 of this payload with **test** should give you
`8470172a1c60447abd7dce97227448da2b369b17d54d128306625979eca6476b` This value must be the same as the value of `ac_signature` header of the request.
You may also check the `timestamp` of the payload to prevent replay attacks. You may give 5-10 minutes of a threshold for the timestamp for late webhook deliveries.
### Request History
You can check all the webhooks Appcircle sends to your endpoint by clicking the... button and then clicking the **Request History** section.
You can see all the requests and their results by clicking on them.
:::info
After completing the specified action in Appcircle, you have the option to share release notes via Webhooks.
To enable this feature, ensure you include the [**Publish Release Notes**](https://docs.appcircle.io/workflows/common-workflow-steps/publish-release-notes/) step in your workflow.
Additionally, note that you can access download links for the release notes for a duration of 90 days.
:::
:::info
After completing the specified action in Appcircle, you have the option to share the test results via Webhooks.
To enable this feature, ensure you include the [**Test Reports**](https://docs.appcircle.io/continuous-testing/running-ios-unit-and-ui-tests#generating-test-report) step in your workflow.
:::
## Editing Webhook
You can edit your webhook by clicking the... button and then clicking the **Edit** section.
## Deleting Webhook
You can edit your webhook by clicking the... button and then clicking the **Delete** section.
:::tip
You may use https://webhook.site to test and inspect your webhooks.
:::
---
## Profile and Team
The Organization and Team Management section provides comprehensive tools to structure and manage your teams effectively within Appcircle. Here, you can define roles, assign permissions, and organize team members according to your project needs. This section also covers how to manage multiple organizations, control access levels, and ensure that every team member has the appropriate permissions to perform their tasks efficiently. Whether you’re overseeing a large enterprise or a smaller development team, these features help you maintain order and enhance collaboration across all levels of your organization.
Current headlines and the actions you can complete are listed below:
- [**Organization Management**](/account/my-organization/profile-and-team/organization-management)
- [**Team Management**](/account/my-organization/profile-and-team/team-management)
- [**Role Management**](/account/my-organization/profile-and-team/role-management)
In order to see the details, check the submenu of this documentation page.
---
## Organization Management
## Managing Organization
The "My Organization" screen is accessible from the button with the organization name initials at the bottom left and it contains all operations to manage an organization.
### Organization Name and ID Management
When you create an account, an individual organization for you is created by default with your email address.
In the left column under the organization management screen, you can change your organization name, which is a descriptive name, for that specific organization.
:::caution Organization Identifier
You cannot change the Appcircle organization unique ID. This value is a unique identifier assigned by Appcircle.
:::
:::info Organization Name
When your Appcircle organization is first created, your email address is used as the organization name. To avoid confusion when working with multiple organizations, we recommend changing your organization name.
:::
To update these details, simply enter the new values and press _Update_.
## Working with Multiple Organizations
### Adding an Organization
To add a new organization, press the "Create New Organization" button on the top-right (denoted by a plus sign) and type in the Organization Name. The organization will be created with the specified name and your role will be set as the owner.
:::caution
If you are on the Starter Plan, you cannot add a new organization. To create more organizations, you need to upgrade to a higher plan.
:::
### Adding a Sub Organization
Appcircle's Sub-Organization feature allows you to create multiple sub-organizations from your organization, providing a way to manage different teams and projects separately. With this feature, each sub-organization is linked to the organization.
It's worth noting that sub organizations are very similar to the organization. When you are inside a sub organization, you will have access to all the features and functionality that are available in your organization. Any licenses associated with the organization will also be applicable to the sub organization.
:::caution
To use this feature, an enterprise license is required.
:::
:::info
If you add a user to the sub-organization who already exists in the main organization, all the permissions assigned to that user in the main organization will automatically extend to the sub-organization as well.
:::
It's worth noting that sub-organizations are very similar to the organization. When you are inside a sub-organization, you will have access to all the features and functionality that are available in your organization. Additionally, any licenses associated with the organization will also be applicable to the sub-organization.
:::caution
Please note that an **Enterprise License** is required to use this feature.
:::
If you have an enterprise license, you can create sub-organizations from the organization by navigating to the "My Organization" page, clicking on the **`Create Sub Organization`** button, and entering the necessary details for the sub-organization.
Multiple sub-organizations can be created from an organization as required. This feature is particularly useful for businesses with multiple teams working on different projects, providing a way to manage each team's access to Appcircle separately. With the Sub-Organization feature, businesses can create and manage multiple sub-organizations linked to the organization, giving different teams access to the tools they need to work on their specific projects.
#### Why do you need sub-organizations?
Sub-organizations are subsidiary organizations linked to the main organization, all of which can be easily managed from within the main organization. The primary purpose of creating sub-organizations is to provide isolation. For example, if you have three different projects within Appcircle, each with its own dedicated teams, the sub-organization structure allows you to isolate these projects and teams from one another, making management more straightforward and efficient.
### Switching Organizations
Once you create an organization or accept an organization invite, you will be switched to that organization automatically. To switch between organizations, press the quick team switching button on the bottom-left on status bar and select an organization from the menu. The currently selected one is indicated with a check mark.
Each organization is isolated from each other, and switching means that you will switch to the "workspace" of that organization.
:::info
Once you select your organization, you will only see the profiles, artifacts, and reports belonging to that organization in all modules.
You can switch between organizations at any time without any data loss.
:::
To switch between organizations or sub organizations, follow these steps:
1. **Locate the Organization Switch Button:**
- Find the button displaying the name of your current organization at the bottom of your screen.
2. **Press the Organization Switch Button:**
- Click this button to display a list of available organizations and sub-organizations you are part of.
3. **Select the Desired Organization:**
- From the list, choose the organization or sub-organization you want to switch to.
:::important
- **Membership Requirement:** You will only be able to view and switch to organizations that you are a member of. Organizations that you are not a member of will not be visible in the list.
:::
By following these steps, you can seamlessly navigate between different organizations within your account.
:::caution Avoid Using Multiple Organizations in the Same Browser
Using two different organizations in separate tabs or windows of the **same browser** is not recommended. Doing so may lead to unexpected behavior, session conflicts, or errors.
If you need to access multiple organizations simultaneously, please use **different browsers** to keep sessions isolated.
:::
### Leaving or Deleting an Organization
To leave or delete an organization, press the organization operations button on the top-right (three-dots menu) and select the related operation.
You will be prompted before the leave/delete operation.
:::caution
Both leaving and deleting are irreversible operations and it is advised to use them with caution:
- If you leave an organization, only an Owner can add you back, even if you were an Owner.
- If you delete an organization, you will lose ALL platform data including apps, profiles, and artifacts.
:::
---
## Role Management
With Appcircle's [Advanced Role Management](/account/my-organization/profile-and-team/team-management#advanced-role-management) structure, you can assign specific roles to organization members for each module, allowing you to manage and restrict their permissions effectively. Appcircle provides various role types for each module, with a brief description of each role provided in the table below. For more detailed information on role management for each module, please refer to the respective module titles.
- **Owner**: The user is authorized for unlimited access to all modules.
- **Manager**: The user becomes the administrator of the relevant module with no restrictions.
- **Operator**: The user manages the operations of the relevant module, with certain restrictions in place.
- **Ext. Operator**: The user has very limited authorization in the relevant module, typically intended for third-party employees from outside the company.
- **Viewer**: The user only has view authorization in the relevant module and cannot take any action.
:::caution Role Types
Some role types are not used in certain modules because they are redundant or unnecessary, as they serve the same function as another role. Therefore, roles may vary for each module.
:::
:::caution Multiple Role Assignment for Users
When assigning roles on Appcircle, you can assign more than one role for a user at the same time. For example, a user can be both **Manager** and **Operator** in the Build module.
For this reason, Appcircle behavior will change when multiple roles are assigned. For example, you have assigned **Ext Operator** and **Viewer** role in **Publish to Stores Module** for a user. This means that the Ext Operator role now has the privileges of the Viewer role. So while Ext Operator cannot see Activity logs, it now has access to those logs because it also has the viewer role.
:::
### Build Permissions
The following table details the roles and restrictions for the [**Build**](/build) module. Please refer to the related module information and caution notes.
| Build Sub-modules | Scopes | Owner | Manager | Operator | Viewer |
|---------------------|--------------------------------------------|-------|---------|----------|--------|
| Build Profile | Add/Delete/Update Build Profiles | ✅ | ✅ | ⛔ | ⛔ |
| Build Profile | List Build Profiles | ✅ | ✅ | ✅ | ✅ |
| Build Profile | Build List | ✅ | ✅ | ✅ | ✅ |
| Repository | Connect/Disconnect Repository | ✅ | ✅ | ⛔ | ⛔ |
| Webhook | View Webhook URL, Webhook Key | ✅ | ✅ | ✅ | ✅ |
| Webhook | Generate Webhook Key | ✅ | ✅ | ⛔ | ⛔ |
| Configuration | Add/Delete/Update Build Configuration | ✅ | ✅ | ⛔ | ⛔ |
| Configuration | View Build Configuration | ✅ | ✅ | ✅ | ✅ |
| Workflow | Add/Delete/Update Workflows | ✅ | ✅ | ⛔ | ⛔ |
| Workflow | View Workflows | ✅ | ✅ | ✅ | ✅ |
| Triggers | Add/Delete/Update Triggers | ✅ | ✅ | ⛔ | ⛔ |
| Triggers | View Triggers | ✅ | ✅ | ✅ | ✅ |
| Build Actions | Start Build | ✅ | ✅ | ✅ | ⛔ |
| Build Actions | Delete Commit Artifacts | ✅ | ✅ | ⛔ | ⛔ |
| Build Actions | Download Artifacts | ✅ | ✅ | ✅ | ✅ |
| Build Actions | Distribution Binary | ✅ | ✅ | ✅ | ⛔ |
| Build Actions | View Build Cache Size Usage | ✅ | ✅ | ✅ | ✅ |
| Build Actions | Clear Build Caches | ✅ | ✅ | ⛔ | ⛔ |
| Test Results | List Test Results | ✅ | ✅ | ✅ | ✅ |
| Connection | Add/Delete/Update Connections (User Based) | ✅ | ✅ | ✅ | ✅ |
| Connection | List Connection (User Based) | ✅ | ✅ | ✅ | ✅ |
| Runner | Add/Delete/Update Runner(Root Only) | ✅ | ⛔ | ⛔ | ⛔ |
| Runner | List Runner(Root Only) | ✅ | ✅ | ✅ | ✅ |
| Runner Access Token | Create/Delete Runner Access Token | ✅ | ⛔ | ⛔ | ⛔ |
| Runner Access Token | List Runner Access Token | ✅ | ⛔ | ⛔ | ⛔ |
| Report | List Build Reports | ✅ | ✅ | ✅ | ✅ |
| Build Cache | View Build Cache Usage | ✅ | ✅ | ✅ | ✅ |
| Build Cache | Delete Build Cache | ✅ | ✅ | ⛔ | ⛔ |
| Build History | View Build History | ✅ | ✅ | ✅ | ✅ |
| Build Activity Log | View Build Activity Log | ✅ | ✅ | ✅ | ✅ |
:::caution Distribution Binary and Runner Details
- **Manager** or **Operator** Build Profile permission can distribute binary if user has **Manager** or **Operator** distribution permission.
- **Manager** or **Operator** Build Profile permission can publish if user has **Manager** or **Operator** Publish Android/iOS permission.
- **Manager**, **Operator** and **Viewer** Build Profile permissions can view self-hosted runners but **cannot** modify the configuration.
:::
### Environment Variables Permissions
The following table details the roles and restrictions for the [**Environment Variables**](/environment-variables). Please refer to the related module information and caution notes.
| Environment Variable | Scopes | Owner | Manager | Viewer |
|----------------------|-----------------------------------------------|-------|---------|--------|
| Environment Variable | Add/Delete/Update Environment Variable Groups | ✅ | ✅ | ⛔ |
| Environment Variable | Add/Delete/Update Environment Variable | ✅ | ✅ | ⛔ |
| Environment Variable | List Environment Variable | ✅ | ✅ | ✅ |
| Environment Variable | List Environment Variable Groups | ✅ | ✅ | ✅ |
:::info
**Manager**, **Operator** and **Viewer** Environment Variable permissions can use variable groups in [**Build profile configuration**](/build/build-environment-variables).
:::
### CodePush Permissions
The following table details the roles and restrictions for the [**CodePush**](/code-push). Please refer to the related module information and caution notes.
| CodePush | Scopes | Owner | Manager | Operator | Viewer |
|--------------------|-------------------------------------|-------|---------|----------|--------|
| CodePush Profile | Add/Delete/Update | ✅ | ✅ | ⛔ | ⛔ |
| Deployment Channel | Add/Delete/Update | ✅ | ✅ | ⛔ | ⛔ |
| Release | Release Version/Rollback | ✅ | ✅ | ✅ | ⛔ |
| Deployment Keys | List/Copy | ✅ | ✅ | ✅ | ⛔ |
| Release Version | List | ✅ | ✅ | ✅ | ✅ |
| Release Version | Promote/Settings Update/Download | ✅ | ✅ | ✅ | ⛔ |
### Signing and Identity Permissions
The following table details the roles and restrictions for the [**Signing and Identity**](/signing-identities) module. Please refer to the related module information and caution notes.
| Signing Identity Sub-modules | Scopes | Owner | Manager | Viewer |
|---------------------------------|----------------------------------------|-------|---------|--------|
| Apple Cerficate | Add/Delete/Download Apple Certificates | ✅ | ✅ | ⛔ |
| Apple Cerficate | List Apple Certificates | ✅ | ✅ | ✅ |
| Apple Cerficate Signing Request | Add/Delete/Download CSR | ✅ | ✅ | ⛔ |
| Apple Cerficate Signing Request | Convert CSR to .p12 | ✅ | ✅ | ⛔ |
| Apple Cerficate Signing Request | List CSR | ✅ | ✅ | ✅ |
| Apple Identifiers | Add/Delete/Update Apple Identifiers | ✅ | ✅ | ⛔ |
| Apple Identifiers | List Apple Identifiers | ✅ | ✅ | ✅ |
| Apple Device | Add Device Manuel | ✅ | ✅ | ⛔ |
| Apple Device | Invite User via Email | ✅ | ✅ | ⛔ |
| Apple Device | Delete Apple Device | ✅ | ✅ | ⛔ |
| Apple Device | Sync from Apple Developer | ✅ | ✅ | ⛔ |
| Apple Device | Register Devices to Apple Developer | ✅ | ✅ | ⛔ |
| Apple Device | Adding New Device to Provision | ✅ | ✅ | ⛔ |
| Apple Device | List Apple Device | ✅ | ✅ | ✅ |
| Apple Profile | Add/Delete/Update Apple Profiles | ✅ | ✅ | ⛔ |
| Apple Profile | List Apple Profiles | ✅ | ✅ | ✅ |
| Keystore | Add/Delete/Update Keystores | ✅ | ✅ | ⛔ |
| Keystore | List Keystores | ✅ | ✅ | ✅ |
| Report | List Signing Reports | ✅ | ✅ | ✅ |
:::info Signing and Identities
**Manager** and **Viewer** Signing Identity permissions can use signing identities in [**Build profile configuration**](/build/build-process-management/configurations#environment-variables-configuration).
:::
:::caution Signing Identity Permission
- - **Manager** Signing Identity permission can delete Apple Certificates and Apple Profiles if user has **Manager** Build permission.
:::
### Testing Distribution Permissions
The following table details the roles and restrictions for the [**Testing Distribution**](/testing-distribution) module. Please refer to the related module information and caution notes.
| Testing Distribution | Scopes | Owner | Manager | Operator | Ext. Operator | Viewer |
|----------------------------|----------------------------------------|-------|---------|----------|-------------|--------|
| Distribution Profile | Add/Delete/Update Distribution Profile | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Distribution Profile | Setting Update Distribution Profile | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Distribution Profile | List Distribution Profiles | ✅ | ✅ | ✅ | ✅ | ✅ |
| App Version | Add/Delete/Update App Version | ✅ | ✅ | ✅ | ✅ | ⛔ |
| App Version Actions | Send to Testers | ✅ | ✅ | ✅ | ✅ | ⛔ |
| App Version Actions | Send to Enterprise App Store | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| App Version Actions | Send to Publish | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| App Version Actions | Download Binary | ✅ | ✅ | ✅ | ✅ | ⛔ |
| Settings | Select Authentication Type | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| Settings | View Authentication Settings | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Session Management | Single Active Session | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| Auto Re-sign Configuration | List/Update Auto Re-sign Configuration | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Report | List Reports App Version | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Report | List Reports App Sharing | ✅ | ✅ | ✅ | ⛔ | ✅ |
:::caution Authentication Settings
If the selected Authentication type is Static login, Manager role can change **Username** and **Password**. However, it cannot change the content for other Authentication types such as **LDAP** or **SSO**.
:::
:::caution Share with Tester
Users can share the binary with registered Tester Groups only if they have **Viewer** or higher Testing Group permission. However, users can still share the binary with individual testers by adding them manually.
:::
:::caution Sending Binary
- **Manager** or **Operator** Distribution Profile permission can send to Enterprise App Store if user has Manager or Operator Enterprise App Store permission.
- **Manager** or **Operator** Distribution Profile permission can send to Publish if user has Manager or Operator Publish Android and Manager or Operator iOS permission.
- **Manager** or **Operator** Distribution Profile permission can resign binary if user has Manager or Viewer Signing Identity Management permission.
:::
:::caution Resign Binary
User can resign the binary if this user has **Manager** or **Viewer** Signing Identity permission
:::
### Testing Group Permissions
The following table details the roles and restrictions for the [**Testing Groups**](/testing-distribution/testing-groups). Please refer to the related module information and caution notes.
| Testing Groups | Scopes | Owner | Manager | Viewer |
|----------------|-------------------------------------------|-------|---------|--------|
| Testing Groups | Add/Delete/Update Testing Group | ✅ | ✅ | ⛔ |
| Testing Groups | Add/Delete/Update Testing Group Testers | ✅ | ✅ | ⛔ |
| Testing Groups | List Testing Groups | ✅ | ✅ | ✅ |
| Testing Groups | List Testing Group Testers | ✅ | ✅ | ✅ |
| Testing Groups | Update LDAP Group Members Synchronization | ✅ | ✅ | ⛔ |
| Testing Groups | Sync Testing Group From LDAP | ✅ | ✅ | ⛔ |
| Testing Groups | List LDAP Groups and Members | ✅ | ✅ | ✅ |
### Publish to Stores Module iOS Permissions
The following table details the roles and restrictions for the [**Publish**](/publish-to-stores-module) module for iOS. Please refer to the related module information and caution notes.
| Publish | Scopes | Owner | Manager | Operator | Ext. Operator | Viewer |
|----------------------------|-------------------------------------------|-------|---------|----------|---------------|--------|
| Publish Profiles | Add/Delete/Update Publish Profile | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Profiles | List Publish Profiles | ✅ | ✅ | ✅ | ✅ | ✅ |
| App Version | Add/Delete App Version | ✅ | ✅ | ✅ | ✅ | ⛔ |
| App Version | List App Versions | ✅ | ✅ | ✅ | ✅ | ✅ |
| Profile Settings | View/Update Profile Settings | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | Add/Delete/Update Publish Flow Step | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | Download Publish Flow | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | Upload Publish Flow | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | View Publish Flow | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish | Start/Restart/Stop Flow | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Publish | Start Single Step | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Publish | Update Publish Details | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Publish | View Publish Details | ✅ | ✅ | ✅ | ✅ | ✅ |
| App Store Connect Info | List/Update App Store Connect Information | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| TestFlight Beta Info | List/Update TestFlight Beta Information | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Auto Re-sign Configuration | List/Update Auto Re-sign Configuration | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Check Release Status | Get Relese Status | ✅ | ✅ | ✅ | ✅ | ✅ |
| Metadata | Update Metadata Details | ✅ | ✅ | ✅ | ✅ | ⛔ |
| Metadata | View Metadata Details | ✅ | ✅ | ✅ | ✅ | ✅ |
| Mark as RC | Marking RC a version | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Binary Information | List Binary Information | ✅ | ✅ | ✅ | ✅ | ✅ |
| Binary Comparison | List Binary Comparison | ✅ | ✅ | ✅ | ✅ | ✅ |
| Resing Binary | Resigning Binary | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Release Note | Update Release Note | ✅ | ✅ | ✅ | ✅ | ⛔ |
| History | View/Download History Logs | ✅ | ✅ | ✅ | ✅ | ✅ |
| History | List History | ✅ | ✅ | ✅ | ✅ | ✅ |
| Download Binary | Download Binary | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Cancel Submission | Cancel Submission | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Reject Binary | Reject Binary | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Activity Logs | List Activity Log Details | ✅ | ✅ | ✅ | ⛔ | ✅ |
:::caution Resign Binary
User can resign the binary if this user has **Manager** or **Viewer** Signing Identity permission
:::
### Publish to Stores Module Android Permissions
The following table details the roles and restrictions for the [**Publish**](/publish-to-stores-module) module for Android. Please refer to the related modules information and caution notes.
| Publish | Scopes | Owner | Manager | Operator | Ext. Operator | Viewer |
|---------------------------------|---------------------------------------------|-------|---------|----------|---------------|--------|
| Publish Profiles | Add/Delete/Update Publish Profile | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Profiles | List Publish Profiles | ✅ | ✅ | ✅ | ✅ | ✅ |
| App Version | Add/Delete App Version | ✅ | ✅ | ✅ | ✅ | ⛔ |
| App Version | List App Versions | ✅ | ✅ | ✅ | ✅ | ✅ |
| Profile Settings | View/Update Profile Settings | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | Add/Delete/Update Publish Flow Step | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | Download Publish Flow | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | Upload Publish Flow | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish Flows | View Publish Flow | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Publish | Start/Restart/Stop Flow | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Publish | Start Single Step | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Publish | Update Publish Details | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Publish | View Publish Details | ✅ | ✅ | ✅ | ✅ | ✅ |
| Google Play Console Information | List/Update Google Play Console Information | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Auto Re-sign Configuration | List/Update Auto Re-sign Configuration | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Metadata | Update Metadata Details | ✅ | ✅ | ✅ | ✅ | ⛔ |
| Metadata | View Metadata Details | ✅ | ✅ | ✅ | ✅ | ✅ |
| Mark as RC | Marking RC a version | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Binary Information | List Binary Information | ✅ | ✅ | ✅ | ✅ | ✅ |
| Binary Comparison | List Binary Comparison | ✅ | ✅ | ✅ | ✅ | ✅ |
| Resing Binary | Resigning Binary | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Release Note | Update Release Note | ✅ | ✅ | ✅ | ✅ | ⛔ |
| History | View/Download History Logs | ✅ | ✅ | ✅ | ✅ | ✅ |
| History | List History | ✅ | ✅ | ✅ | ✅ | ✅ |
| Download Binary | Download Binary | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Reject Binary | Reject Binary | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Activity Logs | List Activity Log Details | ✅ | ✅ | ✅ | ⛔ | ✅ |
### Publish Environment Variables
The following table details the roles and restrictions for the [**Publish Variables**](/publish-to-stores-module/publish-variables) module for Android. Please refer to the related modules information and caution notes.
| Publish | Scopes | Owner | Manager | Viewer |
|----------------------|-----------------------------------------------|-------|---------|--------|
| Environment Variable | Add/Delete/Update Environment Variable Groups | ✅ | ✅ | ⛔ |
| Environment Variable | Add/Delete/Update Environment Variable | ✅ | ✅ | ⛔ |
| Environment Variable | List Environment Variable | ✅ | ✅ | ✅ |
| Environment Variable | List Environment Variable Groups | ✅ | ✅ | ✅ |
:::info
Google Play and Huawei AppGallery permissions are managed through a single rule. When this rule is used, it will apply to both platforms.
:::
### Enterprise App Store Permissions
Manage and Upload Apps to Enterprise App Store.
| Ent. App Sub Modules | Scopes | Owner | Manager | Operator | Ext. Operator | Viewer |
|----------------------|----------------------------------------|-------|---------|----------|---------------|--------|
| Store Profile | Add/Delete/Update Profiles | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Store Profile | List Profiles | ✅ | ✅ | ✅ | ✅ | ✅ |
| App Version | Add/Delete/Update App Versions | ✅ | ✅ | ✅ | ✅ | ⛔ |
| App Version | Download App Versions | ✅ | ✅ | ✅ | ✅ | ⛔ |
| App Version | List App Versions | ✅ | ✅ | ✅ | ✅ | ✅ |
| App Version Actions | Publish App Version Live/Beta Channels | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| App Version Actions | Notify Users | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| App Version Actions | Create/Delete In-app Update | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| App Version Actions | Get In-app Update | ✅ | ✅ | ✅ | ✅ | ✅ |
| Settings | Update Store Domain | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| Settings | Update Store Customization | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| Settings | Select Authentication Type | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| Settings | View Authentication Settings | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Settings | View Customization Settings | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Settings | View Store Domain | ✅ | ✅ | ✅ | ⛔ | ✅ |
| Re-sign Binary | Run Manual Re-sign | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| Re-sign Binary | View Auto Re-sign Settings | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Re-sign Binary | Edit Auto Re-sign Settings | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| Session Management | Single Active Session | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| Report | List Reports | ✅ | ✅ | ✅ | ⛔ | ✅ |
:::caution Authentication Settings
If the selected Authentication type is Static login, Manager role can change **Username** and **Password**. However, it cannot change the content for other Authentication types.
:::
### Organization Management Permissions
The user can create an organization or sub-organization within license limits, add and remove members, and manage their permissions.
Also, the user can view self-hosted runners and change configuration.
| Organization Management Sub-modules | Scopes | Owner | Manager | Viewer |
|------------------------------------------------------|-----------------------------------------| ----- | ------- | ------ |
| Organization and Team Management | Create/Delete/Update Organization | ✅ | ✅ | ⛔ |
| Organization and Team Management | Create/Delete/Update Sub-Organization | ✅ | ✅ | ⛔ |
| Organization and Team Management | Add/Delete/Update User | ✅ | ✅ | ⛔ |
| Organization and Team Management | Assign Role for User | ✅ | ✅ | ⛔ |
| Organization and Team Management | List User | ✅ | ✅ | ✅ |
| Testing Portal and Enterprise Portal Authentications | Add/Delete/Update LDAP/SSO Integrations | ✅ | ✅ | ⛔ |
| Testing Portal and Enterprise Portal Authentications | View LDAP/SSO Integrations | ✅ | ✅ | ✅ |
| Appcircle Login | Create/Delete/Update SSO | ✅ | ✅ | ⛔ |
| Appcircle Login | List SSO | ✅ | ✅ | ✅ |
| Appcircle Login | Add/Delete/Update LDAP | ✅ | ✅ | ⛔ |
| Appcircle Login | List LDAP | ✅ | ✅ | ✅ |
| Runner Access Token | List Runner Access Token | ✅ | ⛔ | ⛔ |
| Runner Access Token | Create/Delete Runner Access Token | ✅ | ⛔ | ⛔ |
| Report | View Organziation Report | ✅ | ✅ | ✅ |
| Artifacts | View Retention Period | ✅ | ✅ | ✅ |
| Artifacts | Update Retention Period | ✅ | ✅ | ⛔ |
| Artifacts | View Artifacts Report | ✅ | ✅ | ✅ |
| Domain Verification | View Domain List | ✅ | ✅ | ✅ |
| Domain Verification | View Domain Verification Details | ✅ | ✅ | ⛔ |
| Domain Verification | Add New Domain Verification | ✅ | ✅ | ⛔ |
| Domain Verification | Verify a Domain | ✅ | ✅ | ⛔ |
| Domain Verification | Remove Domain Verification | ✅ | ✅ | ⛔ |
| Export Users | Export User List | ✅ | ✅ | ⛔ |
| API Keys | View API Keys List | ✅ | ✅ | ✅ |
| API Keys | Manage/Delete API Keys | ✅ | ✅ | ⛔ |
:::info Organization Management
Whatever role a user is assigned in the root organization, they will have the same role in the **sub-organizations**. For example, someone who is a Manager in the root organization is automatically assigned as a Manager in the sub-organizations.
If you want to assign a role in a sub-organization, please do so within the respective **sub-organization**.
:::
:::caution Appcircle Login and LDAP/SSO Integrations
LDAP/SSO integrations under Integration are only for setting authentication for logins to the Testing Distribution [**Testing Portal**](/testing-distribution/testing-portal) and [**Enterprise App Store**](/enterprise-app-store).
Please use [**Appcircle Login**](/account/my-organization/security/authentications) for **LDAP** and **SSO** integration when logging into Appcircle.
:::
:::caution Organization Management Role Assignment
The Manager role **cannot** assign itself and another user as **Owner** when assigning roles.
:::
### Billing Management Permissions
Manage the subscription, payment details, and invoices.
The following table details the roles and restrictions for the **Billing** details. Please refer to the related module information and caution notes.
| Billing Sub-modules | Scopes | Owner | Manager |
|---------------------|---------------------------|-------|---------|
| Subscription | List Subscription Details | ✅ | ✅ |
### Integrations and Connection Managements
Connect or disconnect from third-party service providers such as notification tools or store connections.
#### Notification Tools
- [**Slack Notifications**](/account/my-organization/notifications/slack-notifications)
- [**Microsoft Teams Notifications**](/account/my-organization/notifications/teams-notifications)
- [**Email Notifications**](/account/my-organization/notifications/email-connection)
#### Store Connections
- [**App Store Connect API Keys**](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key)
- [**Google Play Developer API Keys**](/account/my-organization/security/credentials/adding-google-play-service-account)
- [**Huawei AppGallery Developer API Keys**](/account/my-organization/security/credentials/adding-huawei-api-key)
- [**Microsoft Intune API Keys**](/account/my-organization/security/credentials/adding-microsoft-intune-api-key)
| Integrations and Connections | Scopes | Owner | Manager | Viewer |
|------------------------------|-------------------------------|-------|---------|--------|
| Credentials | Add/Delete/Update Credentials | ✅ | ✅ | ⛔ |
| Credentials | View Credentials | ✅ | ✅ | ✅ |
| Notifications | Update Notifications | ✅ | ✅ | ⛔ |
| Notifications | View Notifications | ✅ | ✅ | ✅ |
---
## Organization Activity
You can view team management actions such as creating, deleting, and adding members to Organizations or Sub Organizations in the Organization Activity section within the My Organization area.
Here is the full list of actions that can be monitored:
- Organization Create
- Organization Update
- Organization Delete
- Organization Invite Create
- Organization Invite Re-Invite
- Organization Invite Update
- Organization Invite Delete
- Organization Invite Accept
- Organization Member Assign
- Organization Member Remove
- Organization Member Leave
- Organization Member Role Update
- Organization PAT Create
- Organization PAT Revoke
- Organization API Key Create
- Organization API Key Update
- Organization API Key Revoke
- Organization API Key Rotate
- LDAP Group Mapping Create
- LDAP Group Mapping Delete
- LDAP Role Mapping Create
- LDAP Role Mapping Update
- LDAP Role Mapping Delete
:::caution
Only Organization / Sub-Organization Owners and users with Organization Management Role will have access to this area.
Information about other Organizations and their Sub-Organizations will not be accessible without the required level of clearance.
:::
:::info
Organization Owners can also observe the team activity actions of their Sub-Organizations.
:::
You can edit the required date range by clicking the **Filter** button and choosing a date option from various options.
Organization Activity also include filters to help users perform more precise searches. By clicking the **Filter** button and choosing Organization: 'All' option, you can select a specific organization or sub-organization from the list, provided you have access to monitor their organization activity.
Another method to search is by **Actions**. Simply click the **Filter** button and select **Actions**. Then choose a specific action to refine your search.
---
## Team Management
### Team Ownership
The creator of a team starts with the Owner role. The Owner role has full administrative privileges for the team and organization management such as adding/removing members or editing the organization details, while any new members can be assigned specific module-based read/write roles.
:::caution
Each organization must have at least one Owner and each user must be an Owner of at least one organization.
:::
### Managing Team Members
As an Owner, you can invite new members simply by entering their email address under the related field in Team Management and pressing the **Add a New User** button.
The user will be then shown in a **Pending** state until the invitation is accepted. At the same time, you can resend the invitation with the **Resend** option. You can also revoke a pending invite by pressing the delete button at the end of the row.
Once a user accepts an invite, it will be added to the team as a Member with read only access. You can change the role of any user, including yourself, with the **Manage Roles** button next to the user ID. You can also delete a user by pressing the delete button.
Within the opened modal, you can specifically adjust the user's roles across all modules on the right side.
Additionally, the user's assigned organization and sub-organizations will be visible on the left side.
If a sub-organization is created within an organization, everyone in the root organization will be able to see this sub-organization. The roles for these users in the sub-organization will be inherited from the root organization, which is why their permissions will be listed as inherited.
If a user is directly added to the sub-organization, their role will be listed as **Member** instead of **Inherited**.
:::info Sub-organizations
If you want a user to be part of only a specific sub-organization, invite them directly from within that sub-organization.
:::
:::tip
The search bar within the Team Management area allows you to efficiently manage and locate organization members by searching their email addresses to enhance visibility and streamline the management of both current and newly invited members.
:::
## Advanced Role Management
:::info
Team management with fine-grained roles and integration with enterprise identity systems are available in the enterprise plan. Please [contact us](https://appcircle.io/contact) for more information.
:::
Once you click the "Manage Roles" button, you will be presented with a detailed selection of roles for each module.
Here, you can assign the Owner role to a user for full access or you can select specific read or write roles for use cases like developers or testers or billing administrators.
:::info
The "None" is a special type of permission that denotes that a user has no defined role or special permissions. If the user's permission is set to "None" in sub-organizations, the user's permission defaults from the organization.
:::
For more information on the roles and permissions, please refer to the:
Role Management
---
## API Keys
Appcircle provides a secure method to create and manage API keys for accessing its API. These tokens can be generated and scoped to match organizational requirements.
## Creating an API Key
To generate a new API key:
**1.** Click on the **Create a New API Key** button.
**2.** Enter a name for your API key and select an expiry date.
*Note: The expiry date and API key name cannot be modified after creation.*
:::info Expiry Date
Appcircle will set a default expiry date of 6 months from the time you created the API Key. This can be edited to last up to 1 year or lower than 6 months.
:::
**3.** Select the **Organization** and the **Roles** that the API key should have access to.
**4.** Once the key is created, the **API key secret** will be shown **only once**. Copy and store it securely. After this, it will be encrypted and hidden. However, users can create a new key with the **same expiry date** if needed.
:::tip Expiry Notification
Appcircle will send a reminder to the organization owners if any API key is due to expire within a week; for sub-organizations, notifications are sent to their owners, and if no owner exists, they are forwarded to the root organization’s owners.
:::
## Managing API Keys
You can view all your API keys under the API Keys section. The status of each key is indicated as either `Active` or `Expired`.
- **Manage**: Allows updating the **role scope** of the API key.
*Note: Updating roles does not require regenerating the API key or secret.*
- **Delete**: Permanently removes the API key from the system.
- Each API key includes an **auto-generated email** used for audit logging purposes.
:::tip
This feature is also available for **sub-organizations**.
:::
## Using API Keys to Retrieve Access Tokens
The following script can be used to retrieve an access token using an API key name and secret. You also need to include the Organization ID:
```bash
set -e
API_KEY_NAME=apikey1
API_KEY_SECRET='your_secret'
ROOT_ORGANIZATION_ID=your_orgID # root_org
SUB_ORGANIZATION_ID=your_orgID # sub_org
echo "Retrieving access token for API key: $API_KEY_NAME"
response=$(curl --location 'https://auth.appcircle.io/auth/v1/api-key/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'name='"$API_KEY_NAME"'' \
--data-urlencode 'secret='"$API_KEY_SECRET"'' \
--data-urlencode 'organizationId='"$SUB_ORGANIZATION_ID"'')
ACCESS_TOKEN=$(echo "$response" | jq -r '.access_token')
echo "Access token retrieved: $ACCESS_TOKEN"
```
:::tip
An access token for a sub-organization can be created using an API key generated within the root organization, provided that the role settings include access to these sub-organizations.
:::
:::warning API Key Limit
The overall API key limit is typically 10 keys, including those from both the root and sub-organizations.
:::
---
## Testing Portal LDAP Authentication
# Testing Portal LDAP Settings
This document serves as a helpful guide for setting up and managing LDAP (Lightweight Directory Access Protocol) login integration within our organizational system.
Whether you're new to LDAP or looking to streamline your authentication process, this document provides step-by-step instructions to ensure a smooth setup and management experience.
To get started, simply navigate to the **Security** page within our platform and click on the "Add New" button next to LDAP Login under the **Authentications** section.
From there, you'll be guided through the process of creating LDAP configurations, including filling in the necessary details and enabling Two Factor Authentication (2FA) for added security.
:::note
**Cloud** Appcircle supports **only email** 2FA method, while the self-hosted Appcircle installation using **Docker/Podman** supports both **email** and **SMS** 2FA methods.
Similar to the cloud, the self-hosted Appcircle installation using the **Helm chart** also **does not support SMS** 2FA method for now.
:::
:::info
The SMS 2FA method on Docker/Podman-based self-hosted Appcircle requires a custom integration with your SMS service. Please [contact us](https://appcircle.io/contact) for further details.
:::
Once set up, LDAP Login allows you to control access to distributed links and adjust distribution authorization through the Distribution Profiles.
This means you can tailor access permissions according to your organization's specific needs.
If you ever need to remove LDAP Login integration, the document also provides clear instructions for doing so, ensuring that your system remains secure and up-to-date.
To start, go to [My Organization](/account/my-organization) > Security screen and press the **Add New** button next to LDAP Login under the **Authentications** section.
- The **Manage Testing Portal LDAP Login** window will open, click **Create New Authentication** button.
- The **Create New Authentication** window will open, presenting two options:
- **Create New Authentication**
- **Create From Existing Authentication**
You can create new configuration or create from existing configuration. Click on the **Create New Authentication** section to create new configuration.
Please refer the [**Create From Existing LDAP Configuration**](/account/my-organization/security/authentications/distribution-ldap-authentication#create-from-existing-ldap-configuration).
- Fill in the details of your LDAP Configurations.
- The Connect button will switch to the Manage button once a configuration is created.
- To access the LDAP integration settings, click the "Manage" button of the "LDAP Login" after click **Manage Authentication** button. Then click the "Edit" button of the existing LDAP provider.
- The "Order" field in your LDAP configuration determines the priority or sequence in which providers are utilized when conducting a user lookup.
Providers are entities responsible for retrieving user information from LDAP servers.
Specifying the order allows you to prioritize certain providers over others, ensuring efficient user lookup operations.
:::info
Provider A: Order: 1
Provider B: Order: 2
In this example, when conducting a user lookup, Appcircle will first attempt to retrieve information from "Provider A" before falling back to "Provider B".
:::
- The "Connection Pooling" option in your LDAP configuration determines whether Appcircle should utilize connection pooling for accessing the LDAP server.
- To enable Two Factor Authentication, open it by clicking the Manage button and select the verification method.
- To change the distribution authorization, navigate to the Distribution Profiles screen and select your distribution profile. Click **Settings** button and under the Authentication tab you should see LDAP Login. Toggle the **LDAP Login** to 'On'.
- After this step, it will be necessary to log in from the LDAP Login screen to access the distributed links.
- If the Two Factor Authentication is enabled, you will need to verify your account.
- If the login is successful, the Testing Portal screen will appear.
## Create From Existing LDAP Configuration
Appcircle allows you to create a new SSO configuration based on an existing one, ensuring a smooth and efficient setup experience.
- Navigate to the **Organization > Security > Authentications** section on your dashboard.
- Select the **Add New** on the **Testing Portal LDAP Login**.
- Select the **Create New Authentication** and then select the **Create From Existing Configuration**.
Existing LDAP configurations will be listed on the screen. Select one and click **Next** to proceed.
- On the Create LDAP Configuration screen, fill in the **Name** and **Credential** fields (all other values are prefilled). Adjust any fields as needed, then click **Save**.
:::info
The LDAP authentication configuration for Testing Portal can be enabled or disabled by clicking the “Activate LDAP” toggle.
:::
## Deleting LDAP Login
- To delete, go to the [My Organization](/account/my-organization) > Security screen and press the Manage button next to LDAP Login under the Authentications section.
- Click the Remove button.
- Type the alias’s name to confirm deletion and click the Delete button.
---
## Testing Portal SSO Authentication
# Testing Portal Single Sign-On (SSO) Providers Configuration
## 1. Introduction
Single Sign-On (SSO) allows users to log in to Appcircle using their existing credentials from an Identity Provider (IdP). By integrating SSO, organizations can streamline user access management, enhance security, and provide a seamless login experience across multiple platforms.
This document specifically covers the SSO configuration for the Testing Portal (Testing Distribution module). Please note that a separate SSO configurations exists for the [Appcircle Login](/account/my-organization/security/authentications/sso-authentication) and [Enterprise Portal](/account/my-organization/security/authentications/store-sso-authentication). This document does not cover those configurations.
Currently, this configuration supports enabling SSO with only one identity provider at a time. Adding multiple SSO providers is not supported at this moment but may be available in the future.
The SSO setup described in this document integrates the selected identity provider with the Appcircle IAM module, essentially adding the provider as an identity source for Appcircle.
This document provides a comprehensive guide to configuring SSO with various supported identity providers, including Auth0, Microsoft Entra ID (formerly Azure Active Directory), Okta and OneLogin. Whether you choose to implement OpenID Connect or SAML, this guide will walk you through the necessary steps to ensure a successful integration with Appcircle.
### Supported Identity Providers
- Auth0:
- Auth0 (OpenID Connect)
- Auth0 (SAML)
- Microsoft Entra ID (formerly Azure Active Directory):
- Microsoft Entra ID (SAML)
- Okta:
- Okta (OpenID Connect)
- Okta (SAML)
- OneLogin:
- OneLogin (SAML)
Each section will provide detailed instructions for configuring your chosen identity provider, including screenshots and troubleshooting tips to ensure a smooth setup process.
## 2. Prerequisites
Before you begin configuring SSO for Appcircle, ensure that you have the following prerequisites:
- An active account with one of the supported Identity Providers (IdPs).
- Administrative access to both the Identity Provider and Appcircle's platform. For more details, refer to the [Appcircle Role Management Documentation](/account/my-organization/profile-and-team/role-management#organization-management-permissions).
- Access to SAML tracing tools or other relevant debugging resources.
- SSL certificates (if required by your IdP).
These prerequisites will ensure that the SSO configuration process is smooth and any issues that arise can be quickly resolved.
### SSO Terminology
Understanding the following key terms will help you navigate the SSO configuration process more effectively:
- **Identity Provider (IdP):** The service responsible for authenticating the user and issuing identity information. Common examples include Auth0, Microsoft Entra ID, Okta, and OneLogin.
- **Service Provider (SP):** The service (in this case, Appcircle) that relies on the IdP to authenticate users and grant them access. The SP uses the identity information provided by the IdP to manage user sessions and permissions.
- **SAML Assertion:** A secure XML document sent by the IdP to the SP, containing the user's authentication and authorization information. This document is a core component of the SAML protocol, used to establish a user’s identity across different services.
- **OpenID Connect Token:** A token used in the OpenID Connect protocol to convey identity information from the IdP to the SP. This token typically includes user information and is crucial for establishing secure communication between the IdP and SP.
These terms form the foundation of the SSO process, where the IdP authenticates the user and the SP relies on this authentication to grant access. For more in-depth information, refer to the [OpenID Connect specification](https://openid.net/developers/how-connect-works/) or the [SAML specification](https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf).
## 3. General Configuration Steps
The following steps outline the general process for configuring Single Sign-On (SSO) with Appcircle, applicable to all supported identity providers. These steps will guide you through the initial setup within the Appcircle dashboard and the configuration within your chosen identity provider.
Step 1: Enable SSO in Appcircle
Begin by enabling SSO within your Appcircle organization settings. Follow these steps:
1. In the Appcircle dashboard, navigate to the **Organization** section located on the far left sidebar.
2. On the **My Organization** screen, select **Security** from the left-hand menu.
3. On the **Security** screen, locate the **Authentications** section on the far right, find **Testing Portal SSO Login**, and click **Add New**.
4. The **Manage Appcircle SSO Login** window will open, presenting two options:
- **Create New Authentication**
- **Create From Existing Authentication**
You can create new configuration or create from existing configuration. Click on the **Create New Authentication** section to create new configuration.
Please refer the **Step 3: Create From Existing SSO Configuration** section in the 3. General Configuration Steps.
5. The **Create New Authentication** window will open, presenting two options:
- **Set up OpenID Connect Provider**
- **Set up SAML SSO Provider**
Select the option that corresponds to the identity provider you will configure.
6. In the setup window, manually enter a unique **Alias** for your organization.
7. After setting the alias, Appcircle will automatically generate the **Distribute Redirect URL** and **Distribute Logout Redirect URL** specific to your configuration. These URLs must be used in your identity provider's settings to ensure proper redirection after authentication and logout.
The generated **Distribute Redirect URL** and **Distribute Logout Redirect URL** are crucial for your SSO setup, so be sure to copy and save them for use in the following steps.
8. Additionally, enter a **Display Name** for your organization. Ensure that the alias and Display Name you choose are unique and easily identifiable, as they are essential for the SSO authentication process.
Step 2: Select and Configure Your Identity Provider
After enabling SSO and setting your alias, proceed to select and configure your identity provider:
1. Depending on the option you selected in the previous step, you will either be configuring an OpenID Connect or SAML provider.
2. Follow the specific steps for your chosen provider to enter the necessary configuration details, including Client ID, Client Secret, and other required parameters.
3. Use the previously generated **Distribute Redirect URL** and **Distribute Logout Redirect URL** provided by Appcircle when configuring your identity provider settings to ensure proper redirection after authentication and logout.
Only one SSO provider can be configured at a time.
Step 3: Create From Existing SSO Configuration
Appcircle allows you to create a new SSO configuration based on an existing OpenID configuration, ensuring a smooth and efficient setup experience.
:::caution
**Important:** The 'Create From Existing' SSO feature cannot be used for SAML configurations because some identity providers restrict the use of a single SAML Entity ID or a single Logout Redirect URL.
:::
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Add New** on the **Testing Portal SSO Login**
3. Select the **Create New Authentication** and then select the **Create From Existing SSO Configuration**
Existing SSO configurations will be listed in screen. Select one of them and click on **Next**.
4. On the Create SSO Configuration screen, fill in the **Alias** and **Display Name** and **Credential** fields (all other values are prefilled). Customize as needed, then click **Save**.
5. Copy the **Distribute Redirect URL** and **Distribute Logout Redirect URL** and go to your identity provider. Paste it into the appropriate fields.
Step 4: Test and Verify
After completing the SSO configuration, it's essential to test and ensure everything is functioning correctly. The following steps outline the testing process.
Begin by enabling SSO for the Testing Portal. Follow these steps:
1. In the Appcircle dashboard, navigate to the **Testing Distribution** section located on the far left sidebar.
2. On the **Testing Distribution** screen, select **Distribution Profiles** from the left-hand menu.
3. Select the relevant **Distribution Profile** to be distributed via SSO authentication.
4. On the **Distribution Profile** screen, click on the **Settings** button.
5. Navigate to the **Authentication** tab and select **SSO Login** as the authentication type.
6. Follow the [Share Binary](/testing-distribution/create-or-select-a-distribution-profile#share-your-application-with-the-test-groups-manually) documentation to distribute application. You can share application to your email address that exist on Identity Provider for testing purposes.
7. Check your email inbox and goto link in email.
8. Click on **Login With SSO** and authenticate with your identity provider.
## 4. Specific Provider Configuration
4.1 Auth0 (OpenID Connect)
Auth0 is a popular identity provider that supports the OpenID Connect protocol, which can be integrated with Appcircle for secure authentication.
#### Step 1: Create an Application in Auth0
To start, log in to your Auth0 dashboard and create a new application for Appcircle:
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Click **Create Application** and choose a name for your application (e.g., "Appcircle SSO - OpenID").
3. Select **Regular Web Applications** as the application type.
4. Click **Create** button.
5. Once application created, navigate to the **Settings** of application.
6. Take note of the **Client ID** and **Client Secret**, which will be needed later.
#### Step 2: Configure Callback URLs in Auth0
Next, configure the callback URLs in Auth0 to ensure proper redirection to Appcircle after authentication:
1. In the Auth0 dashboard, go to the **Settings** tab of your application.
2. In the **Allowed Callback URLs** field, enter **Distribute Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section).
**Example Callback URL:** `https://auth.appcircle.io/auth/realms/distribute/broker/identity-{your-alias}/endpoint`
3. In the **Allowed Logout URLs** field, enter the **Distribute Logout Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "3. General Configuration Steps" section.
4. Click on the **Save Changes** button.
#### Step 3: Download OpenID Configuration from Auth0
Instead of writing all the settings of OpenID, you can download the settings file from Auth0 and import in Appcircle. Download the OpenID configuration JSON file from Auth0 with following steps.
1. In the Auth0 dashboard, go to the **Settings** tab of your application.
2. Scroll to the bottom of the page and expand the **Advanced Settings** section.
3. Navigate to the **Endpoints** tab.
4. Copy and open **OpenID Configuration** URL in different tab in your browser.
5. Save **OpenID Configuration** as json file.
#### Step 4: Upload OpenID Configuration to Appcircle
Now, upload the OpenID configuration JSON file to Appcircle and complete the configuration:
1. Navigate to the **Set up OpenID Connect Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Choose the **Client secret sent as basic auth** as Client Authentication
3. Enter the **Client ID** and **Client Secret** that you noted earlier from Auth0.
4. Upload the downloaded OpenID configuration JSON file to Appcircle.
5. Click **Save** to finalize the SSO setup.
4.2 Auth0 (SAML)
Auth0 supports the SAML protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create a SAML Application in Auth0
To start, log in to your Auth0 dashboard and create a new SAML application for Appcircle:
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Click **Create Application** and choose a name for your application (e.g., "Appcircle SSO - SAML").
3. Select **Regular Web Applications** as the application type.
4. Click **Create** button.
#### Step 2: Configure SAML Settings in Auth0
Next, configure the SAML settings in Auth0 to ensure it can authenticate and redirect back to Appcircle:
1. Enable the SAML addon for your Auth0 application through the **Addons** tab in your Auth0 application settings.
2. Navigate to the **Settings** tab in the opened dialog. Use the following JSON settings to configure the SAML addon. Enter the **Distribute Logout Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section as the logout callback value.
```
{
"nameIdentifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"nameIdentifierProbes": [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
],
"logout": {
"callback": "https://auth.appcircle.io/auth/realms/distribute/broker/identity-{your-alias}/endpoint",
"slo_enabled": "false"
}
}
```
3. In the **Application Callback URL** field, enter the **Distribute Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section)
**Example Callback URL:** `https://auth.appcircle.io/auth/realms/distribute/broker/identity-{your-alias}/endpoint`
4. Download the **SAML metadata** file from Auth0.
This metadata file will be used in the next step to configure Appcircle.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata file to Appcircle and finalize the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata file to Appcircle.
Check that the Redirect and SSO URLs are imported correctly. Ensure the X509 Certificate is imported correctly as well. If you need to enter multiple certificates, separate them with a comma. Be sure to remove any new lines or file headers, as this edit box only accepts a long base64 encoded string.
3. Complete any additional configuration settings in Appcircle as required.
5. Click **Save** to finalize the SSO setup.
**Important:** Ensure all settings match those provided in the SAML metadata file to avoid issues with authentication.
4.3 Microsoft Entra ID (SAML) (formerly Azure Active Directory)
Microsoft Entra ID supports the SAML protocol, allowing integration with Appcircle for secure authentication. This section will guide you through setting up Microsoft Entra ID as your SAML identity provider for Appcircle.
#### Step 1: Access Microsoft Entra and Create an Enterprise Application
First, log in to your Azure portal as an admin:
1. Log in to Azure portal as an admin and navigate to Azure Services and then click Microsoft Entra ID.
2. In the Azure portal, go to **Enterprise Applications**
3. Click **New Application**.
4. Select **Create your own application**, name it (e.g., "Appcircle SSO - SAML").
5. Choose **Integrate any other application you don't find in the gallery**.
6. Click **Create** to set up the application.
#### Step 2: Assign Users to the Enterprise Application
Once the enterprise application is created, you need to assign users to it:
1. Navigate to the created enterprise application and click **Users and Groups**.
2. Click **Add User/Group**, search for the user you want to assign, select them, and click **Assign**.
#### Step 3: Configure SAML-based Sign-on in Microsoft Entra ID
Next, configure the SAML-based sign-on for the Microsoft Entra ID application:
1. In the application settings, navigate to **Single sign-on** and select **SAML** as the sign-on method.
2. Click **Edit** under the **Basic SAML Configuration** section, and set the following:
- **Identifier (Entity ID)**: Enter `https://auth.appcircle.io/auth/realms/store`.
- **Reply URL (Assertion Consumer Service URL)**: Enter the **Distribute Redirect URL** that created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section.
**Example Distribution Redirect URL:** `https://auth.appcircle.io/auth/realms/distribute/broker/identity-{your-alias}/endpoint`
5. Click **Save** to apply the settings.
#### Step 4: Download and Upload SAML Metadata
Now, download the SAML metadata from Microsoft Entra ID and upload it to Appcircle:
1. In the Azure portal, go to the **SAML Signing Certificate** section and download the **Federation Metadata XML** file.
2. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
3. Upload the downloaded Federation Metadata XML file to Appcircle.
4. Review the settings and click **Save** to finalize the configuration.
4.4 Okta (OpenID Connect)
Okta supports the OpenID Connect protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create an Application in Okta
To start, log in to your Okta dashboard and create a new application for Appcircle:
1. In the Okta dashboard, navigate to **Applications** and click **Create App Integration**.
2. Select **OIDC - OpenID Connect** as the Sign In Method and **Web Application** as the application type.
3. Once created, take note of the **Client ID** and **Client Secret**, which will be needed later.
#### Step 2: Configure Callback URLs in Okta
Next, configure the callback URLs in Okta to ensure proper redirection to Appcircle after authentication:
1. Navigate to the settings of the created application in Okta.
2. Add the **Distribute Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section) to the **Sign-in redirect URLs** field.
**Example Distribution Redirect URL:** `https://auth.appcircle.io/auth/realms/distribute/broker/identity-{your-alias}/endpoint`
3. Add the **Distribute Logout Redirect URL** to the **Sign-out redirect URLs** field.
4. Download the OpenID configuration JSON file from Okta using one of the following URLs:
- `https://{your_okta_domain}/.well-known/openid-configuration`
- `https://{your_okta_domain}/oauth2/default/.well-known/openid-configuration?client_id={your_client_id}`
#### Step 3: Upload OpenID Configuration to Appcircle
Now, upload the OpenID configuration JSON file to Appcircle and complete the configuration:
1. Navigate to the **Set up OpenID Connect Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Enter your **Client ID** and **Client Secret** that you noted earlier from Okta.
3. Upload the downloaded OpenID configuration JSON file to Appcircle.
4. Check that the **Authorization** and **Token URLs** are correctly imported.
5. Click **Save** to finalize the SSO setup.
4.5 Okta (SAML)
Okta supports the SAML protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create a SAML Application in Okta
To start, log in to your Okta dashboard and create a new application for Appcircle:
. In the Okta dashboard, navigate to **Applications** and click **Create App Integration**.
2. Select **SAML 2.0** as the Sign In Method.
3. Pick a name and optional logo for the app, then click **Next**.
#### Step 2: Configure SAML Settings in Okta
Next, configure the SAML settings in Okta to ensure proper authentication and redirection to Appcircle:
1. In the **Single sign-on URL** field, enter the **Distribute Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section).
**Example Distribute Redirect URL:** `https://auth.appcircle.io/auth/realms/distribute/broker/identity-{your-alias}/endpoint`
2. For the **Audience URI (SP Entity ID)** field, copy and paste **Service Provider Entity ID** from Appcircle.
**Example URL:** `https://auth.appcircle.io/auth/realms/store`
3. Select **EmailAddress** for the Name ID format.
4. Download **Signing Certificate** from Appcircle.
5. Click on **Show Advanced Settings**
6. Upload downloaded certificate to Signature Certificate field.
7. Enable **Allow application to initiate Single Logout**.
8. Copy and paste **Logout Redirect URL** to **Single Logout URL** field. Copy and paste **Service Provider Entity ID** to **SP Issuer**.
9. Instead of manually configuring all SAML settings in Appcircle, you can download the SAML metadata XML file from Okta:
Click the **Copy** button next to the Metadata URL and open it in another tab to download the XML file.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata XML file to Appcircle to complete the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata XML file to Appcircle.
3. Ensure that the Redirect and SSO URLs are imported correctly. You can check if the X509 Certificate is imported correctly as well. If you want to enter multiple certificates you can separate them by using a comma between them. Please be aware that you need to remove any new lines or file headers from this edit box. This edit box only accepts a long base64 encoded string.
4. Enable **Want AuthnRequests Signed** in Appcircle.
5. Click **Save** to finalize the SSO setup.
## 5. Troubleshooting
This section provides a list of common issues that users might encounter during the SSO setup and how to resolve them.
5.1 Common Issues and Resolutions
- **Misconfigured SAML Assertions:** Ensure that the SAML assertions are correctly configured with the appropriate attributes and claims. Incorrect settings here can lead to failed logins.
- **Incorrect Redirect URIs:** Verify that the Redirect URIs configured in your identity provider match the ones set in Appcircle. Mismatches can cause authentication failures.
- **Token Mismatches:** If you encounter token mismatches, ensure that the correct Client ID, Client Secret, and endpoints are configured in both Appcircle and the identity provider.
- **Metadata Import Issues:** If the metadata import fails, manually check the SAML metadata for formatting errors or missing elements that may cause issues during import.
- **SSO Alias Not Recognized:** Make sure the SSO alias entered matches the one configured in Appcircle. Any discrepancies could prevent successful authentication.
- **Account Linking Problems:** If account linking fails, verify that the user’s email address in the identity provider matches the one in Appcircle.
5.2 Troubleshooting for Auth0 (OpenID Connect)
- **Callback URL Mismatch:** Ensure that the callback URL in Auth0 matches the one configured in Appcircle. This mismatch often causes authentication failures.
- **Invalid or Missing Redirect URIs:** Ensure that the redirect URIs in both Auth0 and Appcircle match exactly. Any mismatch, even in trailing slashes, can cause authentication to fail.
- **Invalid Client ID/Secret:** Verify that the Client ID and Secret are correctly entered in Appcircle’s SSO settings. Regenerate these values in Auth0 if needed.
- **Logs Don't Show Successful Login Event:** If the user successfully logs in with the identity provider, but the Appcircle logs do not show a successful login event, check the SAML Authentication Assertion returned by the IdP or analyze the HTTP trace for any discrepancies in Appcircle.
- **Misconfigured Scopes:** Ensure that the scopes requested in Appcircle match those defined in Auth0. Mismatches can lead to login failures.
- **Error Response Handling:** If Auth0 returns an error response, Appcircle may display a generic "500 Error: Oops, An Error Occurred. Invalid username or password." This issue often arises when users input incorrect details, such as entering an organization they are not a member of.
5.3 Troubleshooting for Auth0 (SAML)
- **Attribute Mapping Problems:** Verify that the attributes sent by Auth0 match those expected by Appcircle.
- **Token Mismatch:** Ensure the tokens issued by Auth0 match the expected format in Appcircle.
- **Incorrect Assertion Consumer Service (ACS) URL:** Verify that the ACS URL in Auth0 matches the one configured in Appcircle’s SSO settings.
- **SAML Assertion Issues:** Use tools like a SAML debugger to check the contents of the SAML assertion for correct format and expected values before entering them into Appcircle.
- **IdP Login Page Doesn't Display:** If the IdP login page fails to display, ensure the correct SSO URL is being used in Appcircle and that the binding method (HTTP-POST or HTTP-Redirect) is properly configured.
- **Certificate Issues:** Ensure the SAML certificate in Auth0 is valid and correctly configured. Invalid certificates can prevent proper authentication in Appcircle.
- **Error Response Handling:** If Auth0 returns an error response, Appcircle may display a generic "500 Error: Oops, An Error Occurred. Invalid username or password." This issue often arises when users input incorrect details, such as entering an organization they are not a member of.
5.4 Troubleshooting for Microsoft Entra ID (SAML)
- **Incorrect SAML Response:** Check that all required claims and attributes are configured correctly in Microsoft Entra ID.
- **Certificate Expiration:** Ensure that the SAML signing certificate used by Microsoft Entra ID is valid and not expired.
- **Misconfigured Claims or Attributes:** Ensure that the claims and attributes being sent from Microsoft Entra ID are correctly mapped and expected by Appcircle. Mismatches can lead to failed logins or incomplete user profiles.
- **Redirect Loop:** This often occurs due to incorrect reply URLs or session issues. Verify the reply URL in Microsoft Entra ID matches the one in Appcircle and that session cookies are correctly managed.
- **Invalid Certificate or Encryption Issues:** Ensure that the certificates used for signing and encryption are valid and correctly configured in both Microsoft Entra ID and Appcircle’s SSO settings. Expired certificates are a common cause of failures in SAML setups.
- **Unassigned Users:** Ensure that users are assigned to the enterprise application in Microsoft Entra ID. Unassigned users cannot authenticate through Appcircle.
5.5 Troubleshooting for Okta (OpenID Connect)
- **Invalid Client ID/Secret:** Verify the Client ID and Secret in Appcircle match those configured in Okta.
- **Incorrect Scopes Configuration:** Ensure that the correct scopes, like `openid`, `profile`, and `email`, are requested by the client application and match those configured in Appcircle. Okta will reject requests with unsupported or misconfigured scopes.
- **Token Validation Issues:** Use Okta’s introspection endpoint for remote validation of access tokens to ensure they have not been revoked or expired in Appcircle’s SSO integration.
- **Key Rotation Problems:** Regularly update the public keys used by Okta in Appcircle’s SSO settings to ensure continuous validation of tokens, as Okta automatically rotates these keys multiple times a year.
- **Invalid Redirect URI:** Ensure that the redirect URI in Okta matches the one specified in Appcircle. Mismatches can cause authentication failures.
- **403 Forbidden Errors:** Ensure the user has the necessary permissions and that the application is set up correctly in Okta to prevent access issues in Appcircle.
5.6 Troubleshooting for Okta (SAML)
- **Certificate Errors:** Verify that the SAML certificate used in Okta is valid and has not expired.
- **Incorrect ACS URL:** Ensure the Assertion Consumer Service (ACS) URL in Okta matches the one configured in Appcircle.
- **Signing and Encryption Issues:** Verify that both signing and encryption certificates are correctly configured and up to date in both Okta and Appcircle. Expired or incorrectly installed certificates are a common cause of SAML failures.
- **Misconfigured SAML Responses:** Use Okta’s SAML troubleshooting tools to validate the SAML response, ensuring that all required fields are present and correctly formatted before integrating with Appcircle.
- **Invalid SSO URL or Mismatched Entity IDs:** Confirm that the SSO URL and Entity ID configured in Okta are correctly set up in Appcircle’s SSO settings to prevent login issues or errors in the authentication process.
- **Clock Skew:** Ensure the system clocks of both Okta and Appcircle are synchronized to avoid timing issues in the authentication process.
5.7 Troubleshooting for OneLogin (SAML)
- **SSO Errors Due to Incorrect URLs:** Ensure that the SAML Assertion Consumer Service (ACS) URL and other SSO URLs in OneLogin match those in Appcircle.
- **SAML Metadata Misconfiguration:** Ensure that the SAML metadata imported into OneLogin is current and accurately reflects Appcircle’s SSO requirements. Update the metadata periodically to avoid integration issues.
- **Incomplete Attribute Mapping:** Verify that all necessary user attributes are mapped from OneLogin to Appcircle to avoid incomplete user sessions or missing information.
- **Account Linking Failures:** Ensure that user email addresses match between OneLogin and Appcircle. Discrepancies in user data can prevent successful account linking.
- **Certificate Expiration:** Verify that the SAML signing certificate in OneLogin is valid and not expired to ensure seamless authentication with Appcircle.
---
## Authenticaiton
# Authentication
The **Authentication** section enables you to manage access control and secure your Appcircle environment. Set up authentication methods such as LDAP, SSO or two-factor authentication, to ensure that only authorized users can access your projects and integrations, protecting your data and workflows.
:::info
Appcircle consists of three isolated modules for authentication management:
- Appcircle Dashboard
- Enterprise Portal
- Testing Portal
Each module manages authentication independently. Authentication configurations (such as SSO or LDAP) must be set up separately for each module.
Users and their access permissions are also managed independently. A user who has access to one module does not automatically gain access to the others unless they are configured there as well.
:::
Current headlines and the actions you can complete are listed below:
- [**Appcircle SSO Authentication**](/account/my-organization/security/authentications/sso-authentication)
- [**Enterprise Portal SSO Authentication**](/account/my-organization/security/authentications/store-sso-authentication)
- [**Testing Portal SSO Authentication**](/account/my-organization/security/authentications/distribution-sso-authentication)
- [**Enterprise Portal LDAP Authentication**](/account/my-organization/security/authentications/store-ldap-authentication)
- [**Testing Portal LDAP Authentication**](/account/my-organization/security/authentications/distribution-ldap-authentication)
In order to see the details, check the submenu of this documentation page.
---
## Appcircle SSO Authentication
# Appcircle Login Single Sign-On (SSO) Providers Configuration
## 1. Introduction
Single Sign-On (SSO) allows users to log in to Appcircle using their existing credentials from an Identity Provider (IdP). By integrating SSO, organizations can streamline user access management, enhance security, and provide a seamless login experience across multiple platforms.
This document specifically covers the SSO configuration for the Appcircle Login. Please note that a separate SSO configuration exists for the [Testing Portal (Testing Distribution module)](/account/my-organization/security/authentications/distribution-sso-authentication) and [Enterprise Portal (Enterprise App Store module)](/account/my-organization/security/authentications/store-sso-authentication). This document does not cover those configurations.
Currently, this configuration supports enabling SSO with only one identity provider at a time. Adding multiple SSO providers is not supported at this moment but may be available in the future.
The SSO setup described in this document integrates the selected identity provider with the Appcircle IAM module, essentially adding the provider as an identity source for Appcircle.
This document provides a comprehensive guide to configuring SSO with various supported identity providers, including Auth0, Microsoft Entra ID (formerly Azure Active Directory), Okta and OneLogin. Whether you choose to implement OpenID Connect or SAML, this guide will walk you through the necessary steps to ensure a successful integration with Appcircle.
:::caution
When Single Sign-On (SSO) is enabled for an organization, all users must log in through SSO to access it. Attempting to sign in with traditional email and password will switch the user to a separate organization with a starter license. If needed, SSO can be disabled, allowing users to access the organization again using their email and password credentials.
:::
### Supported Identity Providers
- Auth0:
- Auth0 (OpenID Connect)
- Auth0 (SAML)
- Microsoft Entra ID (formerly Azure Active Directory):
- Microsoft Entra ID (SAML)
- Okta:
- Okta (OpenID Connect)
- Okta (SAML)
- OneLogin:
- OneLogin (SAML)
Each section will provide detailed instructions for configuring your chosen identity provider, including screenshots and troubleshooting tips to ensure a smooth setup process.
## 2. Prerequisites
Before you begin configuring SSO for Appcircle, ensure that you have the following prerequisites:
- An active account with one of the supported Identity Providers (IdPs).
- Administrative access to both the Identity Provider and Appcircle's platform. For more details, refer to the [Appcircle Role Management Documentation](/account/my-organization/profile-and-team/role-management#organization-management-permissions).
- Access to SAML tracing tools or other relevant debugging resources.
- SSL certificates (if required by your IdP).
These prerequisites will ensure that the SSO configuration process is smooth and any issues that arise can be quickly resolved.
### SSO Terminology
Understanding the following key terms will help you navigate the SSO configuration process more effectively:
- **Identity Provider (IdP):** The service responsible for authenticating the user and issuing identity information. Common examples include Auth0, Microsoft Entra ID, Okta and OneLogin.
- **Service Provider (SP):** The service (in this case, Appcircle) that relies on the IdP to authenticate users and grant them access. The SP uses the identity information provided by the IdP to manage user sessions and permissions.
- **SAML Assertion:** A secure XML document sent by the IdP to the SP, containing the user's authentication and authorization information. This document is a core component of the SAML protocol, used to establish a user’s identity across different services.
- **OpenID Connect Token:** A token used in the OpenID Connect protocol to convey identity information from the IdP to the SP. This token typically includes user information and is crucial for establishing secure communication between the IdP and SP.
These terms form the foundation of the SSO process, where the IdP authenticates the user and the SP relies on this authentication to grant access. For more in-depth information, refer to the [OpenID Connect specification](https://openid.net/developers/how-connect-works/) or the [SAML specification](https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf).
## 3. General Configuration Steps
The following steps outline the general process for configuring Single Sign-On (SSO) with Appcircle, applicable to all supported identity providers. These steps will guide you through the initial setup within the Appcircle dashboard and the configuration within your chosen identity provider.
Step 1: Enable SSO in Appcircle
Begin by enabling SSO within your Appcircle organization settings. Follow these steps:
1. In the Appcircle dashboard, navigate to the **Organization** section located on the far left sidebar.
2. On the **My Organization** screen, select **Security** from the left-hand menu.
3. On the **Security** screen, locate the **Authentications** section on the far right, find **Appcircle SSO Login**, and click **Add New**.
4. The **Manage Appcircle SSO Login** window will open, presenting two options:
- **Create New Authentication**
- **Create From Existing Authentication**
You can create new configuration or create from existing configuration. Click on the **Create New Authentication** section to create new configuration.
Please refer the **Step 3: Create From Existing SSO Configuration** section in the 3. General Configuration Steps.
5. The **Create New Authentication** window will open, presenting two options:
- **Set up OpenID Connect Provider**
- **Set up SAML SSO Provider**
Select the option that corresponds to the identity provider you will configure.
6. In the setup window, manually enter a unique **Alias** for your organization. This alias is used to create a custom Redirect URI that will be required for configuring your SSO provider.
7. After setting the alias, Appcircle will automatically generate a **Redirect URL** and a **Logout Redirect URL** specific to your configuration. These URLs must be used in your identity provider's settings to ensure proper redirection after authentication and logout.
Ensure that the alias is unique and easily identifiable, as they are essential for the SSO authentication process. The generated **Redirect URL** and **Logout Redirect URL** are crucial for your SSO setup, so be sure to copy and save them for use in the following steps.
8. Additionally, enter a **Display Name** for your organization.
Step 2: Select and Configure Your Identity Provider
After enabling SSO and setting your alias, proceed to select and configure your identity provider:
1. Depending on the option you selected in the previous step, you will either be configuring an OpenID Connect or SAML provider.
2. Follow the specific steps for your chosen provider to enter the necessary configuration details, including Client ID, Client Secret, and other required parameters.
3. Use the previously generated Redirect URI provided by Appcircle when configuring your identity provider settings to ensure proper redirection after authentication.
Only one SSO provider can be configured at a time.
Step 3: Create From Existing SSO Configuration
Appcircle allows you to create a new SSO configuration based on an existing OpenID Connect configuration, ensuring a smooth and efficient setup experience.
:::caution
**Important:** The 'Create From Existing' SSO feature cannot be used for SAML configurations because some identity providers restrict the use of a single SAML Entity ID or a single Logout Redirect URL.
:::
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Add New** on the **Appcircle SSO Login**.
3. Select the **Create New Authentication** and then select the **Create From Existing SSO Configuration**.
Existing SSO configurations will be listed in screen. Select one of them and click on **Next**.
- On the Create SSO Configuration screen, fill in the **Alias** and **Display Name** and **Credential** fields (all other values are prefilled). Customize as needed, then click **Save**.
- Copy the Redirect URL and go to your identity provider. Paste it into the appropriate field.
Step 4: SSO Login Direct Link
Appcircle also supports direct SSO login links. Use the following URL format to log in directly using your SSO alias:
- For Cloud-Hosted Appcircle:
`https://my.appcircle.io/sso/{SSO_ALIAS}`
- For Self-Hosted Appcircle:
`https://my.appcircle.{your-domain}/sso/{SSO_ALIAS}`
Replace `{SSO_ALIAS}` with the alias you configured, and if you are using a self-hosted solution, replace `{your-domain}` with your actual domain.
Step 5: Test and Verify SSO Configuration
After completing the SSO configuration, it's essential to test and ensure everything is functioning correctly. The following steps outline the testing process.
Step 5.1: Initiate SSO Login
1. Open an incognito window in your browser to avoid any cached sessions interfering with the test.
2. Navigate to the Appcircle login page and click the **Continue with SSO** button.
3. Enter the SSO Alias you configured earlier and proceed. The alias is used to identify your organization's specific SSO setup.
Step 5.2: Account Linking
1. After entering the alias, if a user with the same email already exists, you should see a confirmation screen prompting you to link your account with the SSO provider.
2. Confirm the account linking by clicking the appropriate button on the confirmation screen.
3. You will receive an email to verify the account linking. Open the email and click the verification link.
Step 5.3: Verification via Email
Once you confirm the account linking, an email will be sent to your registered email address. You must verify your account using the link in this email to complete the process.
1. Open the verification email and click the provided link to confirm your account.
2. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
:::info
Manual email verification can be bypassed by enabling domain verification. For more information, refer to the [Domain Verification Documentation](/account/my-organization/security/domain-verification).
:::
Step 5.4: Final Login
After verifying your account via email, your SSO setup is complete. From now on, you can log in with your SSO alias or using the direct SSO login link.
:::info
After enabling SSO, the traditional login method using your previous credentials will no longer be available for your organization. Ensure that you can log in successfully using SSO before logging out of any sessions.
:::
## 4. Specific Provider Configuration
This section provides detailed instructions for configuring Single Sign-On (SSO) with specific identity providers supported by Appcircle. Each provider may have unique requirements, so it's important to follow the steps closely.
4.1 Auth0 (OpenID Connect)
Auth0 is a popular identity provider that supports the OpenID Connect protocol, which can be integrated with Appcircle for secure authentication.
#### Step 1: Create an Application in Auth0
To start, log in to your Auth0 dashboard and create a new application for Appcircle:
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Click **Create Application** and choose a name for your application (e.g., "Appcircle SSO - OpenID").
3. Select **Regular Web Applications** as the application type.
4. Click **Create** button.
5. Once application created, navigate to the **Settings** of application.
6. Take note of the **Client ID** and **Client Secret**, which will be needed later.
#### Step 2: Configure Callback URLs in Auth0
Next, configure the callback URLs in Auth0 to ensure proper redirection to Appcircle after authentication:
1. In the Auth0 dashboard, go to the **Settings** tab of your application.
2. In the **Allowed Callback URLs** field, enter the Redirect URL that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "3. General Configuration Steps" section.
**Example Callback URL:** `https://auth.appcircle.io/auth/realms/appcircle/broker/identity-{your-alias}/endpoint`
3. In the **Allowed Logout URLs** field, enter the **Logout Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "3. General Configuration Steps" section.
4. Click on the **Save Changes** button.
#### Step 3: Download OpenID Configuration from Auth0
Instead of writing all the settings of OpenID, you can download the settings file from Auth0 and import in Appcircle. Download the OpenID configuration JSON file from Auth0 with following steps.
1. In the Auth0 dashboard, go to the **Settings** tab of your application.
2. Scroll to the bottom of the page and expand the **Advanced Settings** section.
3. Navigate to the **Endpoints** tab.
4. Copy and open **OpenID Configuration** URL in different tab in your browser.
5. Save **OpenID Configuration** as json file.
#### Step 4: Upload OpenID Configuration to Appcircle
Now, upload the OpenID configuration JSON file to Appcircle and complete the configuration:
1. Navigate to the **Set up OpenID Connect Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps".
2. Choose the **Client secret sent as basic auth** as Client Authentication.
3. Enter the **Client ID** and **Client Secret** that you noted earlier from Auth0.
4. Upload the downloaded OpenID configuration JSON file to Appcircle.
5. Click **Save** to finalize the SSO setup.
#### Step 5: Test the Integration
After configuring the settings, it’s crucial to test the OpenID Connect SSO integration:
:::caution
**Important:** When connecting your Identity Provider, use an incognito window to test the SSO integration. Only log off once you are sure you can log in with your SSO credentials. If the connection fails, review your settings before logging out.
:::
1. Open a incognito window in your browser and initiate a new login session.
2. On the login screen, click the **Login with SSO** button to start the SSO login process
3. Enter your SSO alias when prompted and click **Continue**.
4. You will be redirected to the Auth0 login screen. Enter your Auth0 credentials.
5. After successful authentication, you will be redirected back to Appcircle.
6. If a user with your email already exists, you will be prompted to confirm account linking. Confirm account linking and verify it via the email sent to your registered email address.
7. Once you confirm the account linking, an email will be sent to your registered email address.
8. Open the verification email and click the provided link to confirm your account.
9. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
4.2 Auth0 (SAML)
Auth0 supports the SAML protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create a SAML Application in Auth0
To start, log in to your Auth0 dashboard and create a new SAML application for Appcircle:
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Click **Create Application** and choose a name for your application (e.g., "Appcircle SSO - SAML").
3. Select **Regular Web Applications** as the application type.
4. Click **Create** button.
#### Step 2: Configure SAML Settings in Auth0
Next, configure the SAML settings in Auth0 to ensure it can authenticate and redirect back to Appcircle:
1. Enable the SAML addon for your Auth0 application through the **Addons** tab in your Auth0 application settings.
2. Navigate to the **Settings** tab in the opened dialog. Use the following JSON settings to configure the SAML addon. Enter the **Logout Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section as the logout callback value.
```
{
"nameIdentifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"nameIdentifierProbes": [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
],
"logout": {
"callback": "https://auth.appcircle.io/auth/realms/appcircle/broker/identity-{your-alias}/endpoint",
"slo_enabled": "false"
}
}
```
3. In the **Application Callback URL** field, enter the **Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section.
**Example Callback URL:** `https://auth.appcircle.io/auth/realms/appcircle/broker/identity-{your-alias}/endpoint`
4. Download the **SAML metadata** file from Auth0.
This metadata file will be used in the next step to configure Appcircle.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata file to Appcircle and finalize the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata file to Appcircle.
Check that the Redirect and SSO URLs are imported correctly. Ensure the X509 Certificate is imported correctly as well. If you need to enter multiple certificates, separate them with a comma. Be sure to remove any new lines or file headers, as this edit box only accepts a long base64 encoded string.
3. Complete any additional configuration settings in Appcircle as required.
5. Click **Save** to finalize the SSO setup.
**Important:** Ensure all settings match those provided in the SAML metadata file to avoid issues with authentication.
#### Step 4: Test the Integration
After configuring the settings, it’s crucial to test the OpenID Connect SSO integration:
:::caution
**Important:** When connecting your Identity Provider, use an incognito window to test the SSO integration. Only log off once you are sure you can log in with your SSO credentials. If the connection fails, review your settings before logging out.
:::
1. Open a incognito window in your browser and initiate a new login session.
2. On the login screen, click the **Login with SSO** button to start the SSO login process
3. Enter your SSO alias when prompted and click **Continue**.
4. You will be redirected to the Auth0 login screen. Enter your Auth0 credentials.
5. After successful authentication, you will be redirected back to Appcircle.
6. If a user with your email already exists, you will be prompted to confirm account linking. Confirm account linking and verify it via the email sent to your registered email address.
7. Once you confirm the account linking, an email will be sent to your registered email address.
8. Open the verification email and click the provided link to confirm your account.
9. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
If the test is successful, your integration is complete, and you can start using Auth0 (SAML) as your identity provider for Appcircle.
4.3 Microsoft Entra ID (SAML) (formerly Azure Active Directory)
Microsoft Entra ID supports the SAML protocol, allowing integration with Appcircle for secure authentication. This section will guide you through setting up Microsoft Entra ID as your SAML identity provider for Appcircle.
#### Step 1: Access Microsoft Entra and Create an Enterprise Application
First, log in to your Azure portal as an admin:
1. Log in to Azure portal as an admin and navigate to Azure Services and then click Microsoft Entra ID.
2. In the Azure portal, go to **Enterprise Applications**
3. Click **New Application**.
4. Select **Create your own application**, name it (e.g., "Appcircle SSO - SAML").
5. Choose **Integrate any other application you don't find in the gallery**.
6. Click **Create** to set up the application.
#### Step 2: Assign Users to the Enterprise Application
Once the enterprise application is created, you need to assign users to it:
1. Navigate to the created enterprise application and click **Users and Groups**.
2. Click **Add User/Group**, search for the user you want to assign, select them, and click **Assign**.
#### Step 3: Configure SAML-based Sign-on in Microsoft Entra ID
Next, configure the SAML-based sign-on for the Microsoft Entra ID application:
1. In the application settings, navigate to **Single sign-on** and select **SAML** as the sign-on method.
2. Click **Edit** under the **Basic SAML Configuration** section, and set the following:
- **Identifier (Entity ID)**: Enter `https://auth.appcircle.io/auth/realms/appcircle`.
- **Reply URL (Assertion Consumer Service URL)**: Enter the Redirect URL created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section (e.g., `https://auth.appcircle.io/auth/realms/appcircle/broker/identity-{your-alias}/endpoint`).
5. Click **Save** to apply the settings.
#### Step 4: Download and Upload SAML Metadata
Now, download the SAML metadata from Microsoft Entra ID and upload it to Appcircle:
1. In the Azure portal, go to the **SAML Signing Certificate** section and download the **Federation Metadata XML** file.
2. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
3. Upload the downloaded Federation Metadata XML file to Appcircle.
4. Review the settings and click **Save** to finalize the configuration.
#### Step 4: Test the Integration
After configuring the settings, it’s crucial to test the OpenID Connect SSO integration:
:::caution
**Important:** When connecting your Identity Provider, use an incognito window to test the SSO integration. Only log off once you are sure you can log in with your SSO credentials. If the connection fails, review your settings before logging out.
:::
1. Open a incognito window in your browser and initiate a new login session.
2. On the login screen, click the **Login with SSO** button to start the SSO login process
3. Enter your SSO alias when prompted and click **Continue**.
4. You will be redirected to the Auth0 login screen. Enter your Auth0 credentials.
5. After successful authentication, you will be redirected back to Appcircle.
6. If a user with your email already exists, you will be prompted to confirm account linking. Confirm account linking and verify it via the email sent to your registered email address.
7. Once you confirm the account linking, an email will be sent to your registered email address.
8. Open the verification email and click the provided link to confirm your account.
9. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
If the test is successful, your integration is complete, and you can start using Microsoft Entra ID (SAML) as your identity provider for Appcircle.
4.4 Okta (OpenID Connect)
Okta supports the OpenID Connect protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create an Application in Okta
To start, log in to your Okta dashboard and create a new application for Appcircle:
1. In the Okta dashboard, navigate to **Applications** and click **Create App Integration**.
2. Select **OIDC - OpenID Connect** as the Sign In Method and **Web Application** as the application type.
3. Once created, take note of the **Client ID** and **Client Secret**, which will be needed later.
#### Step 2: Configure Callback URLs in Okta
Next, configure the callback URLs in Okta to ensure proper redirection to Appcircle after authentication:
1. Navigate to the settings of the created application in Okta.
2. Add the Appcircle Redirect URL to the **Sign-in redirect URLs** field.
**Example Redirect URL:** `https://auth.appcircle.io/auth/realms/appcircle/broker/identity-{your-alias}/endpoint`
3. Add the **Logout Redirect URL** to the **Sign-out redirect URLs** field.
4. Download the OpenID configuration JSON file from Okta using one of the following URLs:
- `https://{your_okta_domain}/.well-known/openid-configuration`
- `https://{your_okta_domain}/oauth2/default/.well-known/openid-configuration?client_id={your_client_id}`
#### Step 3: Upload OpenID Configuration to Appcircle
Now, upload the OpenID configuration JSON file to Appcircle and complete the configuration:
1. Navigate to the **Set up OpenID Connect Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Choose the **Client secret sent as basic auth** as Client Authentication.
3. Enter the **Client ID** and **Client Secret** that you noted earlier from Okta.
4. Upload the downloaded OpenID configuration JSON file to Appcircle.
5. Check that the **Authorization** and **Token URLs** are correctly imported.
6. Click **Save** to finalize the SSO setup.
#### Step 4: Test the Integration
After configuring the settings, it’s crucial to test the OpenID Connect SSO integration:
:::caution
**Important:** When connecting your Identity Provider, use an incognito window to test the SSO integration. Only log off once you are sure you can log in with your SSO credentials. If the connection fails, review your settings before logging out.
:::
1. Open a incognito window in your browser and initiate a new login session.
2. On the login screen, click the **Login with SSO** button to start the SSO login process
3. Enter your SSO alias when prompted and click **Continue**.
4. You will be redirected to the Auth0 login screen. Enter your Auth0 credentials.
5. After successful authentication, you will be redirected back to Appcircle.
6. If a user with your email already exists, you will be prompted to confirm account linking. Confirm account linking and verify it via the email sent to your registered email address.
7. Once you confirm the account linking, an email will be sent to your registered email address.
8. Open the verification email and click the provided link to confirm your account.
9. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
If the test is successful, your integration is complete, and you can start using Okta (SAML) as your identity provider for Appcircle.
4.5 Okta (SAML)
Okta supports the SAML protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create a SAML Application in Okta
To start, log in to your Okta dashboard and create a new application for Appcircle:
1. In the Okta dashboard, navigate to **Applications** and click **Create App Integration**.
2. Select **SAML 2.0** as the Sign In Method.
3. Pick a name and optional logo for the app, then click **Next**.
#### Step 2: Configure SAML Settings in Okta
Next, configure the SAML settings in Okta to ensure proper authentication and redirection to Appcircle:
1. In the **Single sign-on URL** field, add the Appcircle Redirect URL.
**Example URL:** `https://auth.appcircle.io/auth/realms/appcircle/broker/identity-mySAML/endpoint`
3. For the **Audience URI (SP Entity ID)** field, copy and paste **Service Provider Entity ID** from Appcircle.
**Example URL:** `https://auth.appcircle.io/auth/realms/appcircle`
4. Select **EmailAddress** for the Name ID format.
5. Download **Signing Certificate** from Appcircle.
6. Click on **Show Advanced Settings**.
7. Upload downloaded certificate to Signature Certificate field.
8. Enable **Allow application to initiate Single Logout**.
9. Copy and paste **Logout Redirect URL** to **Single Logout URL** field. Copy and paste **Service Provider Entity ID** to **SP Issuer**.
8. Instead of manually configuring all SAML settings in Appcircle, you can download the SAML metadata XML file from Okta:
Click the **Copy** button next to the Metadata URL and open it in another tab to download the XML file.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata XML file to Appcircle to complete the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata XML file to Appcircle.
3. Ensure that the Redirect and SSO URLs are imported correctly. You can check if the X509 Certificate is imported correctly as well. If you want to enter multiple certificates you can separate them by using a comma between them. Please be aware that you need to remove any new lines or file headers from this edit box. This edit box only accepts a long base64 encoded string.
4. Enable **Want AuthnRequests Signed** in Appcircle.
5. Click **Save** to finalize the SSO setup.
#### Step 4: Test the Integration
After configuring the settings, it’s crucial to test the OpenID Connect SSO integration:
:::caution
**Important:** When connecting your Identity Provider, use an incognito window to test the SSO integration. Only log off once you are sure you can log in with your SSO credentials. If the connection fails, review your settings before logging out.
:::
1. Open a incognito window in your browser and initiate a new login session.
2. On the login screen, click the **Login with SSO** button to start the SSO login process
3. Enter your SSO alias when prompted and click **Continue**.
4. You will be redirected to the Auth0 login screen. Enter your Auth0 credentials.
5. After successful authentication, you will be redirected back to Appcircle.
6. If a user with your email already exists, you will be prompted to confirm account linking. Confirm account linking and verify it via the email sent to your registered email address.
7. Once you confirm the account linking, an email will be sent to your registered email address.
8. Open the verification email and click the provided link to confirm your account.
9. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
If the test is successful, your integration is complete, and you can start using Okta (SAML) as your identity provider for Appcircle.
#### Starting the SAML SSO Flow from Okta (Optional)
If you want to initiate the SAML SSO flow from the Okta side, you need to complete an additional configuration step:
1. In Okta, open your application settings by navigating to:
**Applications > Your Application > Sign On tab > Edit Settings.**
2. Set the **Default Relay State** to:
```
rd=https://my.appcircle.io/sso/your_sso_alias
```
Replace `your_sso_alias` with your actual SSO alias.
3. Go to the ***Okta End-User Dashboard**.
4. Click the application you just configured.
By doing this, you will be able to start the SSO login process directly from the Okta dashboard.
4.6 OneLogin (SAML)
OneLogin supports the SAML protocol, allowing integration with Appcircle for secure authentication. The Appcircle application is pre-configured in OneLogin, which simplifies the setup process by providing predefined settings.
#### Step 1: Create a SAML Application in OneLogin
To start, log in to your OneLogin dashboard and create a new SAML application for Appcircle:
1. In the OneLogin dashboard, navigate to **Applications** and click **Add App**.
2. In the search box, type **Appcircle** and select it from the search results. The application is pre-configured with the necessary settings, including URLs and certificates.
3. Pick a name and optional logo for the app, then click **Save**.
#### Step 2: Configure SAML Settings in OneLogin
Now configure the SAML settings in OneLogin:
1. Write the alias that you have created earlier and click **Save**.
2. Instead of writing all the settings of SAML, you can download the settings file from OneLogin and upload it. Click the **More Actions** button and click **SAML Metadata**.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata XML file to Appcircle to complete the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata XML file to Appcircle.
3. Ensure that the Redirect and SSO URLs are imported correctly. You can check if the X509 Certificate is imported correctly as well. If you want to enter multiple certificates you can separate them by using a comma between them. Please be aware that you need to remove any new lines or file headers from this edit box. This edit box only accepts a long base64 encoded string.
4. Click **Save** to finalize the SSO setup.
#### Step 4: Test the Integration
After configuring the settings, it’s crucial to test the OpenID Connect SSO integration:
:::caution
**Important:** When connecting your Identity Provider, use an incognito window to test the SSO integration. Only log off once you are sure you can log in with your SSO credentials. If the connection fails, review your settings before logging out.
:::
1. Open a incognito window in your browser and initiate a new login session.
2. On the login screen, click the **Login with SSO** button to start the SSO login process
3. Enter your SSO alias when prompted and click **Continue**.
4. You will be redirected to the Auth0 login screen. Enter your Auth0 credentials.
5. After successful authentication, you will be redirected back to Appcircle.
6. If a user with your email already exists, you will be prompted to confirm account linking. Confirm account linking and verify it via the email sent to your registered email address.
7. Once you confirm the account linking, an email will be sent to your registered email address.
8. Open the verification email and click the provided link to confirm your account.
9. After verification, you will be redirected back to the Appcircle dashboard, fully authenticated via SSO.
If the test is successful, your integration is complete, and you can start using OneLogin (SAML) as your identity provider for Appcircle.
## 5. Troubleshooting
This section provides a list of common issues that users might encounter during the SSO setup and how to resolve them.
6.1 Common Issues and Resolutions
- **Misconfigured SAML Assertions:** Ensure that the SAML assertions are correctly configured with the appropriate attributes and claims. Incorrect settings here can lead to failed logins.
- **Incorrect Redirect URIs:** Verify that the Redirect URIs configured in your identity provider match the ones set in Appcircle. Mismatches can cause authentication failures.
- **Token Mismatches:** If you encounter token mismatches, ensure that the correct Client ID, Client Secret, and endpoints are configured in both Appcircle and the identity provider.
- **Metadata Import Issues:** If the metadata import fails, manually check the SAML metadata for formatting errors or missing elements that may cause issues during import.
- **SSO Alias Not Recognized:** Make sure the SSO alias entered matches the one configured in Appcircle. Any discrepancies could prevent successful authentication.
- **Account Linking Problems:** If account linking fails, verify that the user’s email address in the identity provider matches the one in Appcircle.
6.2 Troubleshooting for Auth0 (OpenID Connect)
- **Callback URL Mismatch:** Ensure that the callback URL in Auth0 matches the one configured in Appcircle. This mismatch often causes authentication failures.
- **Invalid or Missing Redirect URIs:** Ensure that the redirect URIs in both Auth0 and Appcircle match exactly. Any mismatch, even in trailing slashes, can cause authentication to fail.
- **Invalid Client ID/Secret:** Verify that the Client ID and Secret are correctly entered in Appcircle’s SSO settings. Regenerate these values in Auth0 if needed.
- **Logs Don't Show Successful Login Event:** If the user successfully logs in with the identity provider, but the Appcircle logs do not show a successful login event, check the SAML Authentication Assertion returned by the IdP or analyze the HTTP trace for any discrepancies in Appcircle.
- **Misconfigured Scopes:** Ensure that the scopes requested in Appcircle match those defined in Auth0. Mismatches can lead to login failures.
- **Error Response Handling:** If Auth0 returns an error response, Appcircle may display a generic "500 Error: Oops, An Error Occurred. Invalid username or password." This issue often arises when users input incorrect details, such as entering an organization they are not a member of.
6.3 Troubleshooting for Auth0 (SAML)
- **Attribute Mapping Problems:** Verify that the attributes sent by Auth0 match those expected by Appcircle.
- **Token Mismatch:** Ensure the tokens issued by Auth0 match the expected format in Appcircle.
- **Incorrect Assertion Consumer Service (ACS) URL:** Verify that the ACS URL in Auth0 matches the one configured in Appcircle’s SSO settings.
- **SAML Assertion Issues:** Use tools like a SAML debugger to check the contents of the SAML assertion for correct format and expected values before entering them into Appcircle.
- **IdP Login Page Doesn't Display:** If the IdP login page fails to display, ensure the correct SSO URL is being used in Appcircle and that the binding method (HTTP-POST or HTTP-Redirect) is properly configured.
- **Certificate Issues:** Ensure the SAML certificate in Auth0 is valid and correctly configured. Invalid certificates can prevent proper authentication in Appcircle.
- **Error Response Handling:** If Auth0 returns an error response, Appcircle may display a generic "500 Error: Oops, An Error Occurred. Invalid username or password." This issue often arises when users input incorrect details, such as entering an organization they are not a member of.
6.4 Troubleshooting for Microsoft Entra ID (SAML)
- **Incorrect SAML Response:** Check that all required claims and attributes are configured correctly in Microsoft Entra ID.
- **Certificate Expiration:** Ensure that the SAML signing certificate used by Microsoft Entra ID is valid and not expired.
- **Misconfigured Claims or Attributes:** Ensure that the claims and attributes being sent from Microsoft Entra ID are correctly mapped and expected by Appcircle. Mismatches can lead to failed logins or incomplete user profiles.
- **Redirect Loop:** This often occurs due to incorrect reply URLs or session issues. Verify the reply URL in Microsoft Entra ID matches the one in Appcircle and that session cookies are correctly managed.
- **Invalid Certificate or Encryption Issues:** Ensure that the certificates used for signing and encryption are valid and correctly configured in both Microsoft Entra ID and Appcircle’s SSO settings. Expired certificates are a common cause of failures in SAML setups.
- **Unassigned Users:** Ensure that users are assigned to the enterprise application in Microsoft Entra ID. Unassigned users cannot authenticate through Appcircle.
6.5 Troubleshooting for Okta (OpenID Connect)
- **Invalid Client ID/Secret:** Verify the Client ID and Secret in Appcircle match those configured in Okta.
- **Incorrect Scopes Configuration:** Ensure that the correct scopes, like `openid`, `profile`, and `email`, are requested by the client application and match those configured in Appcircle. Okta will reject requests with unsupported or misconfigured scopes.
- **Token Validation Issues:** Use Okta’s introspection endpoint for remote validation of access tokens to ensure they have not been revoked or expired in Appcircle’s SSO integration.
- **Key Rotation Problems:** Regularly update the public keys used by Okta in Appcircle’s SSO settings to ensure continuous validation of tokens, as Okta automatically rotates these keys multiple times a year.
- **Invalid Redirect URI:** Ensure that the redirect URI in Okta matches the one specified in Appcircle. Mismatches can cause authentication failures.
- **403 Forbidden Errors:** Ensure the user has the necessary permissions and that the application is set up correctly in Okta to prevent access issues in Appcircle.
6.6 Troubleshooting for Okta (SAML)
- **Certificate Errors:** Verify that the SAML certificate used in Okta is valid and has not expired.
- **Incorrect ACS URL:** Ensure the Assertion Consumer Service (ACS) URL in Okta matches the one configured in Appcircle.
- **Signing and Encryption Issues:** Verify that both signing and encryption certificates are correctly configured and up to date in both Okta and Appcircle. Expired or incorrectly installed certificates are a common cause of SAML failures.
- **Misconfigured SAML Responses:** Use Okta’s SAML troubleshooting tools to validate the SAML response, ensuring that all required fields are present and correctly formatted before integrating with Appcircle.
- **Invalid SSO URL or Mismatched Entity IDs:** Confirm that the SSO URL and Entity ID configured in Okta are correctly set up in Appcircle’s SSO settings to prevent login issues or errors in the authentication process.
- **Clock Skew:** Ensure the system clocks of both Okta and Appcircle are synchronized to avoid timing issues in the authentication process.
6.7 Troubleshooting for OneLogin (SAML)
- **SSO Errors Due to Incorrect URLs:** Ensure that the SAML Assertion Consumer Service (ACS) URL and other SSO URLs in OneLogin match those in Appcircle.
- **SAML Metadata Misconfiguration:** Ensure that the SAML metadata imported into OneLogin is current and accurately reflects Appcircle’s SSO requirements. Update the metadata periodically to avoid integration issues.
- **Incomplete Attribute Mapping:** Verify that all necessary user attributes are mapped from OneLogin to Appcircle to avoid incomplete user sessions or missing information.
- **Account Linking Failures:** Ensure that user email addresses match between OneLogin and Appcircle. Discrepancies in user data can prevent successful account linking.
- **Certificate Expiration:** Verify that the SAML signing certificate in OneLogin is valid and not expired to ensure seamless authentication with Appcircle.
---
## Enterprise Portal LDAP Authentication
# Enterprise Portal LDAP Settings
This document serves as a helpful guide for setting up and managing LDAP (Lightweight Directory Access Protocol) login integration within our organizational system.
Whether you're new to LDAP or looking to streamline your authentication process, this document provides step-by-step instructions to ensure a smooth setup and management experience.
To get started, simply navigate to the **Security** page within our platform and click on the "Add New" button next to LDAP Login under the **Authentications** section.
From there, you'll be guided through the process of creating LDAP configurations, including filling in the necessary details and enabling Two Factor Authentication (2FA) for added security.
:::note
**Cloud** Appcircle supports **only email** 2FA method, while the self-hosted Appcircle installation using **Docker/Podman** supports both **email** and **SMS** 2FA methods.
Similar to the cloud, the self-hosted Appcircle installation using the **Helm chart** also **does not support SMS** 2FA method for now.
:::
:::info
The SMS 2FA method on Docker/Podman-based self-hosted Appcircle requires a custom integration with your SMS service. Please [contact us](https://appcircle.io/contact) for further details.
:::
Once set up, LDAP Login allows you to control access to distributed links and adjust distribution authorization through the Distribution Profiles.
This means you can tailor access permissions according to your organization's specific needs.
If you ever need to remove LDAP Login integration, the document also provides clear instructions for doing so, ensuring that your system remains secure and up-to-date.
To start, go to [My Organization](/account/my-organization) > Security screen and press the **Add New** button next to LDAP Login under the **Authentications** section.
- The **Manage Testing Portal LDAP Login** window will open, click **Create New Authentication** button.
- The **Create New Authentication** window will open, presenting two options:
- **Create New Authentication**
- **Create From Existing Authentication**
You can create a new configuration or create one from an existing configuration. Click on the **Create New Authentication** section to create new configuration.
Please refer the [**Create From Existing LDAP Configuration**](/account/my-organization/security/authentications/store-ldap-authentication#create-from-existing-ldap-configuration).
- Fill in the details of your LDAP Configurations
- You can see that the Connect button has changed to the Manage button.
- To access the LDAP integration settings, click the "Manage" button of the "LDAP Login". Then, click **Manage Authentication** button and select the "Edit" button of the existing LDAP provider.
- The "Order" field in your LDAP configuration determines the priority or sequence in which providers are utilized when conducting a user lookup.
Providers are entities responsible for retrieving user information from LDAP servers.
Specifying the order allows you to prioritize certain providers over others, ensuring efficient user lookup operations.
:::info
Provider A: Order: 1
Provider B: Order: 2
In this example, when conducting a user lookup, Appcircle will first attempt to retrieve information from "Provider A" before falling back to "Provider B".
:::
- The "Connection Pooling" option in your LDAP configuration determines whether Appcircle should utilize connection pooling for accessing the LDAP server.
- To enable Two Factor Authentication, open it by clicking the Manage button and select the verification method.
- To change the distribution authorization go to Distribution Profiles screen and press the your distribution profile click **Settings** button and under the Authentication tab you should see LDAP Login. Convert **LDAP Login** to on.
- After this step, it will be necessary to log in from the LDAP Login screen to access the distributed links.
- You must verify according to the method you have chosen.
- If the login is successful, a screen similar to the one below will appear.
## Create From Existing LDAP Configuration
Appcircle allows you to create a new SSO configuration based on an existing one, ensuring a smooth and efficient setup experience.
- Navigate to the **Organization > Security > Authentications** section on your dashboard.
- Select the **Add New** on the **Enterprise Portal LDAP Login**.
- Select the **Create New Authentication** and then select the **Create From Existing Configuration**.
Existing LDAP configurations will be listed on the screen. Select one, and click on **Next** to proceed.
- On the Create LDAP Configuration screen, fill in the **Name** and **Credential** fields (all other values are prefilled). Customize as needed, then click **Save**.
:::info
The LDAP authentication configuration for Enterprise Portal can be enabled or disabled by clicking the “Activate LDAP” toggle.
:::
## Deleting LDAP Login
- To delete, go to the [My Organization](/account/my-organization) > Security screen and press the Manage button next to LDAP Login under the Authentications section.
- Click the Remove button.
- Type the alias’s name to confirm deletion and click the Delete button.
---
## Enterprise Portal SSO Authentication
# Enterprise Portal Single Sign-On (SSO) Providers Configuration
## 1. Introduction
Single Sign-On (SSO) allows users to log in to Appcircle using their existing credentials from an Identity Provider (IdP). By integrating SSO, organizations can streamline user access management, enhance security, and provide a seamless login experience across multiple platforms.
This document specifically covers the SSO configuration for the Enterprise Portal (Enterprise App Store module). Please note that a separate SSO configurations exists for the [Appcircle Login](/account/my-organization/security/authentications/sso-authentication) and [Testing Portal](/account/my-organization/security/authentications/distribution-sso-authentication). This document does not cover those configurations.
Currently, this configuration supports enabling SSO with only one identity provider at a time. Adding multiple SSO providers is not supported at this moment but may be available in the future.
The SSO setup described in this document integrates the selected identity provider with the Appcircle IAM module, essentially adding the provider as an identity source for Appcircle.
This document provides a comprehensive guide to configuring SSO with various supported identity providers, including Auth0, Microsoft Entra ID (formerly Azure Active Directory), Okta and OneLogin. Whether you choose to implement OpenID Connect or SAML, this guide will walk you through the necessary steps to ensure a successful integration with Appcircle.
### Supported Identity Providers
- Auth0:
- Auth0 (OpenID Connect)
- Auth0 (SAML)
- Microsoft Entra ID (formerly Azure Active Directory):
- Microsoft Entra ID (SAML)
- Okta:
- Okta (OpenID Connect)
- Okta (SAML)
- OneLogin:
- OneLogin (SAML)
Each section will provide detailed instructions for configuring your chosen identity provider, including screenshots and troubleshooting tips to ensure a smooth setup process.
## 2. Prerequisites
Before you begin configuring SSO for Appcircle, ensure that you have the following prerequisites:
- An active account with one of the supported Identity Providers (IdPs).
- Administrative access to both the Identity Provider and Appcircle's platform. For more details, refer to the [Appcircle Role Management Documentation](/account/my-organization/profile-and-team/role-management#organization-management-permissions).
- Access to SAML tracing tools or other relevant debugging resources.
- SSL certificates (if required by your IdP).
These prerequisites will ensure that the SSO configuration process is smooth and any issues that arise can be quickly resolved.
### SSO Terminology
Understanding the following key terms will help you navigate the SSO configuration process more effectively:
- **Identity Provider (IdP):** The service responsible for authenticating the user and issuing identity information. Common examples include Auth0, Microsoft Entra ID, Okta and OneLogin.
- **Service Provider (SP):** The service (in this case, Appcircle) that relies on the IdP to authenticate users and grant them access. The SP uses the identity information provided by the IdP to manage user sessions and permissions.
- **SAML Assertion:** A secure XML document sent by the IdP to the SP, containing the user's authentication and authorization information. This document is a core component of the SAML protocol, used to establish a user’s identity across different services.
- **OpenID Connect Token:** A token used in the OpenID Connect protocol to convey identity information from the IdP to the SP. This token typically includes user information and is crucial for establishing secure communication between the IdP and SP.
These terms form the foundation of the SSO process, where the IdP authenticates the user and the SP relies on this authentication to grant access. For more in-depth information, refer to the [OpenID Connect specification](https://openid.net/developers/how-connect-works/) or the [SAML specification](https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf).
## 3. General Configuration Steps
The following steps outline the general process for configuring Single Sign-On (SSO) with Appcircle, applicable to all supported identity providers. These steps will guide you through the initial setup within the Appcircle dashboard and the configuration within your chosen identity provider.
Step 1: Enable SSO in Appcircle
Begin by enabling SSO within your Appcircle organization settings. Follow these steps:
1. In the Appcircle dashboard, navigate to the **Organization** section located on the far left sidebar.
2. On the **My Organization** screen, select **Security** from the left-hand menu.
3. On the **Security** screen, locate the **Authentications** section on the far right, find **Enterprise Portal SSO Login**, and click **Add New**.
4. The **Manage Appcircle SSO Login** window will open, presenting two options:
- **Create New Authentication**
- **Create From Existing Authentication**
You can create new configuration or create from existing configuration. Click on the **Create New Authentication** section to create new configuration.
Please refer the **Step 3: Create From Existing SSO Configuration** section in the 3. General Configuration Steps.
5. The **Create New Authentication** window will open, presenting two options:
- **Set up OpenID Connect Provider**
- **Set up SAML SSO Provider**
Select the option that corresponds to the identity provider you will configure.
6. In the setup window, manually enter a unique **Alias** for your organization.
7. Additionally, enter a **Display Name** for your organization.
8. After setting the alias and Display Name, Appcircle will automatically generate the **Store Redirect URL** and **Store Logout Redirect URL** specific to your configuration. **Store Redirect URL** must be used in your identity provider's settings to ensure proper redirection after authentication and logout.
Ensure that the alias and Display Name you choose are unique and easily identifiable, as they are essential for the SSO authentication process. The generated **Store Redirect URL** and **Store Logout Redirect URL** are crucial for your SSO setup, so be sure to copy and save it for use in the following steps.
Step 2: Select and Configure Your Identity Provider
After enabling SSO and setting your alias, proceed to select and configure your identity provider:
1. Depending on the option you selected in the previous step, you will either be configuring an OpenID Connect or SAML provider.
2. Follow the specific steps for your chosen provider to enter the necessary configuration details, including Client ID, Client Secret, and other required parameters.
3. Use the previously generated **Store Redirect URL** and **Store Logout Redirect URL** provided by Appcircle when configuring your identity provider settings to ensure proper redirection after authentication and logout.
Only one SSO provider can be configured at a time.
Step 3: Create From Existing SSO Configuration
Appcircle allows you to create a new SSO configuration based on an existing OpenID Connect configuration, ensuring a smooth and efficient setup experience.
:::caution
**Important:** The 'Create From Existing' SSO feature cannot be used for SAML configurations because some identity providers restrict the use of a single SAML Entity ID or a single Logout Redirect URL.
:::
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Add New** on the **Store Portal SSO Login**
3. Select the **Create New Authentication** and then select the **Create From Existing SSO Configuration**
Existing SSO configurations will be listed in screen. Select one of them and click on **Next**.
4. On the Create SSO Configuration screen, fill in the **Alias** and **Display Name** and **Credential** fields (all other values are prefilled). Customize as needed, then click **Save**.
5. Copy the **Store Redirect URL** and **Store Logout Redirect URL** and go to your identity provider. Paste it into the appropriate fields.
Step 4: Test and Verify
After completing the SSO configuration, it's essential to test and ensure everything is functioning correctly. The following steps outline the testing process.
Begin by enabling SSO for the Enterprise App Store. Follow these steps:
1. In the Appcircle dashboard, navigate to the **Enterprise App Store** section located on the far left sidebar.
2. On the **Enterprise App Store** screen, select **Settings** from the left-hand menu.
3. Click on the **Activate** button next to SSO Login.
4. Follow [Enterprise App Store Documentation](/enterprise-app-store/enterprise-app-store-profile) to test the integration.
## 4. Specific Provider Configuration
4.1 Auth0 (OpenID Connect)
Auth0 is a popular identity provider that supports the OpenID Connect protocol, which can be integrated with Appcircle for secure authentication.
#### Step 1: Create an Application in Auth0
To start, log in to your Auth0 dashboard and create a new application for Appcircle:
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Click **Create Application** and choose a name for your application (e.g., "Appcircle SSO - OpenID").
3. Select **Regular Web Applications** as the application type.
4. Click **Create** button.
5. Once application created, navigate to the **Settings** of application.
6. Take note of the **Client ID** and **Client Secret**, which will be needed later.
#### Step 2: Configure Callback URLs in Auth0
Next, configure the callback URLs in Auth0 to ensure proper redirection to Appcircle after authentication:
1. In the Auth0 dashboard, go to the **Settings** tab of your application.
2. In the **Allowed Callback URLs** field, enter the **Store Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section)
**Example Callback URL:** `https://auth.appcircle.io/auth/realms/store/broker/identity-{your-alias}/endpoint`
3. In the **Allowed Logout URLs** field, enter the **Store Logout Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "3. General Configuration Steps" section.
4. Click on the **Save Changes** button.
#### Step 3: Download OpenID Configuration from Auth0
Instead of writing all the settings of OpenID, you can download the settings file from Auth0 and import in Appcircle. Download the OpenID configuration JSON file from Auth0 with following steps.
1. In the Auth0 dashboard, go to the **Settings** tab of your application.
2. Scroll to the bottom of the page and expand the **Advanced Settings** section.
3. Navigate to the **Endpoints** tab.
4. Copy and open **OpenID Configuration** URL in different tab in your browser.
5. Save **OpenID Configuration** as `.JSON` file.
#### Step 4: Upload OpenID Configuration to Appcircle
Now, upload the OpenID configuration JSON file to Appcircle and complete the configuration:
1. Navigate to the **Set up OpenID Connect Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Choose the **Client secret sent as basic auth** as Client Authentication
3. Enter the **Client ID** and **Client Secret** that you noted earlier from Auth0.
4. Upload the downloaded OpenID configuration JSON file to Appcircle.
5. Click **Save** to finalize the SSO setup.
4.2 Auth0 (SAML)
Auth0 supports the SAML protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create a SAML Application in Auth0
To start, log in to your Auth0 dashboard and create a new SAML application for Appcircle:
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Click **Create Application** and choose a name for your application (e.g., "Appcircle SSO - SAML").
3. Select **Regular Web Applications** as the application type.
4. Click **Create** button.
#### Step 2: Configure SAML Settings in Auth0
Next, configure the SAML settings in Auth0 to ensure it can authenticate and redirect back to Appcircle:
1. Enable the SAML addon for your Auth0 application through the **Addons** tab in your Auth0 application settings.
2. Navigate to the **Settings** tab in the opened dialog. Use the following JSON settings to configure the SAML addon. Enter the **Store Logout Redirect URL** that was created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section as the logout callback value.
```
{
"nameIdentifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"nameIdentifierProbes": [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
],
"logout": {
"callback": "https://auth.appcircle.io/auth/realms/store/broker/identity-{your-alias}/endpoint",
"slo_enabled": "false"
}
}
```
3. In the **Application Callback URL** field, enter the **Store Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section), combined by a comma.
**Example Callback URL:** `https://auth.appcircle.io/auth/realms/store/broker/identity-{your-alias}/endpoint`
4. Download the **SAML metadata** file from Auth0.
This metadata file will be used in the next step to configure Appcircle.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata file to Appcircle and finalize the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata file to Appcircle.
Check that the Redirect and SSO URLs are imported correctly. Ensure the X509 Certificate is imported correctly as well. If you need to enter multiple certificates, separate them with a comma. Be sure to remove any new lines or file headers, as this edit box only accepts a long base64 encoded string.
3. Complete any additional configuration settings in Appcircle as required.
5. Click **Save** to finalize the SSO setup.
**Important:** Ensure all settings match those provided in the SAML metadata file to avoid issues with authentication.
4.3 Microsoft Entra ID (SAML) (formerly Azure Active Directory)
Microsoft Entra ID supports the SAML protocol, allowing integration with Appcircle for secure authentication. This section will guide you through setting up Microsoft Entra ID as your SAML identity provider for Appcircle.
#### Step 1: Access Microsoft Entra and Create an Enterprise Application
First, log in to your Azure portal as an admin:
1. Log in to Azure portal as an admin and navigate to Azure Services and then click Microsoft Entra ID.
2. In the Azure portal, go to **Enterprise Applications**
3. Click **New Application**.
4. Select **Create your own application**, name it (e.g., "Appcircle SSO - SAML").
5. Choose **Integrate any other application you don't find in the gallery**.
6. Click **Create** to set up the application.
#### Step 2: Assign Users to the Enterprise Application
Once the enterprise application is created, you need to assign users to it:
1. Navigate to the created enterprise application and click **Users and Groups**.
2. Click **Add User/Group**, search for the user you want to assign, select them, and click **Assign**.
#### Step 3: Configure SAML-based Sign-on in Microsoft Entra ID
Next, configure the SAML-based sign-on for the Microsoft Entra ID application:
1. In the application settings, navigate to **Single sign-on** and select **SAML** as the sign-on method.
2. Click **Edit** under the **Basic SAML Configuration** section, and set the following:
- **Identifier (Entity ID)**: Enter `https://auth.appcircle.io/auth/realms/store`.
- **Reply URL (Assertion Consumer Service URL)**: Enter the **Store Redirect URL** that created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section.
**Example Store Redirect URL:** `https://auth.appcircle.io/auth/realms/store/broker/identity-{your-alias}/endpoint`
5. Click **Save** to apply the settings.
#### Step 4: Download and Upload SAML Metadata
Now, download the SAML metadata from Microsoft Entra ID and upload it to Appcircle:
1. In the Azure portal, go to the **SAML Signing Certificate** section and download the **Federation Metadata XML** file.
2. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
3. Upload the downloaded Federation Metadata XML file to Appcircle.
4. Review the settings and click **Save** to finalize the configuration.
4.4 Okta (OpenID Connect)
Okta supports the OpenID Connect protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create an Application in Okta
To start, log in to your Okta dashboard and create a new application for Appcircle:
1. In the Okta dashboard, navigate to **Applications** and click **Create App Integration**.
2. Select **OIDC - OpenID Connect** as the Sign In Method and **Web Application** as the application type.
3. Once created, take note of the **Client ID** and **Client Secret**, which will be needed later.
#### Step 2: Configure Callback URLs in Okta
Next, configure the callback URLs in Okta to ensure proper redirection to Appcircle after authentication:
1. Navigate to the settings of the created application in Okta.
2. Add the **Store Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section) to the **Sign-in redirect URLs** field.
**Example Store Redirect URL:** `https://auth.appcircle.io/auth/realms/store/broker/identity-{your-alias}/endpoint`
3. Add the **Store Logout Redirect URL** to the **Sign-out redirect URLs** field.
5. Download the OpenID configuration JSON file from Okta using one of the following URLs:
- `https://{your_okta_domain}/.well-known/openid-configuration`
- `https://{your_okta_domain}/oauth2/default/.well-known/openid-configuration?client_id={your_client_id}`
#### Step 3: Upload OpenID Configuration to Appcircle
Now, upload the OpenID configuration JSON file to Appcircle and complete the configuration:
1. Navigate to the **Set up OpenID Connect Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Enter your **Client ID** and **Client Secret** that you noted earlier from Okta.
3. Upload the downloaded OpenID configuration JSON file to Appcircle.
4. Check that the **Authorization** and **Token URLs** are correctly imported.
5. Click **Save** to finalize the SSO setup.
4.5 Okta (SAML)
Okta supports the SAML protocol, allowing integration with Appcircle for secure authentication.
#### Step 1: Create a SAML Application in Okta
To start, log in to your Okta dashboard and create a new application for Appcircle:
. In the Okta dashboard, navigate to **Applications** and click **Create App Integration**.
2. Select **SAML 2.0** as the Sign In Method.
3. Pick a name and optional logo for the app, then click **Next**.
#### Step 2: Configure SAML Settings in Okta
Next, configure the SAML settings in Okta to ensure proper authentication and redirection to Appcircle:
1. In the **Single sign-on URL** field, enter the **Store Redirect URL** (created using the alias in "Step 1: Enable SSO in Appcircle" from the "General Configuration Steps" section).
**Example Store Redirect URL:** `https://auth.appcircle.io/auth/realms/store/broker/identity-{your-alias}/endpoint`
2. For the **Audience URI (SP Entity ID)** field, copy and paste **Service Provider Entity ID** from Appcircle.
**Example URL:** `https://auth.appcircle.io/auth/realms/store`
3. Select **EmailAddress** for the Name ID format.
4. Download **Signing Certificate** from Appcircle.
5. Click on **Show Advanced Settings**.
6. Upload downloaded certificate to Signature Certificate field.
7. Enable **Allow application to initiate Single Logout**.
8. Copy and paste **Logout Redirect URL** to **Single Logout URL** field. Copy and paste **Service Provider Entity ID** to **SP Issuer**.
9. Instead of manually configuring all SAML settings in Appcircle, you can download the SAML metadata XML file from Okta:
Click the **Copy** button next to the Metadata URL and open it in another tab to download the XML file.
#### Step 3: Upload SAML Metadata to Appcircle
Now, upload the SAML metadata XML file to Appcircle to complete the configuration:
1. Navigate to the **Set up SAML SSO Provider** screen in Appcircle, which you accessed during the SSO setup in the "General Configuration Steps."
2. Upload the downloaded SAML metadata XML file to Appcircle.
3. Ensure that the Redirect and SSO URLs are imported correctly. You can check if the X509 Certificate is imported correctly as well. If you want to enter multiple certificates you can separate them by using a comma between them. Please be aware that you need to remove any new lines or file headers from this edit box. This edit box only accepts a long base64 encoded string.
4. Enable **Want AuthnRequests Signed** in Appcircle.
5. Click **Save** to finalize the SSO setup.
## 5. Troubleshooting
This section provides a list of common issues that users might encounter during the SSO setup and how to resolve them.
5.1 Common Issues and Resolutions
- **Misconfigured SAML Assertions:** Ensure that the SAML assertions are correctly configured with the appropriate attributes and claims. Incorrect settings here can lead to failed logins.
- **Incorrect Redirect URIs:** Verify that the Redirect URIs configured in your identity provider match the ones set in Appcircle. Mismatches can cause authentication failures.
- **Token Mismatches:** If you encounter token mismatches, ensure that the correct Client ID, Client Secret, and endpoints are configured in both Appcircle and the identity provider.
- **Metadata Import Issues:** If the metadata import fails, manually check the SAML metadata for formatting errors or missing elements that may cause issues during import.
- **SSO Alias Not Recognized:** Make sure the SSO alias entered matches the one configured in Appcircle. Any discrepancies could prevent successful authentication.
- **Account Linking Problems:** If account linking fails, verify that the user’s email address in the identity provider matches the one in Appcircle.
5.2 Troubleshooting for Auth0 (OpenID Connect)
- **Callback URL Mismatch:** Ensure that the callback URL in Auth0 matches the one configured in Appcircle. This mismatch often causes authentication failures.
- **Invalid or Missing Redirect URIs:** Ensure that the redirect URIs in both Auth0 and Appcircle match exactly. Any mismatch, even in trailing slashes, can cause authentication to fail.
- **Invalid Client ID/Secret:** Verify that the Client ID and Secret are correctly entered in Appcircle’s SSO settings. Regenerate these values in Auth0 if needed.
- **Logs Don't Show Successful Login Event:** If the user successfully logs in with the identity provider, but the Appcircle logs do not show a successful login event, check the SAML Authentication Assertion returned by the IdP or analyze the HTTP trace for any discrepancies in Appcircle.
- **Misconfigured Scopes:** Ensure that the scopes requested in Appcircle match those defined in Auth0. Mismatches can lead to login failures.
- **Error Response Handling:** If Auth0 returns an error response, Appcircle may display a generic "500 Error: Oops, An Error Occurred. Invalid username or password." This issue often arises when users input incorrect details, such as entering an organization they are not a member of.
5.3 Troubleshooting for Auth0 (SAML)
- **Attribute Mapping Problems:** Verify that the attributes sent by Auth0 match those expected by Appcircle.
- **Token Mismatch:** Ensure the tokens issued by Auth0 match the expected format in Appcircle.
- **Incorrect Assertion Consumer Service (ACS) URL:** Verify that the ACS URL in Auth0 matches the one configured in Appcircle’s SSO settings.
- **SAML Assertion Issues:** Use tools like a SAML debugger to check the contents of the SAML assertion for correct format and expected values before entering them into Appcircle.
- **IdP Login Page Doesn't Display:** If the IdP login page fails to display, ensure the correct SSO URL is being used in Appcircle and that the binding method (HTTP-POST or HTTP-Redirect) is properly configured.
- **Certificate Issues:** Ensure the SAML certificate in Auth0 is valid and correctly configured. Invalid certificates can prevent proper authentication in Appcircle.
- **Error Response Handling:** If Auth0 returns an error response, Appcircle may display a generic "500 Error: Oops, An Error Occurred. Invalid username or password." This issue often arises when users input incorrect details, such as entering an organization they are not a member of.
5.4 Troubleshooting for Microsoft Entra ID (SAML)
- **Incorrect SAML Response:** Check that all required claims and attributes are configured correctly in Microsoft Entra ID.
- **Certificate Expiration:** Ensure that the SAML signing certificate used by Microsoft Entra ID is valid and not expired.
- **Misconfigured Claims or Attributes:** Ensure that the claims and attributes being sent from Microsoft Entra ID are correctly mapped and expected by Appcircle. Mismatches can lead to failed logins or incomplete user profiles.
- **Redirect Loop:** This often occurs due to incorrect reply URLs or session issues. Verify the reply URL in Microsoft Entra ID matches the one in Appcircle and that session cookies are correctly managed.
- **Invalid Certificate or Encryption Issues:** Ensure that the certificates used for signing and encryption are valid and correctly configured in both Microsoft Entra ID and Appcircle’s SSO settings. Expired certificates are a common cause of failures in SAML setups.
- **Unassigned Users:** Ensure that users are assigned to the enterprise application in Microsoft Entra ID. Unassigned users cannot authenticate through Appcircle.
5.5 Troubleshooting for Okta (OpenID Connect)
- **Invalid Client ID/Secret:** Verify the Client ID and Secret in Appcircle match those configured in Okta.
- **Incorrect Scopes Configuration:** Ensure that the correct scopes, like `openid`, `profile`, and `email`, are requested by the client application and match those configured in Appcircle. Okta will reject requests with unsupported or misconfigured scopes.
- **Token Validation Issues:** Use Okta’s introspection endpoint for remote validation of access tokens to ensure they have not been revoked or expired in Appcircle’s SSO integration.
- **Key Rotation Problems:** Regularly update the public keys used by Okta in Appcircle’s SSO settings to ensure continuous validation of tokens, as Okta automatically rotates these keys multiple times a year.
- **Invalid Redirect URI:** Ensure that the redirect URI in Okta matches the one specified in Appcircle. Mismatches can cause authentication failures.
- **403 Forbidden Errors:** Ensure the user has the necessary permissions and that the application is set up correctly in Okta to prevent access issues in Appcircle.
5.6 Troubleshooting for Okta (SAML)
- **Certificate Errors:** Verify that the SAML certificate used in Okta is valid and has not expired.
- **Incorrect ACS URL:** Ensure the Assertion Consumer Service (ACS) URL in Okta matches the one configured in Appcircle.
- **Signing and Encryption Issues:** Verify that both signing and encryption certificates are correctly configured and up to date in both Okta and Appcircle. Expired or incorrectly installed certificates are a common cause of SAML failures.
- **Misconfigured SAML Responses:** Use Okta’s SAML troubleshooting tools to validate the SAML response, ensuring that all required fields are present and correctly formatted before integrating with Appcircle.
- **Invalid SSO URL or Mismatched Entity IDs:** Confirm that the SSO URL and Entity ID configured in Okta are correctly set up in Appcircle’s SSO settings to prevent login issues or errors in the authentication process.
- **Clock Skew:** Ensure the system clocks of both Okta and Appcircle are synchronized to avoid timing issues in the authentication process.
5.7 Troubleshooting for OneLogin (SAML)
- **SSO Errors Due to Incorrect URLs:** Ensure that the SAML Assertion Consumer Service (ACS) URL and other SSO URLs in OneLogin match those in Appcircle.
- **SAML Metadata Misconfiguration:** Ensure that the SAML metadata imported into OneLogin is current and accurately reflects Appcircle’s SSO requirements. Update the metadata periodically to avoid integration issues.
- **Incomplete Attribute Mapping:** Verify that all necessary user attributes are mapped from OneLogin to Appcircle to avoid incomplete user sessions or missing information.
- **Account Linking Failures:** Ensure that user email addresses match between OneLogin and Appcircle. Discrepancies in user data can prevent successful account linking.
- **Certificate Expiration:** Verify that the SAML signing certificate in OneLogin is valid and not expired to ensure seamless authentication with Appcircle.
---
## Authorization
The **Authorization** section allows you to manage user permissions and control access within your Appcircle environment. Set up authorization methods such as RBAC (Role-Based Access Control) and SSO (Single Sign-On) to ensure that users have the appropriate access to projects, integrations, and resources, safeguarding your data and workflows.
We support RBAC authorization and SSO-based authorization methods. Current headlines and the actions you can complete are listed below:
- [**RBAC (Role-Based Access Control) Authorization**](/account/my-organization/security/authorization/rbac-authorization)
- [**SSO Authorization**](/account/my-organization/security/authorization/sso-authorization)
- [**Enterprise App Store SSO Authorization**](/account/my-organization/security/authorization/store-sso-authorization)
In order to see the details, check the submenu of this documentation page.
---
## RBAC Authorization
## 1. Introduction
RBAC (Role-Based Access Control) authorization allows administrators to manually assign permissions to individual users within Appcircle. This method is particularly useful when specific users require customized access, or when organizations choose to control access internally without relying on external IdP integrations.
### Prerequisites
Before you begin configuring SSO for Appcircle, ensure that you have the following prerequisites:
- An active Appcircle account with administrative privileges.
- A list of users who need specific permissions assigned or modified.
## 2. Managing Team Members and Their Permissions
### Team Ownership
The creator of a team starts with the Owner role. The Owner role has full administrative privileges for the team and organization management such as adding/removing members or editing the organization details, while any new members can be assigned specific module-based read/write roles.
:::caution
Each organization must have at least one Owner and each user must be an Owner of at least one organization.
:::
### Invite Users and Assign Roles
As an Owner, you can invite new users simply by entering their email address under the related field in Team Management and pressing the **Add a New User** button.
The user will be then shown in a **Pending** state until the invitation is accepted. At the same time, you can resend the invitation with the **Resend** option. You can also revoke a pending invite by pressing the delete button at the end of the row.
Once a user accepts an invite, it will be added to the team as a Member with read only access. You can change the role of any user, including yourself, with the **Manage Roles** button next to the user ID. You can also delete a user by pressing the delete button.
Within the opened modal, you can specifically adjust the user's roles across all modules on the right side.
Additionally, the user's assigned organization and sub-organizations will be visible on the left side.
If a sub-organization is created within an organization, everyone in the root organization will be able to see this sub-organization. The roles for these users in the sub-organization will be inherited from the root organization, which is why their permissions will be listed as inherited.
If a user is directly added to the sub-organization, their role will be listed as **Member** instead of **Inherited**.
:::info Sub-organizations
If you want a user to be part of only a specific sub-organization, invite them directly from within that sub-organization.
:::
:::tip
The search bar within the Team Management area allows you to efficiently manage and locate organization members by searching their email addresses to enhance visibility and streamline the management of both current and newly invited members.
:::
## 3. Advanced Role Management
:::info
Team management with fine-grained roles and integration with enterprise identity systems are available in the enterprise plan. Please [contact us](https://appcircle.io/contact) for more information.
:::
Once you click the "Manage Roles" button, you will be presented with a detailed selection of roles for each module.
Here, you can assign the Owner role to a user for full access or you can select specific read or write roles for use cases like developers or testers or billing administrators.
:::info
The "None" is a special type of permission that denotes that a user has no defined role or special permissions. If the user's permission is set to "None" in sub-organizations, the user's permission defaults from the organization.
:::
For more information on the roles and permissions, please refer to the:
Role Management
---
## SSO Authorization
## 1. Introduction
In Appcircle, authorization for SSO users can be managed by mapping user groups and roles from your identity provider (IdP) to specific module permissions and organizations within Appcircle. This ensures seamless Role-Based Access Control (RBAC) across the platform.
Before configuring SSO-based authorization, you must first complete the SSO integration setup. You can refer to the [SSO Integration Documentation](/account/my-organization/security/authentications/sso-authentication) for detailed instructions on how to configure SSO with your chosen provider, such as Azure AD, Okta, or Auth0.
Once SSO integration is complete, you can configure authorization by mapping IdP groups and roles to Appcircle organizations and module permissions.
### Prerequisites
- SSO integration with your chosen identity provider (Auth0, Azure AD, Okta, OneLogin).
- Knowledge of groups and roles in your IdP that you want to map to Appcircle organizations and permissions.
- Administrative access to Appcircle and your IdP.
### Quick Access
Jump directly to your provider configurations:
- [Auth0 - Open ID Connect](/account/my-organization/security/authorization/sso-authorization#auth0-openid-connect)
- [Auth0 - SAML](/account/my-organization/security/authorization/sso-authorization#auth0-saml)
- [Microsoft Entra ID / Azure AD Configuration](/account/my-organization/security/authorization/sso-authorization#microsoft-entra-id-saml)
- [Okta - Open ID Connect](/account/my-organization/security/authorization/sso-authorization#okta-openid-connect)
- [Okta - SAML](/account/my-organization/security/authorization/sso-authorization#okta-saml)
### Overview of Configuring SSO Authorization
In Appcircle, user access is managed through organizations and organization-specific roles. You can add users to any organization and assign them roles in that organization.
With SSO Authorization, you map your IdP (Identity Provider) groups to the corresponding Appcircle organizations, so any user in a particular IdP group automatically becomes a member of the matching organization in Appcircle. This means you no longer need to manually manage user organization membership and role assignments, as the process is handled through your IdP’s group memberships. Then, you must also map your IdP groups or roles (depending on your IdP configuration) to Appcircle roles to manage each user’s permissions.
#### Example Setup
Suppose you have the following structure in Appcircle:
- **Root Organization**
- **Sub Organization1**
- **Sub Organization2**
#### 1. Create Corresponding IdP Groups
Create matching groups in your IdP for each of your Appcircle organizations:
- **IdP group for Root Organization** → _Root Organization_
- **IdP group for Sub Organization1** → _Sub Organization1_
- **IdP group for Sub Organization2** → _Sub Organization2_
Any user who is a member of the IdP group mapped to _Root Organization_ will automatically be added to _Root Organization_ in Appcircle, and likewise for your sub-organizations.
#### 2. Define Role Mappings
For each group-organization pairing, you must configure role mapping to manage user permissions in that organization. For example, you might set up role mappings like this:
- **IdP group “Owners”** → _Owner_ role in Appcircle
- **IdP group “Managers”** → _Build Profile Manager, Testing Distribution Manager etc._ role in Appcircle
- **IdP group “Viewers”** → _Build Profile Viewer_ role in Appcircle
You would create separate spesific IdP groups for each organization. For example:
- **IdP group "AC-SubOrg1-Owners"** → _Owner_ role in _Sub Organization1_
- **IdP group "AC-SubOrg1-Managers"** → _Testing Distribution Manager_ role in _Sub Organization1_
By assigning a role mapping for every group-organization mapping, you ensure that users automatically receive the appropriate permissions as soon as they are placed in the relevant IdP group.
#### Additional Notes
- You must configure a group-to-organization mapping for each organization (root and sub organizations).
- You must define role mappings for each group-organization pairing. If no role mapping exists, users will not have any permissions in organization.
- User organization memberships and permissions are synchronized on every SSO login.
- If your mapping configuration is incorrect, Appcircle ensures at least one Owner remains in the organization by ignoring the faulty mapping.
- You do not need to invite users manually if SSO Authorization is enabled.
## 2. General Configuration Steps
These steps will guide you through the configuration within your chosen identity provider and Appcircle.
Step 1: Configure Your Identity Provider
1. Perform identity provider-specific configurations, including creating groups and roles, and defining group and role claims/attributes.
2. In Appcircle, enter the group and role claim/attribute names as defined in your IdP.
Follow **3. Specific Provider Configuration** section to complete this steps.
Step 2: Enable SSO Mapping and Configure Group and Role Mappings
### Accessing SSO Mapping Settings
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Appcircle SSO Login**.
3. Select the **Manage Authorization**
### Group and Role Mapping Configuration
:::info
You can refer to the [Overview of Configuring SSO Authorization](#overview-of-configuring-sso-authorization) for a better understanding of group and role mapping.
:::
1. Enter the name of the SSO group and select the corresponding Appcircle organization you want to map. Ensure the group name is correct.
2. Click Add to map the SSO group to an Appcircle organization. This will automatically link users from the SSO group to the selected organization in Appcircle.
3. You must define role mappings for each group mapping. Click the **Configure** button to set up role mappings.
4. Enter the role name and select the corresponding Appcircle roles you want to map. Ensure the role name is correct.
5. Finally, enable SSO Authorization with the **Enable SSO Authorization** toggle.
## 3. Specific Provider Configuration
#### Auth0 (OpenID Connect)
Auth0 (OpenID Connect)
#### Step 1. Create Roles
1. In the Auth0 dashboard, navigate to the **User Management > Roles** section.
2. Click **Create Role** button. Create necessary roles.
#### Step 2. Create Organization
1. In the Auth0 dashboard, navigate to the **Organization** section.
2. Click **Create Organization** button to create organizations.
3. Click the created organization to navigate to **Organization Details**.
4. On the **Organization Details** screen, click the **Members** tab to manage members of organization.
5. Click the **Add Members** button to add users who will become members of your organization.
6. On the **Members** screen, click the three dots and select **Assign Roles**. Assign the desired roles to users for organization.
7. On the **Organization Details** screen, navigate to the **Connections** tab.
8. Click the **Enable Connections** button
9. Select **Username-Password-Authentication** and click **Enable Connection**
10. Select **Enable Auto-Membership** and **Enable Signup** on the displayed screen, then click **Save**.
#### Step 3. Enable Organization for your application
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Select the relevant application.
3. On the **Application Details** screen, navigate to the **Organizations** tab.
4. Click **Disable Grants Now**.
5. Choose **Business Users** for the type of users and select **Prompt for Organization** for the login flow.
6. Click **Save Changes**.
#### Step 4. Define Group And Role Attributes & Claims
The user's group and role values should be included in the token as claims. This enables retrieval of the user's group and role during SSO login. The groups claim is already present in the token. Follow these steps to add the roles claim:
1. In the Auth0 dashboard, navigate to the **Actions > Library** section.
2. Click the **Create Action** button and select **Build from Scratch**.
3. Enter an appropriate name for the **Custom Action** in the popup window. Keep the remaining settings at their default values,as shown in the image below.
4. On the **Custom Action Details** screen, copy and paste following Javascript code to code editor.
```js
exports.onExecutePostLogin = async (event, api) => {
const namespace = 'your_namespace_';
if (event.authorization) {
api.idToken.setCustomClaim(`${namespace}roles`, event.authorization.roles);
api.accessToken.setCustomClaim(`${namespace}roles`, event.authorization.roles);
}
}
```
5. Finally click on the **Deploy** button.
6. In the Auth0 dashboard, navigate to the **Flows** section.
7. Click the Login.
8. Drag and drop the custom action created previously. The role claim has been added to the token.
#### Step 5. Define Group and Role Claim Names in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Appcircle SSO Login**.
3. Select the **Manage Authorization**.
2. Enter the Group Claim Name as org_id and the Role Claim Name as your_namespace_roles. Note that the role claim is created as a custom claim in Auth0, so use the name you determined earlier.
#### Auth0 (SAML)
Auth0 (SAML)
#### Step 1. Create Roles
1. In the Auth0 dashboard, navigate to the **User Management > Roles** section.
2. Click **Create Role** button. Create necessary roles.
#### Step 2. Create Organization
1. In the Auth0 dashboard, navigate to the **Organization** section.
2. Click **Create Organization** button to create organizations.
3. Click the created organization to navigate to **Organization Details**.
4. On the **Organization Details** screen, click the **Members** tab to manage members of organization.
5. Click the **Add Members** button to add users who will become members of your organization.
6. On the **Members** screen, click the three dots and select **Assign Roles**. Assign the desired roles to users for organization.
7. On the **Organization Details** screen, navigate to the **Connections** tab.
8. Click the **Enable Connections** button
9. Select **Username-Password-Authentication** and click **Enable Connection**
10. Select **Enable Auto-Membership** and **Enable Signup** on the displayed screen, then click **Save**.
#### Step 3. Enable Organization for your application
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Select the relevant application.
3. On the **Application Details** screen, navigate to the **Organizations** tab.
4. Click **Disable Grants Now**.
5. Choose **Business Users** for the type of users and select **Prompt for Organization** for the login flow.
6. Click **Save Changes**.
#### Step 4. Define Group And Role Attributes & Claims
The user's group and role values should be included in the token as claims. This enables retrieval of the user's group and role during SSO login. The groups claim is already present in the token. Follow these steps to add the roles claim:
1. In the Auth0 dashboard, navigate to the **Actions > Library** section.
2. Click the **Create Action** button and select **Build from Scratch**.
3. Enter an appropriate name for the **Custom Action** in the popup window. Keep the remaining settings at their default values,as shown in the image below.
4. On the **Custom Action Details** screen, copy and paste following Javascript code to code editor.
```js
exports.onExecutePostLogin = async (event, api) => {
const namespace = 'your_namespace_';
if (event.authorization) {
api.idToken.setCustomClaim(`${namespace}roles`, event.authorization.roles);
api.accessToken.setCustomClaim(`${namespace}roles`, event.authorization.roles);
}
}
```
5. Finally click on the **Deploy** button.
6. In the Auth0 dashboard, navigate to the **Flows** section.
7. Click the Login.
8. Drag and drop the custom action created previously. The role claim has been added to the token.
#### Step 5. Define Group and Role Attributes names in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Appcircle SSO Login**.
3. Select the **Manage Authorization**.
4. Enter the Group Attribute Name as `http://schemas.auth0.com/org_id` and the Role Attribute Name as `http://schemas.auth0.com/your_namespace_roles`. Note that the role attribute is created as a custom attribute in Auth0, so you must use the name you determined previously.
#### Microsoft Entra ID (SAML)
Microsoft Entra ID (SAML)
#### Step 1. Create Groups in Microsoft Entra ID
1. Log in to [Azure](https://azure.microsoft.com/en-us/) as an admin and navigate to **Azure Services > Microsoft Entra ID**
2. Navigate to the **Manage > Groups** section from left menu.
3. Click the **New Group**.
4. Assign a proper name and description to the new group. Designate an owner and members to the group.
5. Create the groups for map to Appcircle organizations and roles as needed.
#### Step 2. Assign user and group to application in Microsoft Entra ID
1. Navigate to the **Azure Services > Microsoft Entra ID**.
2. Navigate to the **Manage > Enterprise applications** section from left menu.
3. Click your application.
4. Click **Assign users and groups**.
5. Click **Add user/group**.
6. Select users and groups. This process can be repeated as needed.
#### Step 3. Define Group Attribute & Claim in Microsoft Entra ID
1. Navigate to the **Manage > Single sign-on** section from left menu.
2. Click **Edit** in **Attributes & Claims** section.
3. Click the **Add a Group Claim**.
4. Select the **Groups assigned to the application**
5. Select the **Cloud only group display names** as source attribute.
6. Then click on the **Save** button
#### Step 4. Define Group and Role Attribute names in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Appcircle SSO Login**.
3. Select the **Manage Authorization**.
4. Enter **Group Attribute Name** as ``http://schemas.microsoft.com/ws/2008/06/identity/claims/groups`` and **Role Attribute Name** as ``http://schemas.microsoft.com/ws/2008/06/identity/claims/groups``.
We use EntraID groups to manage user groups and roles. Both are sent to Appcircle in one claim. If needed, you can set up a more advanced configuration with a separate claim for roles.
#### Okta (OpenID Connect)
Okta (OpenID Connect)
#### Step 1. Create Groups and Define Group Claim
1. Navigate to the **Directory > Groups** section in the Okta Dashboard
2. Create the groups for map to Appcircle organizations and roles. In this guide, we’ll use Okta groups to manage user groups and roles.
3. Assign users to groups.
4. Navigate to the **Applications > Applications** section from left navigation menu.
5. Select your application from the list
6. Navigate to the **Sign on** tab.
7. Click **Edit** for OpenID Connect ID Token.
8. Enter Groups claim filter as shown in the image below.
9. Navigate to the **Applications > Applications** section from left navigation menu.
10. Click **Refresh Application Data**.
#### Step 2. Define Group and Role Claim in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Appcircle SSO Login**.
3. Select the **Manage Authorization**.
4. Enter **Group Attribute Name** as ``groups`` and **Role Attribute Name** as ``groups``.
We use Okta groups to manage user groups and roles. Both are sent to Appcircle in one claim. If needed, you can set up a more advanced configuration with a separate claim for roles.
#### Step 3: Update SSO Scope Configuration
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** option under the **Appcircle SSO Login**.
3. Select **Manage Authentication** and click the **Edit** button.
4. Add the **groups** to the **Default Scope** field.
5. Click the **Save** button.
#### Okta (SAML)
Okta (SAML)
#### Step 1. Create Groups and Assign to the Application
1. Navigate to the **Directory > Groups** section in the Okta Dashboard. Create the groups for map to Appcircle organizations and roles. In this guide, we’ll use Okta groups to manage user groups and roles.
2. Assign users to groups.
3. Navigate to the **Applications > Applications** section from left navigation menu.
4. Select your application from the list
5. Navigate to the **Assignments** tab.
6. Assign the previously created groups to the application.
#### Step 2. Define Group and Role Attributes
1. Navigate to the **Applications > Applications** section.
2. Select your application from the list and navigate to the **General** tab.
3. Click on **Edit** in **SAML Settings**
4. Enter the Group Attribute statement as following configuration.
- Name: Enter "groups"
- Name format: Select "Basic"
- Filter: Select "Matches regex"
- Filter Value: Enter ".*"
#### Step 3. Define Group and Role Claim in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Appcircle SSO Login**
3. Select the **Manage Authorization**.
4. Enter **Group Attribute Name** as ``groups`` and **Role Attribute Name** as ``groups``.
We use Okta groups to manage user groups and roles. Both are sent to Appcircle in one claim. If needed, you can set up a more advanced configuration with a separate claim for roles.
## 4. Testing and Verification
After configuring SSO Mapping, it is important to test the integration to ensure that users have the correct permissions based on their groups and roles. This section covers how to test the integration.
When a user logs into Appcircle, their organization membership and roles are updated according to the configured Group and Role Mapping.
1. Open an incognito window in your browser to avoid any cached sessions interfering with the test.
2. Use SSO to log in to Appcircle with a test account.
3. Verify if the user's organization membership and roles are updated according to the configured Group and Role Mapping.
:::info
In self-hosted deployments, the organization memberships and roles of admin users do not change with SSO authorization; they will remain the same.
:::
:::info
Organizations must have at least one owner. After processing SSO Authorization Mapping, if there are no remaining owners in the organization, the user's role and organization membership will remain unchanged for that organization.
:::
## 5. Limitations
Due to technical limitations, SSO mapping does not support automatic synchronization. Changes such as the removal of a user from the Identity Provider or updates to their groups or roles will only take effect when the user logs in to Appcircle.
---
## Enterprise App Store SSO Authorization
### Introduction
Managing user groups within Auth0 provides users and organizations with several benefits. By organizing users into groups, administrators can efficiently manage access permissions for various applications and resources, saving time and effort. Administrators can synchronize Auth0 user groups with Appcircle, allowing for granular access control and group-based permissions. This integration enhances security, simplifies access management, and promotes collaboration within organizations utilizing the Appcircle platform.
### Summary of Configuration Steps
This section provides a brief summary of the configuration steps.
1. Perform identity provider-specific configurations, including creating groups, and defining group claims/attributes.
2. In Appcircle, specify the **Claim Name (OpenID)/Attribute Name (SAML)** according to your Identity Provider configuration.
3. In Appcircle, enable **SSO Authentication** for Enteprise App Store and Testing Distribution.
### Specific Provider Configuration
Auth0Auth0 (OpenID Connect)
#### Step 1. Create Organizations
1. In the Auth0 dashboard, navigate to the **Organization** section.
2. Click **Create Organization** button to create organizations.
3. Click created organization to navigated **Organization Details**.
4. On the **Organization Details** screen, click on the **Members** tab to manage members of organization.
5. Click the **Add Members** button. Add users who will become members of your organization.
6. On the **Organization Details** screen, navigate to the **Connections** tab.
7. Click the **Enable Connections** button
8. Select **Username-Password-Authentication** and click on **Enable Connection**
9. Select **Enable Auto-Membership** and **Enable Signup** on the displayed screen, then click **Save**.
#### Step 2. Enable organization for your application
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Select the relevant application.
3. On the **Application Details** screen, navigate to the **Organizations** tab.
4. Click **Disable Grants Now**.
5. Choose **Business Users** for the type of users and select **Prompt for Organization** for the login flow.
6. Click **Save Changes**.
#### Step 3. Define Group Claim Name in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Enterprise Portal SSO Login**.
3. Select the **Manage Authorization**.
4. Enter the **Claim Name (OpenID)/Attribute Name (SAML)** as `org_id`.
Auth0 (SAML)
#### Step 1. Create Organizations
1. In the Auth0 dashboard, navigate to the **Organization** section.
2. Click **Create Organization** button to create organizations.
3. Click created organization to navigated **Organization Details**.
4. On the **Organization Details** screen, click on the **Members** tab to manage members of organization.
5. Click the **Add Members** button. Add users who will become members of your organization.
6. On the **Organization Details** screen, navigate to the **Connections** tab.
7. Click the **Enable Connections** button
8. Select **Username-Password-Authentication** and click on **Enable Connection**
9. Select **Enable Auto-Membership** and **Enable Signup** on the displayed screen, then click **Save**.
#### Step 2. Enable organization for your application
1. In the Auth0 dashboard, navigate to the **Applications** section.
2. Select the relevant application.
3. On the **Application Details** screen, navigate to the **Organizations** tab.
4. Click **Disable Grants Now**.
5. Choose **Business Users** for the type of users and select **Prompt for Organization** for the login flow.
6. Click **Save Changes**.
#### Step 3. Define Group Attribute Name
1. Navigate to the **SSO Login** screen in Appcircle.
2. Enter the **Claim Name (OpenID)/Attribute Name (SAML)** as `http://schemas.auth0.com/org_id`.
Microsoft Entra ID (formerly Azure Active Directory) Microsoft Entra ID (SAML)
#### Step 1. Create Groups in Microsoft Entra ID
1. Log in to [Azure](https://azure.microsoft.com/en-us/) as an admin and navigate to **Azure Services > Microsoft Entra ID**
2. Navigate to the **Manage > Groups** section from left menu.
3. Click the **New Group**.
4. Assign a proper name and description to the new group. Designate an owner and members to the group.
#### Step 3. Assign user and group to application in Microsoft Entra ID
1. Navigate to the **Azure Services > Microsoft Entra ID**.
2. Navigate to the **Manage > Enterprise applications** section from left menu.
3. Click your application.
4. Click **Assign users and groups**.
5. Click **Add user/group**.
6. Select users, groups and role. This process can be repeated as needed.
#### Step 4. Define Group Attributes & Claims in Microsoft Entra ID
1. Navigate to the **Manage > Single sign-on** section from left menu.
2. Click **Edit** in **Attributes & Claims** section.
3. Click the **Add a Group Claim**.
4. Select the **Groups assigned to the application**
5. Select the **Cloud only group display names** as source attribute.
6. Then click on the **Save** button
#### Step 5. Define Group Attributes names in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Enterprise Portal SSO Login**.
3. Select the **Manage Authorization**.
4. Enter the **Claim Name (OpenID)/Attribute Name (SAML)** as ``http://schemas.microsoft.com/ws/2008/06/identity/claims/groups``.
OktaOkta (OpenID Connect)
#### Step 1. Create Groups and Define Group Claim
1. Navigate to the **Directory > Groups** section in the Okta Dashboard
2. Create the groups as needed.
3. Assign users to groups.
4. Navigate to the **Applications > Applications** section from left navigation menu.
5. Select your application from the list
6. Navigate to the **Sign on** tab.
7. Click **Edit** for OpenID Connect ID Token.
8. Enter Groups claim filter as shown in the image below.
9. Navigate to the **Applications > Applications** section from left navigation menu.
10. Click **Refresh Application Data**.
#### Step 2. Define Group Claim in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Enterprise Portal SSO Login**.
3. Select the **Manage Authorization**.
4. Enter the **Claim Name (OpenID)/Attribute Name (SAML)** as ``groups``.
#### Step 3: Update SSO Scope Configuration
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** option under the **Enterprise Portal SSO Login**.
3. Select **Manage Authentication** and click the **Edit** button.
4. Add the **groups** to the **Default Scope** field.
5. Click the **Save** button.
Okta (SAML)
#### Step 1. Create Groups and Assign to the Application
1. Navigate to the **Directory > Groups** section in the Okta Dashboard. Create the groups as needed.
2. Assign users to groups.
3. Navigate to the **Applications > Applications** section from left navigation menu.
4. Select your application from the list
5. Navigate to the **Assignments** tab.
6. Assign the previously created groups to the application.
#### Step 3. Define Group Attributes
1. Navigate to the **Applications > Applications** section.
2. Select your application from the list and navigate to the **General** tab.
3. Click on **Edit** in **SAML Settings**
4. Enter the Group Attribute statement as as shown in the image below.
#### Step 4. Define Group Claim in Appcircle
1. Navigate to the **Organization > Security > Authentications** section on your dashboard.
2. Select the **Manage** on the **Enterprise Portal SSO Login**.
3. Select the **Manage Authorization**.
4. Enter the **Claim Name (OpenID)/Attribute Name (SAML)** as ``groups``.
### Testing and Troubleshooting
After configuring Authorization with SSO for Enterprise App Store, it is important to test the integration to ensure that users authorization work seamlessly and as expected. Follow [Enterprise App Store Documentation](/enterprise-app-store/enterprise-app-store-profile) to test the integration.
---
## App Store Connect API Key
You can add, delete and manage iOS Certificates and Provisioning Profiles manually using Appcircle. There is also an easier way. By linking your Apple Developer account to Appcircle, you can see a list of certificates and provisioning profiles and pick the ones you want to use for building and distributing.
To link your Apple Developer account, **you need an App Store Connect API Key** from Apple's **App Store Connect Panel**.
## Login to App Store Connect
Go to [https://appstoreconnect.apple.com](https://appstoreconnect.apple.com) and login with your account.
:::caution
Make sure that the correct team is selected on the top right. For developer accounts that belong to multiple teams, this is important.
:::
Once the team is correct, select **Users and Access** from the menu:
After navigating to **Users and Access**, you will see 4 tabs next to the title. Select the **Integrations** tab. Then make sure that **App Store Connect API** is selected from the list on the left.
## Generating a New Key
To generate a new key, press the + button.
:::caution
Only Account Holders can enable the API Key generation. If you see a disabled **Request Access** button, contact your account holder and make them follow the steps above. After they request access, you can create new keys.
:::
A modal popup will ask you to enter a name and add roles for this key:
:::caution
The Admin access is required to create new and download certificates or provisioning profiles. You can also give access to certain users, and on per app basis, but they require additional configuration from Apple Developer Portal.\
\
To see a list of permissions each role has, visit: [https://developer.apple.com/support/roles/](https://developer.apple.com/support/roles/)
:::
### Downloading the Key
After generating the key, download the key file by pressing Download API Key next to it.
:::caution
**You can only download the file once**. If you lose the file, you need to generate a new key.
:::
## Linking Appcircle with App Store Connect
Adding a key to Appcircle is pretty easy. **Go to your organization** by selecting the bottom left button from the toolbar:
On the Organization screen, select **Add New** on **App Store Connect API Keys **list item**:**
On the form, upload the **.p8** key file downloaded from App Store Connect:
Fill in the rest of the form. You can find the **Key ID** and **Issuer ID** from App Store Connect Panel here:
Copy and paste them to the form in Appcircle, give it a name, and save.
:::info
You can add multiple keys. We'll ask you which key to use while downloading a certificate.
:::
### Enterprise API Key Option for App Store Connect
The App Store Connect Enterprise API Key is a crucial component for managing Apple Enterprise accounts within Appcircle. This API key allows seamless integration with App Store Connect, enabling automated provisioning, certificate management, and distribution processes for enterprise applications.
#### Prerequisites
Before using the App Store Connect Enterprise API Key, ensure that:
- You have an Apple Developer Enterprise Program account.
- You have Admin or Account Holder privileges in App Store Connect.
- Your App Store Connect account supports API access.
### Adding the API Key to Appcircle
Once the API key is generated, it must be added to Appcircle:
1. Navigate to the Organization module in Appcircle.
2. Click **Add New** next to the App Store Connect API Keys section under Credentials area.
3. Upload the downloaded .p8 file.
4. Enter the Key ID and Issuer ID obtained from App Store Connect.
5. Select the Enterprise API Key option for enterprise account integration.
6. Click Save to complete the setup.
:::info
Please note that the registered Enterprise API Key cannot be used within the Publish module because the Apple Enterprise Program does not provide TestFlight or App Store Connect services.
:::
## Sharing App Store Connect Credentials
Root Organization users have the ability to share their saved credentials with Sub-Organization users. This feature helps streamline credential management across distributed teams and multiple organizational units.
#### How to Share Credentials
**1.** Navigate to the Credentials Section
Go to My Organization > Security > Credentials.
**2.** Open Manage Panel
Click the respective credential type (e.g., App Store Connect API Keys) to view your saved credentials.
**3.** Select the Credential
Click the Share icon under the Actions column for the credential you want to share.
**4.** Configure Sharing Settings
In the Share Credentials panel:
- Enter or confirm the Settings Name.
- Toggle Share with all sub-organizations if you want to make the credential available to all sub-organizations automatically.
- Alternatively, manually select specific sub-organizations that should have access by checking the boxes under Sub-Organizations.
**5.** Save Sharing Configuration
Once your selections are made, click Share to apply.
Shared credentials will be visible and usable in the selected Sub-Organizations as if they were their own.
:::info
Sub-Organizations cannot edit or delete credentials shared by the Root Organization.
:::
The shared credentials by the Root Organization will be marked with Root Tag on the Sub Organization's credential list.
---
## Google Play Service Account
Google Service Account is required to upload your binary to Google Play Store. This JSON key must be added to your account to publish apps to Google Play.
1. Please go to [Google Cloud Platform](https://console.cloud.google.com/apis) and create a Google Cloud Project.
2. **Enable** the `Google Play Android Developer API` for your Google Cloud Project.
:::danger
Skipping this step will result in your JSON being rejected by Appcircle because it will not have access to the project.
:::
3. Login with your account, then head over to **Credentials -> Create Credentials**, and then click **Service account**.
4. This screen will forward you to the **Create service account** page. Fill in the details of your service account. According to the service name you set, an automatic **Service account ID** will be created.
5. Please select `Editor` in the Role dropdown.
6. Click Done to save this account.
7. Click **Manage service accounts** to open manage page.
8. Find the account you have just created. Click three dots on the Actions column, and then click **Manage keys**.
9. Click **ADD KEY** and then click **Create new key**.
10. Download your key as JSON and save it.
11. Go to [Google Play Console](https://play.google.com/console) and login with your account and then head over to **User and permissions** and then click **Invite new users**.
12. Add the email, generated in step 6 in the **E-mail address** field.
13. Check the permissions of your user.
Make sure this account has access to **Releases**, **Store presence**, and **App access** (for read-only ones).
Then click **Invite User**. Your account key is ready. 🎉
14. To add the key on Appcircle, follow these steps:
a. Navigate to [My Organization](/account/my-organization).
b. Locate the `Google Play Developer API Keys` under the `Credentials` section.
c. Click the `Manage` button if you have saved keys, or directly click the `Add New` button.
## Sharing Google Play Developer Credentials
Root Organization users have the ability to share their saved credentials with Sub-Organization users. This feature helps streamline credential management across distributed teams and multiple organizational units.
#### How to Share Credentials
**1.** Navigate to the Credentials Section
Go to My Organization > Security > Credentials.
**2.** Open Manage Panel
Click the respective credential type (e.g., App Store Connect API Keys) to view your saved credentials.
**3.** Select the Credential
Click the Share icon under the Actions column for the credential you want to share.
**4.** Configure Sharing Settings
In the Share Credentials panel:
- Enter or confirm the Settings Name.
- Toggle Share with all sub-organizations if you want to make the credential available to all sub-organizations automatically.
- Alternatively, manually select specific sub-organizations that should have access by checking the boxes under Sub-Organizations.
**5.** Save Sharing Configuration
Once your selections are made, click Share to apply.
Shared credentials will be visible and usable in the selected Sub-Organizations as if they were their own.
:::info
Sub-Organizations cannot edit or delete credentials shared by the Root Organization.
:::
The shared credentials by the Root Organization will be marked with Root Tag on the Sub Organization's credential list.
## FAQ
**Can I retrieve the JSON private key that I uploaded to Appcircle?**
No, for security reasons, you cannot download the JSON file you uploaded to Appcircle.
**Why cannot I save the JSON after uploading it?**
You might have missed the first step. Please ensure that you have enabled the Service Account.
---
## Huawei AppGallery API Key
Huawei AppGallery API Key is required to upload your binary to Huawei AppGallery. This JSON key must be added to your account to publish apps Huawei AppGallery.
1. Please go to Go to [Huawei AppGallery Console](https://developer.huawei.com) and login with your account and then head over to **Users and Permissions** and then click **Connect API**
2. Create a [Team-Level Api Key](https://developer.huawei.com/consumer/en/doc/distribution/app/appgallerykit-createapiclient). Don't select a project in order to create Team-Level API Key.
3. Hit the `Download` button to download the API key.
Your account key is ready. To add a key, go to [My Organization](/account/my-organization) and press the "Add New" button (or the "Manage" button first if you have saved keys) next to the "Huawei AppGallery API Keys" item under the Credentials section.
## Sharing Huawei AppGallery Credentials
Root Organization users have the ability to share their saved credentials with Sub-Organization users. This feature helps streamline credential management across distributed teams and multiple organizational units.
#### How to Share Credentials
**1.** Navigate to the Credentials Section
Go to My Organization > Security > Credentials.
**2.** Open Manage Panel
Click the respective credential type (e.g., App Store Connect API Keys) to view your saved credentials.
**3.** Select the Credential
Click the Share icon under the Actions column for the credential you want to share.
**4.** Configure Sharing Settings
In the Share Credentials panel:
- Enter or confirm the Settings Name.
- Toggle Share with all sub-organizations if you want to make the credential available to all sub-organizations automatically.
- Alternatively, manually select specific sub-organizations that should have access by checking the boxes under Sub-Organizations.
**5.** Save Sharing Configuration
Once your selections are made, click Share to apply.
Shared credentials will be visible and usable in the selected Sub-Organizations as if they were their own.
:::info
Sub-Organizations cannot edit or delete credentials shared by the Root Organization.
:::
The shared credentials by the Root Organization will be marked with Root Tag on the Sub Organization's credential list.
## FAQ
### Why am I getting the error **[AppGalleryConnectFileService]distContryList is empty and usage route site is not China?**
This error may occur if the [Huawei Supported Countries ](https://developer.huawei.com/consumer/en/doc/app/agc-help-supported-countries-overview-0000001146718725) list has been updated.To resolve this issue, please follow these steps:
1. Open the page with your app information in your [Huawei Developer](https://developer.huawei.com/consumer/en/console/service/AppService) account (App Release > HarmonyOS|Android > Your app on list > Version Information > Your app version).
2. Update the `Country/Region for release` list and save the changes.
3. Try again to send the release to Huawei AppGallery via Appcircle.
### Why am I getting the error **[AppGalleryConnectPublishService]input aab size is too large?**
AppGallery Connect server imposes size limits on app submissions. For AAB files, the size limit is 150MB. This error occurs because your AAB file exceeds this limit. For more details, please refer to the following documentation:
- [Submitting an App Package in Download Mode](https://developer.huawei.com/consumer/en/doc/AppGallery-connect-References/agcapi-add-packageurl-0000001158245065#section15344132481910)
:::info
If your app package is an APK, the size limit is 4GB. This error indicates that your APK exceeds this limit. Make sure your app package complies with the [size limits based on the type of package](https://developer.huawei.com/consumer/en/doc/AppGallery-connect-References/agcapi-add-packageurl-0000001158245065#section15344132481910) you are using.
:::
---
## Microsoft Intune API Key
The Intune API key allows you to upload the binary file and metadata information to your Microsoft Intune account.
Integration information for InTune can be added from the **Security** section under [**Appcircle Organization**](/account/my-organization).
After completing the required credentials information in the modal, your Microsoft InTune account is successfully integrated with Appcircle.
#### Fields Explained
- **Setting Name**: Enter a user-friendly name to save the credentials for reuse in this app or other apps.
- **Client ID**: Specifies the [**Application (client) ID**](https://learn.microsoft.com/en-us/entra/identity-platform/howto-call-a-web-api-with-curl?tabs=dotnet6&pivots=no-api#register-the-web-api) which uniquely identifies your application in the Microsoft cloud ecosystem, across all tenants.
- **Client Secret**: A client secret, sometimes referred to as an application password, is a string value your app can use to identify itself. Learn how to create one [here](https://learn.microsoft.com/en-us/graph/auth-register-app-v2#option-2-add-a-client-secret).
- **Auth URL**: Specifies the authorization URL generated by the application you created on the Microsoft Identity Platform. This URL should be in the following format: `https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token`. More details [here](https://learn.microsoft.com/en-us/entra/identity-platform/howto-call-a-web-api-with-curl?tabs=dotnet6&pivots=no-api#register-the-web-api).
### Providing Microsoft Graph API Credentials for Accessing Intune
To send an app from Appcircle to Microsoft Intune, you need to [register an application with the Microsoft Identity Platform](https://learn.microsoft.com/en-us/graph/auth-register-app-v2) and provide this application's credentials.
:::info
Appcircle utilizes [Microsoft Graph APIs to publish apps in Microsoft Intune](https://learn.microsoft.com/en-us/graph/api/resources/intune-graph-overview?view=graph-rest-1.0). Therefore, you need to grant the following permissions to the application you registered and provided credentials for on the Microsoft Identity Platform.
- DeviceManagementApps.Read.All
- DeviceManagementApps.ReadWrite.All
Ensure that the permissions being granted are Application permissions rather than Delegated permissions. You can find detailed information about granting permissions [here](https://learn.microsoft.com/en-us/entra/identity-platform/howto-call-a-web-api-with-curl?tabs=dotnet6&pivots=no-api#add-application-permissions-to-allow-access-to-a-web-api).
:::
## Sharing Microsoft Intune Credentials
Root Organization users have the ability to share their saved credentials with Sub-Organization users. This feature helps streamline credential management across distributed teams and multiple organizational units.
#### How to Share Credentials
**1.** Navigate to the Credentials Section
Go to My Organization > Security > Credentials.
**2.** Open Manage Panel
Click the respective credential type (e.g., App Store Connect API Keys) to view your saved credentials.
**3.** Select the Credential
Click the Share icon under the Actions column for the credential you want to share.
**4.** Configure Sharing Settings
In the Share Credentials panel:
- Enter or confirm the Settings Name.
- Toggle Share with all sub-organizations if you want to make the credential available to all sub-organizations automatically.
- Alternatively, manually select specific sub-organizations that should have access by checking the boxes under Sub-Organizations.
**5.** Save Sharing Configuration
Once your selections are made, click Share to apply.
Shared credentials will be visible and usable in the selected Sub-Organizations as if they were their own.
:::info
Sub-Organizations cannot edit or delete credentials shared by the Root Organization.
:::
The shared credentials by the Root Organization will be marked with Root Tag on the Sub Organization's credential list.
---
## Credentials
The "Credentials" section allows you to securely manage and store your API keys, and other sensitive information. Easily configure credentials for various integrations, ensuring secure and efficient access to essential services in your projects.
Current headlines and the actions you can complete are listed below:
- [**App Store Connect API Key**](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key)
- [**Google Play Service Account**](/account/my-organization/security/credentials/adding-google-play-service-account)
- [**Huawei AppGallery API Key**](/account/my-organization/security/credentials/adding-huawei-api-key)
- [**Microsoft Intune API Key**](/account/my-organization/security/credentials/adding-microsoft-intune-api-key)
In order to see the details, check the submenu of this documentation page.
---
## Domain Verification
Domain verification is a security process used to confirm ownership or control over a specific domain. It can currently be used to automatically verify user email addresses and accept pending invitations when users log in via SSO with an email that belongs to a verified domain. This is especially useful in cases where users don't have access to their email inbox or are unable to complete email-based verification.
Appcircle supports domain verification through DNS records, allowing you to confirm ownership of your domain by adding a specific DNS TXT record to your DNS provider.
:::info Identifying the Domain to Verify
You should verify the domain name of the SSO user’s email address.
For example, if the user's email is `user@example.com`, then you should verify `example.com`.
:::
:::info Advanced Information
When using Entra ID B2B users, the user's email may appear as:
`user_name_guestuserdomain.com#EXT#@yourdomain.onmicrosoft.com`
In this case, you should verify `yourdomain.onmicrosoft.com` in Microsoft's DNS settings.
:::
:::info
#### **Default Behavior & Configuration**
Domain verification is **enabled by default** and cannot be modified for **Appcircle Cloud** deployments.
For **self-hosted installations**, domain verification is **configurable**. By default, it is **disabled**, allowing domains to be added as trusted without requiring TXT DNS records. Organizations can modify this setting based on their security and compliance requirements.
For detailed configuration options, refer to the following pages:
- [Configuration on Docker/Podman Architecture](/self-hosted-appcircle/install-server/linux-package/configure-server/domain-verification)
- [Configuration on Kubernetes/OpenShift Architecture](/self-hosted-appcircle/install-server/helm-chart/configuration/domain-verification)
:::
### Steps to Verify a Domain
**1.** Navigate to the My Organization > Security > Domain Verification section.
**2.** Enter the domain name to be verified. The domain name must be in a valid format (e.g., example.com).
**3.** Copy the provided DNS record and add it to your DNS provider as a TXT record, using the specified name (host) and value (data).
**4.** Click Verify to check if the record has been propagated.
**5.** If the verification fails, retry after some time as DNS propagation may take time.
:::info
Appcircle will periodically check the DNS record to ensure it still exists and remains accurate.
Users must have administrative access to their domain’s DNS settings to complete verification.
Please note that unauthorized changes to DNS records may result in domain verification failure.
Each domain can be verified by multiple organizations, and also an organization can verify multiple domains.
:::
:::tip Verifying a Domain on Multiple Organizations
A unique hostname is provided by Appcircle for each organization and domain. As long as the correct DNS record is present in the DNS provider settings, the domain can be verified for multiple organizations.
:::
#### Validation Rules
- The domain name must be in a valid format (e.g., example.com).
- Special characters and improperly formatted domains will be rejected.
- If an invalid domain is entered, the verification process will not proceed.
:::info Email Notification
If a domain’s verification status changes — from verified to unverified or from unverified to verified — all organization owners will be notified via email.
:::
### Enabling Auto-Verify Option in SSO
After configuring domain verification, you can enable the Auto Verify feature in the SSO configuration settings. This feature allows to automatically verify user email addresses and accept pending invitations when users log in via SSO using an email address associated with a verified domain. This is particularly useful in cases where users do not have access to their email inbox or are unable to complete email-based verification.
Go to your SSO configuration and enable the **Auto Verify User Email for Verified Domains** option.
### Troubleshooting
- **DNS record value does not match expected value**: Ensure that the exact value provided by the system is entered in the DNS settings.
- **DNS propagation delay**: It may take up to 12-24 hours for the changes to take effect. Retry verification later.
- **Invalid domain format**: Ensure the domain is correctly formatted (e.g., example.com without protocols like http://).
- **Record already exists**: If an old verification record exists, remove it before adding the new one.
- **Invalid characters in domain name**: Avoid using special characters in domain entries.
---
## Appcircle Security
# Security
The "Security" section in Appcircle connects essential tools and services like Authentication, Authorization, Credentials Security. Securely manage API keys, control access, and receive timely alerts through Security with tools like Slack and email, ensuring a streamlined and secure workflow.
Current headlines and the actions you can complete are listed below:
- [**Authentication**](/account/my-organization/security/authentications)
- [**Authorization**](/account/my-organization/security/authorization)
- [**Credentials**](/account/my-organization/security/credentials)
- [**Domain Verification**](/account/my-organization/security/domain-verification)
- [**API Keys**](/account/my-organization/security/api-keys)
- [**Personal Access Key**](/account/my-organization/security/personal-access-key)
In order to see the details, check the submenu of this documentation page.
---
## Personal Access Key
A Personal Access Key is a secure credential used for obtaining a Personal Access Token (PAT) which is used for authentication when using Appcircle’s APIs. It inherits the permissions of your user account within the organization and is organization-specific—meaning you must generate a separate Personal Access Key for each organization you access.
:::warning Personal API Token Renamed
The **Personal Access Key** was previously referred to as the **Personal API Token**.
Only the name has changed, and all functionality remains the same.
:::
## Generating/Managing the Personal Access Keys
To generate a Personal Access Key, go to the [My Organization](/account/my-organization/profile-and-team/organization-management) screen in the Appcircle dashboard. After that, find the Security section from the left side menu. The Personal Access Key section is located on the bottom right.
Press the "Generate Key" button to generate your first key.
The key will then be generated and displayed above the button. Please make sure that you save the key before navigating away from the page as it will be displayed only once for security reasons.
If you want to delete a previously generated key, press "Delete Key" and confirm. You can then generate a new access key if you would like.
:::caution Personal Access Key for Sub-Organizations
To generate a Personal Access Key for a sub-organization, you must be added as a **member** of that sub-organization. Users **inherited** from a parent organization cannot generate a Personal Access Key. For additional details on [Organization](/account/my-organization/profile-and-team/organization-management#working-with-multiple-organizations) and [Team management](/account/my-organization/profile-and-team/team-management#managing-team-members), refer to the relevant documentation.
:::
:::info
Personal Access Keys are only accessible within the organization where they were generated. However, a Personal Access Key created in the Root organization can also be used for sub-organizations.
You can pass the `subOrganization` parameter when obtaining a Personal Access Token(PAT) using a Root Personal Access Key.
:::
```bash
curl -X 'POST' \
'https://auth.appcircle.io/auth/v3/token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'personalAccessKey=your_access_key' \
-d 'scope=openid,profile,email'
-d 'subOrganization={orgId}"
```
Please ensure that the endpoint you are using is v2.
:::warning Personal API Token Renamed
The Personal Access Key was previously referred to as the Personal API Token. The old endpoint is still available, but it is recommended to migrate to the new version.
For reference, the old endpoint was:
```bash
curl -X 'POST' \
'https://auth.appcircle.io/auth/v2/token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'pat=$pat' \
-d 'scope=openid,profile,email'
-d 'subOrganization={orgId}"
```
:::
---
## API Authentication
The Appcircle API supports authentication with a _Personal Access Key_. The key for each user will have the same permissions with the user within the organization and each organization require a separate Personal Access Key.
Alternatively, the Appcircle API also supports authentication with an _API Key_. API Keys are typically used for service-to-service or automation scenarios where the authentication is not tied to an individual user. Each API Key is associated with an organization and can be managed from the organization's security settings.
:::tip Generating Personal Access Key and API Key
You can generate your Personal Access Key or API Key within the security section of the Organization module.
- For detailed information on Personal Access Keys, please refer to [Personal Access Key](/account/my-organization/security/personal-access-key) documentation.
- For API Keys, please refer to [API Keys](/account/my-organization/security/api-keys) documentation.
:::
### Using the Personal Access Key for API Authentication
For authentication, you need to [generate a Personal Access Token(PAT) from the Auth API using the Personal Acccess Key](https://api.appcircle.io/openapi/index.html?urls.primaryName=auth) and add the generated PAT along with an `Authorization` header in all API requests.
A curl-based API call sample is as follows:
First generate a PAT using the Auth API with the Personal Access Key specified as "your_access_key":
```bash
curl -X POST "https://auth.appcircle.io/auth/v3/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "personalAccessKey=your_access_key"
```
Then use the generated token specified as "Auth-Token-Goes-Here":
```bash
curl -X GET "https://api.appcircle.io/distribution/v2/profiles" -H "accept: application/json" -H "Authorization: Auth-Token-Goes-Here"
```
:::warning Personal API Token Renamed
The Personal Access Key was previously referred to as the Personal API Token. The old endpoint is still available, but it is recommended to migrate to the new version.
For reference, the old endpoint was:
```bash
curl -X POST "https://auth.appcircle.io/auth/v1/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "pat=Personal-API-Token""
```
:::
### API Documentation
Access the full API documentation and explore the endpoints available for your integration needs at:
https://api.appcircle.io/openapi/index.html
---
## App Center Migration Tool
The appcenter-migration-tool is designed to assist organizations and individuals to migrate their Visual Studio App Center projects with organizations, collaborators, app profiles as testing distribution profile and test groups to Appcircle effortlessly.
By using the **appcenter-migration-tool**, you can ensure a smooth and efficient migration process, minimizing downtime and preserving the integrity of your data.
**Key Features**:
- **Organization Migration:** Effortlessly transfer your entire App Center organization structure to Appcircle.
- **Collaborator Migration:** Move all your App Center collaborators to Appcircle with their roles and permissions intact.
- **Test Group Migration:** Transition your test groups from App Center to Appcircle with all their associated configurations and data.
## How to Install the Tool
**Node.js must be installed on your machine. Version v18.19.0 is recommended.**
To install the appcenter-migration-tool globally, simply run the following npm command:
```bash
npm install -g @appcircle/appcenter-migration-tool
```
Alternatively, you can install it locally:
```bash
npm install @appcircle/appcenter-migration-tool
```
https://www.npmjs.com/package/@appcircle/appcenter-migration-tool
## Migrating from App Center to Appcircle Automatically
Migrating your data in App Center manually can be a time-consuming and error-prone process. The **appcenter-migration-tool** automates this task, allowing you to efficiently and accurately transfer the data you need with minimal effort.
## App Center API Token
When creating a new API token for the migration tool from App Center, granting **Full Access** permission is recommended.
## Using the Tool for Migration
The CLI tool offers the following main commands to login to App Center and migrate the respective entities: **Login**, **Organizations**, **App Center Apps** and **App Center Distribution Groups**.
### Login Command
Use the Login command to authenticate with App Center and Appcircle using your token.
| Login Subcommands | Command Name | Command Options | Explanation |
| ------------------ | ------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| App Center Account | appcenter | appcenterToken | Use your App Center token to authenticate and authorize access. |
| Appcircle Account | appcircle | appcircleToken | Use your Appcircle [Personal Access Key](/account/my-organization/security/personal-access-key) to authenticate and authorize access. |
To run the command directly instead of starting an interactive session, simply execute the command as shown below:
```bash
appcenter-migration-tool login appcircle --appcircleToken=YOUR_TOKEN
```
### Organizations Command
Use the Organizations command to list and migrate your App Center organizations to Appcircle.
| Organizations Subcommands | Command Name | Command Options | Explanation |
| --------------------------------------------- | ---------------------------- | -------------------------------------------------------- | ---------------------------------------------- |
| List App Center Organizations | list-appcenter-organizations | - | List App Center Organizations. |
| Migrate App Center Organization to Appcircle | migrate | organizationNames | Migrate App Center Organization to Appcircle. |
| Migrate App Center Organization Collaborators | migrate-collaborators | organizationName organizationUsers appcircleOrganization | Migrate App Center organization collaborators. |
To run the command directly instead of starting an interactive session, simply execute the command as shown below:
```bash
appcenter-migration-tool organizations list-appcenter-organizations
```
### App Center Apps Command
Use the App Center Apps command to list and migrate your App Center apps to Appcircle.
| Apps Subcommands | Command Name | Command Options | Explanation |
| ---------------------------------------------------------------- | ----------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| List All App Center Apps | list | - | List All App Center Apps. |
| Migrate App Center App to Appcircle Testing Distribution Profile | list-organization | organizationName | List App Center Apps Based on App Center Organization |
| Migrate App Center App to Appcircle Testing Distribution Profile | migrate-profile | profileName | Migrate App Center App to Appcircle [Testing Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile) |
To run the command directly instead of starting an interactive session, simply execute the command as shown below:
```bash
appcenter-migration-tool apps list
```
:::caution
migrate-profile command only creates an empty **Testing Distribution Profile** with the same app name in Appcircle. Build details are not included in migration for this version.
:::
### App Center Distribution Groups Command
Use the App Center Distribution Groups command to list and migrate your App Center distribution groups to Appcircle.
| Apps Subcommands | Command Name | Command Options | Explanation |
| --------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| List available distribution groups in App Center | list-organization | organizationName | List available distribution groups in App Center for a given organization. |
| List App Center App Distribution Groups | list-app | organizationName appName | List App Center Apps Based on App Center Organization |
| Migrate Distribution Groups from App Center Organization to Appcircle | migrate-organization | organizationName distributionGroupName distGroupUsers | Migrate Distribution Groups from App Center Organization to Appcircle |
| Migrate App Center App Distribution Group to Appcircle | migrate-app | organizationName appName distributionGroupNameForApp distGroupUsersForApp | Migrate App Center App Distribution Group to Appcircle |
To run the command directly instead of starting an interactive session, simply execute the command as shown below:
```bash
appcenter-migration-tool distribution-groups list-organization --organizationName=YOUR_ORGANIZATION_NAME
```
## Example: Migrating an App Center Organization to Appcircle
In this section, we will provide a comprehensive overview of the migration process from App Center to Appcircle. App Center and Appcircle manage organizations and distribution groups in slightly different manner. The following diagram illustrates a sample organization structure in both App Center and Appcircle.
**Organization Hierarchy for Migration:**
App Center organization hierarchy slated for migration is structured as follows:
Migrated Appcircle organization is structured as follows:
**Step-by-Step Migration Process:**
1. **Migrating Organizations:**
- Migrate the organizations from App Center to Appcircle.
- Appcircle uses a main-sub organization structure, meaning every organization you migrate will become part of a main organization.
2. **Migrating Apps:**
- Create a Testing Distribution Profile in Appcircle for each app from App Center.
- This process currently includes only the creation of the profile; migration of build configuration details is not supported yet.
3. **Migrating Distribution Groups:**
- Migrate Distribution Groups from App Center to Appcircle.
- App Center allows users to manage distribution groups at both the organization level and the app level.
- In Appcircle, distribution groups are managed exclusively at the organization level.
### Migrate Organization
The appcenter-migration-tool migrates organizations to Appcircle as sub-organizations under a main organization. This means each migrated organization will be nested under a primary organization. During this migration, the tool will only create organizations that match those existing in App Center. If an organization with the same name already exists in Appcircle, the tool will provide an error.
```bash
appcenter-migration-tool organizations migrate-collaborators --organizationUsers=guven@appcircle.io --appcircleOrganization=Appcircle_Organization
```
### Migrate Organization Collaborators
The tool invites specified collaborators from App Center to the corresponding organization in Appcircle. As a major difference from App Center, Appcircle offers comprehensive [role management](/account/my-organization/profile-and-team/role-management) based on modules. During the invitation process, the roles of the collaborators from App Center are mapped to the Distribution Profile Roles and Testing Group Roles modules in Appcircle as follows:
| App Center Role | Appcircle Role | Module |
| --------------- | -------------- | ------------------------------------------------ |
| Admin | Manager | Distribution Profile Roles & Testing Group Roles |
| Collaborator | Operator | Distribution Profile Roles & Testing Group Roles |
| Member | Viewer | Distribution Profile Roles & Testing Group Roles |
```bash
appcenter-migration-tool organizations migrate --organizationNames=Appcircle_Organization
```
### Migrate App Center Apps to a Testing Distribution Profile at Appcircle
The tool creates a [Testing Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile) in Appcircle using the specified App Center app name.
```bash
appcenter-migration-tool apps migrate-profile --profileNames=Appcircle
```
:::caution
The tool creates only a new [Testing Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile) and does not migrate any existing releases at this time.
:::
### Migrate Organization Distribution Groups
The tool migrates **distribution groups** of the organizations from App Center organizations to **testing groups** in Appcircle.
```bash
appcenter-migration-tool migrate-organization --organizationName=Appcircle_Organization --distributionGroupName=Internal --distGroupUsers=guven@appcircle.io
```
### Migrate App Distribution groups
The tool migrates **distribution groups** of the apps from App Center app to **testing groups** in Appcircle.
```bash
appcenter-migration-tool migrate-organization --organizationName=Appcircle_Organization --appName=Appcircle-iOS --distributionGroupNameForApp="Beta Testers" --distGroupUsersForApp=guven@appcircle.io
```
:::info
In App Center, distribution groups can be managed at both the organization level and the app level. In contrast, Appcircle consolidates all testing groups into a single management location.
:::
## How to Upgrade the Tool
If you installed appcenter-migration-tool globally, simply run the following npm command:
```bash
npm update -g @appcircle/appcenter-migration-tool
```
or if you installed locally, you can run the following npm command:
```bash
npm update @appcircle/appcenter-migration-tool
```
## How to Uninstall the Tool
If you installed appcenter-migration-tool globally, simply run the following npm command:
```bash
npm uninstall -g @appcircle/appcenter-migration-tool
```
or if you installed locally, you can run the following npm command:
```bash
npm uninstall @appcircle/appcenter-migration-tool
```
---
## CLI Authentication
### Appcircle CLI
Appcircle CLI is a unified command-line tool that provides access to Appcircle platform features, enabling you to manage your projects, builds, and more directly from your terminal.
You can install the Appcircle CLI from npm:
```bash
npm install -g @appcircle/cli
```
or yarn:
```bash
yarn global add @appcircle/cli
```
https://www.npmjs.com/package/@appcircle/cli
You can find more information and the open source code of the CLI on GitHub as follows:
https://github.com/appcircleio/appcircle-cli
### Authentication Methods
The Appcircle CLI supports two authentication methods:
1. **Personal Access Key** - Recommended for individual users
2. **API Key** - Suitable for organization-level access
### Login with Personal Access Key
Personal Access Keys provide a secure way to authenticate with Appcircle CLI without exposing your account credentials.
To authenticate using a Personal Access Key:
```bash
appcircle login personal-access-key --secret "your-personal-access-key-here"
```
:::tip
For generating Personal Access Key, please refer to [Personal Access Key](/account/my-organization/security/personal-access-key) documentation.
:::
:::warning Personal API Token Renamed
The Personal Access Key was previously referred to as the Personal API Token. The old login method is still available, but it is recommended to migrate to the new version.
For reference, the old login method was:
```bash
appcircle login pat --token "your-personal-access-token-here"
```
:::
### Login with API Key
API Keys provide organization-level authentication, ideal for automated systems and shared environments. Unlike PATs tied to individual users, API Keys belong to the organization and remain valid regardless of user account changes.
To authenticate using an API Key:
```bash
appcircle login api-key --name "my-api-key" --secret "my-secret"
```
For organization-specific access, you can also specify the organization ID:
```bash
appcircle login api-key --name "my-api-key" --secret "my-secret" --organization-id "org-123"
```
:::tip
For creating and managing API keys, please refer to [API Keys](/account/my-organization/security/api-keys).
:::
### Logout
To securely log out and clear your stored authentication credentials from the CLI, please use following command:
```bash
appcircle logout
```
:::info
The `logout` command clears your stored authentication token locally. This is a local operation that doesn't make any API calls to the server.
:::
### Authentication Behavior
The Appcircle CLI maintains a single active session and prevents multiple concurrent logins to ensure security and avoid credential conflicts.
- If you're already logged in and try to login again, you'll see a "You are already logged in" message
- You must logout first before logging in with different credentials
- If you try to logout when you're not logged in, you'll see a "You are not logged in" message
### Interactive Mode
In interactive mode (`appcircle -i`), authentication options are grouped under "Authentication (Login/Logout)" menu:
1. Select "Authentication (Login/Logout)" from the main menu
2. Choose "Login" or "Logout" from the submenu
- When choosing **Login**, you can authenticate using:
- **API Key**
- **Personal Access Token (PAT)**
### Environment Variable
After successful authentication, the CLI stores your access token locally. You can also manually set the `AC_ACCESS_TOKEN` or `AC_API_KEY_TOKEN` environment variable if needed for other tools or scripts.
---
## Introduction to Appcircle API and CLI
The Appcircle API and CLI are essential tools for accessing and managing the Appcircle platform's features, facilitating automation and integration in your mobile app development workflows.
## [Appcircle API](/appcircle-api-and-cli/api-authentication)
The Appcircle API offers programmatic access to all features available in the Appcircle platform, allowing developers to automate workflows, integrate with other tools, and customize their development processes extensively.
## [Appcircle CLI](/appcircle-api-and-cli/cli-authentication)
Appcircle CLI is a unified command-line tool that provides access to Appcircle platform features, enabling you to manage your projects, builds, and more directly from your terminal.
## [App Center Migration Tool](/appcircle-api-and-cli/appcenter-migration-tool)
The App Center Migration Tool is designed to assist organizations and individuals to migrate their Visual Studio App Center projects with organizations, collaborators, app profiles and test groups to Appcircle effortlessly.
---
## Building Multiple Apps in One Profile
Depending on the structure of your project(s), at one point there might be a need to produce more than one application from a single codebase.
For this situation, there are two ways to accomplish this goal:
- Configure your relevant file to produce different outputs.
- Android -> Build Variants with Product Flavors
- For iOS -> Creating different Targets with Schemes
- Do the steps manually via custom scripts.
:::info
For this task, the developer should configure those from Android Studio or Xcode.
:::
> A different Application means a different packagename for Android and different bundleId for iOS.
### Using Android Product Flavors and Build Variant to Configure Multiple Apps
The Android Developers document has a detailed guide on how to configure build variants and product flavors:
https://developer.android.com/studio/build/build-variants
The assets that you can directly change with the `productFlavor`
- Package Id -> packageName
- App Name
- App Icon
For more information, check the Android Developer Document on `productFlavor`
https://developer.android.com/reference/tools/gradle-api/4.2/com/android/build/api/dsl/ProductFlavor
#### How to Change Variant Programmatically on Appcircle
:::info
This method will not be required in common scenarios. Unless you have a special case, it is advised to stick with configuring `build.gradle` instead, as specified at the Android Developers document.
:::
For example, the script below will change the variant if the built branch is `release` .
:::tip
Put this script before the relevant **build **step. E.g. for Android, this script should be executed **before **`Android Build` step.
:::
Note: This script is in `Bash` language.
```bash
if [ $AC_GIT_BRANCH = 'release' ]; then
echo "AC_VARIANTS=YOUR_FLAVOR" >> $AC_ENV_FILE_PATH
fi
```
For more information about environment variables, [click here](/environment-variables/appcircle-specific-environment-variables#reserved-android-variables).
### Using iOS Schemes to Configure Multiple Apps
Creating and controlling multiple Schemes on an Xcode project is fairly easy. Check the [Apple Help Documentation](https://help.apple.com/xcode/mac/current/#/dev0bee46f46) about how to create & manage schemes.
The assets that you can directly change with the Schemes
- Bundle ID
- Plist file
- App Icon
For more information about iOS Multiple Targets, navigate to the [Apple Help Documentation](https://help.apple.com/xcode/mac/current/#/dev38419576c)
###
#### How to Change Target Programmatically on Appcircle
:::info
This method will not be required in common scenarios. Unless you have a special case, it is advised to configure multiple `plist` files and bundling them into a single scheme.
:::
For example, the script below will change the scheme if the built branch is `release` .
:::tip
Put this script before the relevant **build **step. E.g. for Android, this script should be executed **before **`Android Build` step.
:::
Note: This script is in `Bash` language.
```bash
if [ $AC_GIT_BRANCH = 'release' ]; then
echo "AC_SCHEME=YOUR_FLAVOR" >> $AC_ENV_FILE_PATH
fi
```
For more information about environment variables, [click here](/environment-variables/appcircle-specific-environment-variables#reserved-ios-variables)
### Testing & Downloading Multiple Apps Through Appcircle
As specified in the Appcircle docs, your multiple outputs will be located on the testing distribution and they will be available for download just like a single application.
[Multiple Flavors](/testing-distribution/create-or-select-a-distribution-profile#android-applications-with-multiple-flavors)
---
## Best Practices
Enhance your experience with Appcircle by following our recommended best practices for app development and deployment.
## [Building Multiple Apps in One Profile](/best-practices/building-multiple-apps-in-one-profile)
Learn how to configure a single Appcircle profile to build multiple apps efficiently. This guide will help you set up your projects to streamline the build process across different applications.
## [Appcircle Onboarding](/best-practices/onboarding)
Get started with Appcircle the right way by following our onboarding best practices. This section provides tips and steps to ensure you make the most of Appcircle from the beginning.
Adopting these best practices will not only save you time but also improve the consistency and quality of your app development workflow.
---
## Appcircle Onboarding
To add your iOS or Android project to Appcircle, you must complete the following checklist, divided into sub-sections.
# Prerequisite
Before building the project on Appcircle, ensure it builds properly on your local computer. Developers often do not commit changes, or their changes may not end up in the repo due to the `.gitignore` file. Follow these steps to ensure that the project builds without errors:
- Clone the repo to another folder.
- If it's an iOS project using Cocoapods or Carthage, run pod install or carthage bootstrap.
- Build the project.
If you encounter any errors, correct them and push the changes to your repo. Appcircle always starts a machine from scratch, so it must have access to all files required to build your project.
For detailed information on how Appcircle configures its build machines and manages dependencies, refer to our Infrastructure Documentation. This guide will help you understand the environments in which your applications are built, ensuring you have all necessary files and settings in place
Infrastructure
Once your project builds without error, complete the following sections:
1. Repository
2. Dependencies
3. Signing
4. Integrations
5. Extra suggestions
# Repository
## Firewall
- **Internal Networks:** If your repositories are hosted internally, you must configure firewall settings to allow the runners to clone them. This setup is essential to prevent access issues during the build process.
Accessing Repositories in Internal Networks (Firewalls)
- **External Hosts (e.g., GitHub.com):** If your repositories are hosted on external platforms like GitHub, no additional firewall configuration is necessary.
## Repository Owner
The person adding the repository to Appcircle must own the repository. If the owner has too many repositories, consider creating a bot user specifically for Appcircle to access only the required repositories.
## Repository Type
### Cloud
Access to repositories on GitHub and GitLab is managed by installing an app to the repository. The user who adds the repo must have the necessary access to install the application.
### Self Hosted
If your repository is Self Hosted with GitLab or Bitbucket, add your repo using an Access Token.
**Azure DevOps**
Azure DevOps requires a Personal Access Token to access the repository. The token must have access to the necessary repositories.
Connecting to Azure DevOps
**GitLab**
Generate a Personal Access Token or Project Access Token for GitLab. A Personal Access Token allows access to all the repositories of that person. A Project Access Token allows access to all the repositories under the specified project.
Connecting to GitLab
**Bitbucket**
Bitbucket also supports using repository tokens to access a single repository.
Personal Access Token allows to access all the repositories of that person. Project Access Token allows to access all the repositories under the specified project.
Connecting to Bitbucket
Appcircle requires admin permission to function properly, which is necessary to create relevant WebHooks automatically.
:::note
If dependencies used by the repo are in a different project or inaccessible to the person, the build will throw an error. Therefore, the added token must have access to all necessary dependencies.
:::
## Dependencies
If you use libraries in a private repo, these must be accessible with the tokens mentioned above. If this is not possible, access these libraries using one of the following methods:
- SSH Private Key
- .netrc file
### SSH Private Key
Create a new SSH key, upload the public key to your Repo, and the private key to Appcircle. Follow the steps in this guide.
Connecting to Private Repository via SSH
### Netrc File
The .netrc file contains login and initialization information used by the auto-login process. You can use this component to add credentials for hosts such as your repositories or external hosts. Git automatically recognizes the .netrc file.\
Authenticate with .netrc
## Signing
To upload artifacts to the App Store or GooglePlay, the files must be signed. Upload the following files to Appcircle's Signing Module:
### iOS
There are two types of signing for iOS, Manual and Automatic.
Manual Signing requires you to upload the provisioning profile for each bundle id. For Automatic code signing, only 2 certificates and App Store Connect Key must be added.
**Manual Signing:**
- Upload the Distribution Certificate as a `.p12` file. It is better to create a new distribution certificate specifically for Appcircle.
- Upload Provisioning profiles created with the above certificates. A green checkmark will appear next to the entry if successful. If not, refresh the page or check for missing certificate files.
**Automatic Sign**
Automatic signing works with Xcode 13 and later. It requires:
- One Distribution Certificate
- One Development Certificate
- App Store Connect API Key
Provide both development and distribution certificates to prevent Xcode from continuously creating new certificates in your account.
### Android
For Android, upload the keystore file used to sign the project. Simply uploading this file may not suffice for signing; adjustments to the `build.gradle` file might also be necessary. Consult this document for further guidance.
Android Signing for Google Play
## Integrations
Add App Store, Google Play, or Huawei AppGallery keys to Appcircle to upload IPA or APK-AAB files. Follow these guides for detailed instructions:
Send to App Store
Send to Google Play
Send to Huawei
## Extra suggestions
**General**
- Manage confidential or frequently changing information with Environment Variables to achieve different outputs by selecting different variable groups without altering your code.
Creating Environment Variable Groups
Using Different Values for Different Stages
Using Environment Variables in Android Projects
- Specify versions for React Native and Flutter on the config screen to avoid building with the latest version by default.
- Disable Flipper in React Native to shorten build times by modifying the Podfile as follows:
```
if !ENV['AC_APPCIRCLE']
use_flipper!
post_install do |installer|
flipper_post_install(installer)
end
end
```
**iOS**
- If you are using CocoaPods, SwiftPM or Carthage, you need to commit `Podfile.lock` `Package.resolved` and `Cartfile.resolved` files. When these files are not available, the wrong versions may be installed.
- Avoid making local changes to your pods. If necessary, fork the original pod and make changes in that fork. Appcircle must have access to the same code as your local machine.
**Android**
- Include your Gradle folder in your repo. Appcircle uses the `./gradlew` command to build your project. If this file is missing, the build will fail.
- Update your build.gradle file to replace `jcenter()` with `mavenCentral()` if your project uses Bintray resources, as JFrog shut down Bintray on May 1, 2021. Some dependencies may not be available on Maven.
- Consider uploading dependencies used from jitpack to `mavenCentral()`. Jitpack has reliability issues, and while your local builds may use cached versions, Appcircle downloads your dependencies for each build, which can lead to problems.
---
## Build Activity Log
You can view Build module actions such as creating, deleting, and adding Build profiles or updating configurations performed on Build profiles in your Organization or Sub-Organizations in the Build Activity Log section.
Here is the full list of actions that can be monitored:
* Build Profile Created
* Build Profile Deleted
* Build Profile Updated
* Build Profile Pinned
* Build Profile UnPinned
* Build Profile Renamed
* Build Profile Connection Revoked
* Configuration Created
* Configuration Updated
* Configuration Cloned
* Configuration Renamed
* Configuration Deleted
* Configuration Uploaded
* Workflow Created
* Workflow Uploaded
* Workflow Updated
* Workflow Renamed
* Workflow Deleted
* Build Trigger Updated
* Connection Revoked
* Connection Established
* New Git Connection Added
* Git Connection Renewed
* New Git Connection Removed
* Git PAT Connection Changed
* Git PAT Connection Removed
* New git PAT conenction Added
* Repository Connected
* Repository Disconnected
* Repository Refreshed
* Repository Owner Changed
* Env Group Created
* Env Group Renamed
* Env Group Cloned
* Env Group Deleted
* Env Group Variable(s) Added
* Env Group Variable(s) Removed
* Env Group Variable(s) Updated
:::info
Organization Owners can also observe the actions of their Sub-Organizations unless the search filter is specifically set for the root organization.
:::
You can edit the required date range by clicking the time filter in the top filter header as the default search time option is the last 30 days. Alternatively, you can choose custom dates from the calendar by selecting 'In Between' option.
Team activity logs also include filters to help users perform more precise searches.
Another method to search is by **Actions**. Simply click the filter option and select **Actions**. Then you can choose a specific action to refine your search.
---
## Overview
# Overview of Environment Variables
### Creating environment variable groups
To create an environment variable group, select Environment Variables from the build module. Click on the orange + icon and enter the name of the group into the input box, press enter to save the group name and create the group.
### Adding key and text-based value pairs
To add an environment variable to the group, select the "Text" tab from the top and use the inputs below. Enter a key name, then enter the value for the key and press enter.
You can add as many environment variables as you need.
:::info
Variables that need to be secret can be hidden using the lock icon. Such variables cannot be viewed by the users during the build process.
:::
Please note that some environment variables may need to be duplicated to be used in different groups for different purposes.
### Adding files as environment variables
You can also add files as environment variables and use them in build workflows in the same way. They can be used for things like API-key based authentication in Firebase or for adding dSYM files.
To add a file, select the "File" tab from the top and enter a key name from the inputs below. Then select a file from the file browser that opens when you click the file field.
Then press add to upload the file.
:::info
When you upload a file as an environment variable, file name is not preserved. The reason of this to prevent file name conflicts. You can upload different files with same name and can use their keys to refer them. You need to use your key to find the location of this file and then you can read the contents of this file.
:::
### Downloading environment variables
You can download and view environment variables in **JSON** format. For this, you can use the "Download" button by clicking on the three dots next to one of the variable groups under "Build > Environment Variables > Variable Groups".
In the downloaded file content, you will see a structure with **key-value** pairs.
In addition, if the value part of the environment variable is set to hidden during the text-based environment variable addition process, the "isSecret" value will be `true` and the key, along with the value **will not** be listed in the downloaded file. The same rule is valid for file type variables. If it is not hidden, this value will be `false`, and the value will be visible.
:::info
An example of environment variable downloaded as a JSON file:
```json
[
{
"key": "API_URL",
"value": "https://api.example.com",
"isSecret": false,
"isFile": false,
"id": "API_URL"
}
]
```
As seen in the example above;
- if the **isSecret** value is `false`, it has visible value
- if the **isSecret** value is `true` or **isFile** value is `true` , the key and the value will not be downloaded.
:::
### Uploading environment variables
The Upload feature allows users to bulk-import environment variables into any existing Variable Group (e.g., Staging, Prod, or Dev) within the Build > Environment Variables section.
This feature streamlines the process of configuring variables by enabling users to upload a predefined JSON file instead of manually entering each variable.
The uploadable file must be a `.json` file with an array of variable objects. Each variable object must include the following fields:
```json
[
{
"key": "API_URL",
"value": "https://api.example.com",
"isSecret": false,
"isFile": false,
"id": "API_URL"
},
{
"key": "API_KEY",
"value": "12345-abcde-67890-fghij",
"isSecret": true,
"isFile": false,
"id": "API_KEY"
}
]
```
:::warning
- File type variables (isFile: `true`) cannot be uploaded using JSON. These must be added manually via the UI.
- The Download feature does not include secret values or file contents for security reasons.
- You can edit your own JSON files to update variables in a group. However, duplicated keys are not allowed.
:::
#### Using environment variable groups in builds
Environment variable groups can be used in builds to extend the workflow and add additional actions to workflow steps.
To add an environment variable group to a build, go to the build profile from the build module and select _Build Configuration > Env. Variables_
Here, you can see a list of previously created environment variable groups. Select the groups you want to be included in this specific build profile. Then click Save to save your selection.
Then in workflows, you can specify the environment variable for use.
#### Creating environment variables on the fly
If you want to create environment variables on the fly, you should write those environment variables to a special file called `AC_ENV_FILE_PATH`. For example, if we want to create a build number based on a timestamp and use it in the next steps we can use the following custom script.
```bash
echo "BUILD_NUMBER=$(date +%s)" >> $AC_ENV_FILE_PATH
```
Any step after this custom script can access the `$BUILD_NUMBER` environment variable.
#### Using Environment Variables For SSH And PAT (Personal Access Token) Connections of the Git Provider
You can use personal access tokens or SSH private keys from the environment variables according to your needs by defining them once.
So you can add environment variables and use them in multiple projects. Also, this usage allows you to update all your projects at once when there is a change to the SSH private key, or PAT.
:::info
You can create an environment variable and enter the key value for the Personal Access Token.
:::
:::info
If you are going to use an SSH private key, you need to upload it as a file.
:::
:::caution
There are two use cases for the variable group naming here.
If the variable group nomenclature contains space, the usage will be as follows:
```txt
$"Variable Group:Key"
```
If the variable group nomenclature does not contain any space, it will be used like this:
```txt
$VariableGroup:Key
```
:::
:::caution
If your SSH public key is not defined on the Git provider, Appcircle will not be able to connect to your repository. First, you will need to add your public key to the Git provider.
:::
Connecting to Repository via SSH
For platform specific environment variables and more detailed information, please refer to the related [documentation](/environment-variables/platform-specific-usage).
---
## Build History
This report is accessible from the Build module.
The Build History Report contains the list of build sessions initiated in a given time period.
Each build session is defined as an initiated manual or automatic build for a commit under a branch of a build profile.
The duration indicates the minutes spent by the build agent for the specified build operation. This value only includes the actual duration that the agent was active, including the agent boot duration but excluding the queue wait duration.
The date and time are displayed in the current timezone.
You can filter the report pages according to the organization.
:::info
In the filtering options, you can only view and select the organization and sub-organization you belong to.
:::
---
## Binary Actions
With Appcircle's post-build actions, you can easily distribute your binary file manually, access artifacts, and examine build logs.
## Distribute Binary
The Distribute Binary feature sends the binary file to the relevant module based on the distribution settings in the selected configuration.
:::caution
Please note that AAB files will not be distributed automatically since they cannot be installed on mobile devices directly.
:::
## View Build Logs
This feature allows the relevant build logs to be reviewed in the Appcircle log window. The logs can be examined step by step separately.
## Download Artifacts
Each time a build is completed by Appcircle, all artifacts produced after the build are stored for easy access. These files, which include artifacts such as IPA, APK, and AAB binary files, log files, and archive files, can be accessed by selecting Download Artifacts.
:::caution Output Artifacts
#### For Android
If your Android application has multiple product flavors, Appcircle will create a build for each flavor of your application and let you distribute them at once. A common usage of multi-flavor applications can be free and paid versions of the same application.
When you build and distribute an application with multiple flavors, and `.apk` file will be created for each flavor. On our [**testing portal**](/testing-distribution/testing-portal), your testers will be able to download each `.apk` file separately and test it on their devices.
#### For iOS
iOS applications can be downloaded or distributed as IPA file format if you configure signing identities and sign the application during the build process.
If you disable signing or don't use any signing identities, iOS output will be a `.xarchive` file.
:::
## Download Build Logs
In addition to allowing the review of logs, Appcircle also permits the downloading of these logs in .txt file format, enabling the logs to be downloaded and used in a single file.
#### Working with build logs
Build logs help you to observe and understand exactly what happened during a build. You can see build logs as they happen while a build is in process, or you can view logs of a build after the build is completed.
:::info
In the build logs, the **Builds/Statuses** column is sorted by the latest completion build date. As a result, the start dates displayed in the list might not be in chronological order:
:::
You can use build logs to debug your builds in case you get any errors. Additional parameters and flags can also be used in workflow steps to see more details in build logs.
What are Workflows and How to Use Them?
You can also download build logs in plain text format in case you would like to investigate them on your own or share with your team.
#### Delete Specific Builds
If you want to free up space from your Artifact Storage, you can delete older build profiles that are cluttering your space.
To do that, simply navigate to the Builds tab and select the builds, then click on the Delete icon.
:::info
The build deletion feature is only available for organizations with an enterprise license.
:::
## FAQ
### Artifact Storage is Full
Older builds and/or testing distributions will use almost all of your storage. If your artifact storage is full, you can free up some of the old artifacts.
#### [Refer here to delete specific builds from your build profile](/build/build-process-management/binary-actions#delete-specific-builds)
#### [Refer here to delete testing distribution profiles and specific distribution artifacts](/testing-distribution/create-or-select-a-distribution-profile#delete-a-distribution-profile)
#### [Refer here to delete a Publish Profile](/publish-to-stores-module/creating-publish-profiles/managing-publish-profiles#delete-publish-profile)
In order for storage to be freed up, you should also remove the other references pointing to the artifact. For example, if you have built an app, distributed it to testers, and submitted it to the Store Submit, you should delete that build from Testing Distribution, Store Submit, and Builds, respectively.
:::caution
It may take a couple of minutes to see the change in your account after you have deleted some artifacts.
:::
---
## Triggers
There are multiple ways to trigger a build in Appcircle. You can run builds manually or automate the build process with various triggers.
## Triggers for Manual Builds
For the manual builds, the currently available push triggers apply, and if no trigger is configured, the following trigger is provided by default under the [push triggers](#auto-build-on-every-push). If there are others, they may take precedence based on the [trigger priorities](#trigger-priorities).
## Triggers Configuration
To set up or manage the build triggers, click the Triggers button in the context menu of the build profile, accessible from the top of the profile details.
The triggers are set up at the profile level, and you can specify individual branch names or [utilize wildcards](/build/build-process-management/build-manually-or-with-triggers#wildcard-reference) for branch names to trigger builds.
You also need to select a workflow for each trigger, and the build will be run with that trigger for the specified branch. You can build the same branch with different workflows (e.g., production or development), or you can use the same workflow for multiple branches (e.g., multiple feature branches built with the develop workflow).
## Automatic Build
Builds can be triggered with various triggers such as every push to the repository, pull/merge requests, or tagged pushes. This requires the following:
- Webhook connection to the repository
- Setting up build triggers
There are two options to set up webhooks for automatic builds:
- You can [authorize the Appcircle app](/build/manage-the-connections/connection-guides) for GitHub, Bitbucket, or GitLab repositories for direct integration. The triggers will be available for use immediately. (You can skip the next part about the webhook setup.)
- For the repository connections through SSH, you can add the specific webhook for that build profile manually to the compatible git provider. This enables the Git provider to send a POST request to Appcircle for the selected events, which you can then use for triggers.
## Setting up Manual Webhooks Based on Repository Connection Type
Depending on how your Git provider is connected to Appcircle, the webhook setup may be handled automatically or may require manual configuration.
### Setting Up Manual Webhooks for SSH and Public Repositories
For repositories connected through SSH, you can set up triggers with webhooks in compatible repository providers.
When you connect a repository through SSH or through a public URL, the Webhook URL option will be enabled in the context menu of the build profile, accessible from the top of the profile details.
You can copy this URL and paste it in the related section in the git provider repository settings with the copy button.
To manually configure a webhook:
**1.** Go to your build profile.
**2.** Click the Webhook icon and select Repository Webhook URL.
**3.** In the Repository Webhook URL popup:
- **Select a Git Provider**:
If the Git provider is detected, a compatible URL will be displayed automatically. If not, choose your Git provider (e.g., GitHub, GitLab, Bitbucket) from the dropdown list.
- **Copy the Webhook URL**:
The generated Repository Webhook URL will appear based on your Git Provider. Copy this URL and paste it into your repository’s webhook settings.
The URL Format:
```bash
https://api.appcircle.io/build/v1/callback/hooks/{GIT_PROVIDER}/{YOUR_ORGANIZATION_ID}/custom/{INTEGRATION_ID}/V
```
- **Generate a Webhook Key**:
You can generate a new webhook key/secret to refresh or reset the endpoint’s security token.
**4.** Paste the Webhook URL in your Git repository.
:::info
**The Selected Git Provider** option on the **Webhook Configuration** screen is only available for repositories connected via **SSH** or **Public URL**.
If your repository is connected using GitHub, GitLab, Bitbucket or Azure Devops App integrations, this selection will not appear since webhooks are automatically managed.
:::
:::caution Azure Devops Connections
Azure Devops has slightly different steps to configure a manual webhook.
To manually configure a webhook for an Azure DevOps repository:
1. Connect your Azure DevOps repository to Appcircle and create a build profile.
2. In Azure DevOps, navigate to:
`Project Settings → Service Hooks → + Create Subscription`
3. Choose Web Hooks as the service.
4. Select your repository and choose the required trigger events (e.g., code push, pull request).
5. In the “Action” step, paste the webhook URL.
6. “Accept untrusted SSL certificates“ option can stay disabled.
7. Enter `appcircle` as username.
8. Paste `{YOUR_WEBHOOK_SECRET}` as password.
:::
#### Binding Existing Manual Webhooks to Other Build Profiles
When a manual webhook (SSH/Public URL/Read-only PAT) is already configured for a repository, additional build profiles that are connected to the same repository can reuse this existing webhook configuration.
- When opening the Webhooks section of a build profile, if a manual webhook is already detected for the repository, a prompt will appear asking if you would like to bind the build profile to the existing webhook.
- Selected Git Provider, Webhook URL, and the existing Webhook Key/Secret will be displayed as partially masked.
- Users can directly click the Bind button to link the build profile to the existing webhook.
### Webhook Setup for OAuth and PAT-Based Repository Connections
When a repository is connected to Appcircle via OAuth connection (such as GitHub, GitLab, or Bitbucket) or using a Personal Access Token (PAT), the behavior of webhook creation varies depending on the type of integration and the permission level of the token.
In some cases, Appcircle handles webhook setup automatically, while in others—particularly when using read-only access—manual configuration may be required to enable trigger-based builds.
Below is a breakdown of how webhooks are managed for each supported Git provider based on the connection method.
#### GitHub OAuth Connection
When your repository is connected using the GitHub OAuth connection, webhooks are created automatically. No manual configuration is needed.
#### GitLab OAuth Connection
Webhooks are also automatically created when connecting via the GitLab OAuth connection.
#### GitLab Cloud/Server - PAT Connection
The behavior differs depending on the PAT’s permission level:
- **Admin Permissions**: Webhooks are created automatically.
- **Read-Only Permissions**: Manual webhook creation is required.
To set up a manual webhook for a read-only PAT:
1. Connect the GitLab repository to Appcircle using the read-only PAT and create a build profile.
2. In GitLab Server, go to:
`Projects → → Settings → Webhooks → Add Webhook`
3. Paste the webhook URL in this format:
```
https://api.appcircle.io/build/v1/callback/hooks/{GIT_PROVIDER}/{YOUR_ORGANIZATION_ID}/V7
```
- `APPCIRCLE_API_URL`: Use `api.appcircle.io` for cloud, or your custom server address.
- `APPCIRCLE_BUILD_PROFILE_ID`: The ID of your Appcircle build profile.
:::warning PAT Role
In order to create a webhook, the created PAT must have at least the role of **Maintainer**.
:::
#### Bitbucket OAuth Connection
When using the Bitbucket OAuth connection, Appcircle automatically creates the webhook—no further action is needed.
#### Bitbucket Server - PAT Connection
Webhook behavior is determined by the PAT’s permissions:
- **Admin Permissions**: Webhook is created automatically.
- **Read-Only Permissions**: Manual setup is required.
To manually configure a webhook for a Bitbucket Server repository using a read-only PAT:
1. Connect the Bitbucket Server repository using the read-only PAT and create a build profile in Appcircle.
2. In Bitbucket Server, go to:
`Repositories → → Repository Settings → Webhooks → Create Web Hook`
3. Paste the webhook URL in this format:
```
https://api.appcircle.io/build/v1/callback/hooks/{GIT_PROVIDER}/{YOUR_ORGANIZATION_ID}/V7
```
#### Azure Devops - PAT Connection
When using the Azure Devops PAT Integration, Appcircle automatically creates the webhook—no further action is needed.
This ensures proper webhook communication across all supported Git repository configurations.
Please refer to the following guides to set up webhooks in various git providers:
[https://docs.github.com/en/developers/webhooks-and-events/webhooks](https://docs.github.com/en/developers/webhooks-and-events/webhooks)
[https://docs.gitlab.com/ee/user/project/integrations/webhooks.html](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html)
[https://support.atlassian.com/bitbucket-cloud/docs/manage-webhooks/](https://support.atlassian.com/bitbucket-cloud/docs/manage-webhooks/)
[https://docs.microsoft.com/en-us/azure/devops/service-hooks/overview?view=azure-devops](https://docs.microsoft.com/en-us/azure/devops/service-hooks/overview?view=azure-devops)
### Webhook Events Reference
You can enable or disable webhook event scopes according to your needs. The table below lists supported events for each Git provider along with their descriptions:
| **Event** | **Description** | **GitHub** | **GitLab** | **Bitbucket** | **Azure DevOps** |
|------------------------------|----------------------------------------------------------------------------|------------|------------|---------------|------------------|
| Push / Code Push | Triggered when code is pushed to any branch. | ✅ | ✅ | ✅ | ✅ |
| Tag Push / Tag Created | Triggered when a new tag is pushed. | ✅ | ✅ | ✅ | ✅ |
| Branch or Tag Creation | Triggered when a new branch or tag is created. | ✅ | ✅ | ✅ | ✅ |
| Branch or Tag Deletion | Triggered when a branch or tag is deleted. | ✅ | ✅ | ✅ | ✅ |
| Pull/Merge Request Created | Triggered when a PR/MR is opened. | ✅ | ✅ | ✅ | ✅ |
| Pull/Merge Request Updated | Triggered when commits are added or changes are made to the PR/MR. | ✅ | ✅ | ✅ | ✅ |
| Pull/Merge Request Merged | Triggered when a PR/MR is merged. | ✅ | ✅ | ✅ | ✅ |
| Pull/Merge Request Closed | Triggered when a PR/MR is closed or abandoned. | ✅ | ✅ | ✅ | ✅ |
| Issue or PR Comment Added | Triggered when a comment is added to an issue or PR. | ✅ | ✅ | ✅ | ❌ |
| Pipeline Status Changed | Triggered when a pipeline/build status changes (e.g., success/failure). | ❌ | ✅ | ❌ | ✅ |
| Work Item Updated | Triggered when a task/ticket is updated in the tracker system. | ❌ | ❌ | ❌ | ✅ |
:::info
✅ = Supported by the provider
❌ = Not supported or not applicable
Note: Terminology may vary slightly across providers (e.g., PR vs. Merge Request).
:::
:::tip
You can also use[ appcircle-cli](/appcircle-api-and-cli) to trigger your builds from the command line as well.
:::
## Managing Triggers for Builds
To set up or manage the build triggers, click the Triggers button in the context menu of the build profile, accessible from the top of the profile details.
### Auto build on every push
Appcircle will start building your application whenever you push a commit to your Git repository. For the specified branches, your project will be built automatically with the selected workflow.
You must choose both workflow, and a configuration when you're setting up a trigger.
### Auto build pull/merge requests
Appcircle will start building your application whenever you initiate a pull request or merge request from the source branch(es) to the target branch.
The build will be done with the pull/merge result using the selected workflow. This allows testing of the PR/MR result before the actual approval of the request.
:::caution
Make sure that the names of the source branch and the target branch are spelled correctly.
:::
:::info
If spaces are used in the name, Appcircle will trim it without spaces.
:::
:::info
If you are using Azure DevOps Server or Azure DevOps Services Cloud as a Git provider, the Appcircle build trigger will not run for PR status updates (Approve, Approve with suggestions, Wait for author, Reject, etc.) or action changes (Complete, Mark as draft, Abandon).
Appcircle will only run the trigger for PR creation or PR updates.
:::
### Triggering different workflows at the same time
Now you will be able to trigger different workflows in the same source branch and target branch on Appcircle at once. As soon as the trigger is triggered, Appcircle will start running all the triggered triggers in the build queue, starting from the first place in the established trigger queue.
### Selective auto build with specific tags
Appcircle will start building your application with the selected workflow whenever you perform a push with certain tags to your Git repository. Your project will be built automatically only if the push has the tags you specify, or you can specify a wildcard tag to build all tagged pushes.
This allows building scenarios like building only specific pushes that have the "release" in the tag.
### Skipping a workflow
If your commit message includes `[skip ci]` or `[ci skip]`, your workflow will be skipped.
### Retrying a workflow
If your merge request comment includes `[retry]`, your workflow will be retried.
### Auto Cancel Redundant Pipeline
When enabled, this feature automatically cancels any previously running build that matches the same build configuration, build workflow, build trigger and branch if a new run is triggered.
This helps prevent unnecessary resource usage and reduces queue time by skipping outdated pipeline runs.
To enable this feature:
1. Go to the `Build Profiles` and select `Configurations`.
2. Scroll down and activate `Auto Cancel Redundant Pipeline`.
3. Click `Save` changes.
The Auto-Cancel Redundant Pipeline mechanism works based on four key parameters:
- Build Configuration
- Build Workflow
- Build Trigger
- Git Branch
If a new build is triggered with the same values for all these parameters, any previously queued or running build is automatically cancelled.
:::warning Manual Builds Bypass Auto Cancel Redundant Pipeline
Builds that are **manually started** do not affect ongoing or queued builds; the auto-cancel mechanism does not apply to manually started builds.
:::
## Further Automatic Build Subjects
### Trigger Priorities
If you set multiple triggers, certain branch definitions will not take precedence over wildcard definitions. They will all start at the same time. Below is an example:
Assume that you have a branch named `development` with three push triggers.
- Trigger branch: `*` -> Trigger Workflow: Workflow 1
- Trigger branch: `development` -> Trigger Workflow: Workflow 2
- Trigger branch: `develop*` -> Trigger Workflow: Workflow 3
When there is a push or PR for the development branch, all triggers (since the word `development` contains both `*` and `develop*`) will be used to start a different build for each branch. At this point, a total of three build pipelines will begin.
:::info
If multiple triggered builds exceed your plan's concurrency limits, Appcircle will automatically queue them, and all of them will be executed unless you cancel.
:::
### Wildcard Reference
You can specify branch names or tags with an asterisk wildcard to automate builds. Below are some examples:
| Pattern | Description |
| ------------- | ----------------------------------------------------- |
| `*-fix` | Build if it ends with `-fix` |
| `fix-*` | Build if it starts with `fix-` |
| `*-fix-*` | Build if it `-fix-` is present anywhere in the name |
| `fix-*-build` | Build if it starts with `fix-` and ends with `-build` |
| `*` | Build everything |
## FAQ
### Why is my Appcircle trigger not working and how can I fix it?
First, ensure that the build profile triggers are set for the desired branches and actions. Please check the trigger settings from the [**Managing Triggers for Builds**](/build/build-process-management/build-manually-or-with-triggers#managing-triggers-for-builds) section in the documentation.
Appcircle is triggered via the Git provider's webhooks. To properly work with triggers, webhooks in the repositories are used by Appcircle. Also, ensure that the repository has webhook access to Appcircle. To connect webhooks, the Git provider connection must be set up properly while creating a build profile.
Certain Git actions to the repositories, such as push, merge, pull request, tag push, etc., activate a specified event with the repository's webhooks. It is necessary to ensure that the desired event is actually triggered by the action in the Git provider's repository.
If webhooks are disabled due to frequent use or connection-based errors, using test events may help re-enable webhooks in Git providers.
To ensure webhooks are set and working, the webhook history can be reviewed within the Git providers. Let's check the Git providers below. You can follow the steps in the Git provider's documentation to access the webhook event history.
- [**GitHub Webhook Deliveries**](https://docs.github.com/en/webhooks/testing-and-troubleshooting-webhooks/viewing-webhook-deliveries#about-webhook-deliveries)
- [**GitLab Webhook Request History**](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#view-webhook-request-history)
- [**Azure DevOps Services Webhook History**](https://learn.microsoft.com/en-us/azure/devops/service-hooks/services/webhooks?view=azure-devops)
- [**Bitbucket Webhook Documentations**](https://support.atlassian.com/bitbucket-cloud/docs/manage-webhooks)
:::info Bitbucket Webhook Event History
A document detailing the history of webhooks is not provided by Bitbucket. To access the webhook history, please navigate to:
**Bitbucket -> Repository -> Repository Settings -> Webhooks -> View Requests**
View Requests has to be enabled before requests can be seen.
:::
Once the webhook is created and confirmed to be properly set up and healthy in the Appcircle build profile, and it is verified to work correctly with the specific Git provider, the process works as follows:
- A Git action, such as pushing a code block, triggers a webhook event.
- This webhook event activates the trigger in Appcircle.
- Appcircle then automatically starts the build process.
### Why does my tag trigger start a build on a different branch?
When you create a tag, it is applied to a specific commit, not a branch. The system does not have explicit branch information linked to the tag. Therefore, when the tag trigger starts a build in Appcircle, it may select any branch that contains the tagged commit, leading to seemingly random behavior.
To control this behavior, push an empty commit to the desired branch and then apply the tag to this new commit. This ensures that the tag trigger starts from the intended branch.
### How to enable triggers for AWS CodeCommit repositories?
Appcircle supports AWS CodeCommit triggers through an Amazon SNS topic.
For more information, please refer to: [https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-notify-sns.html](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-notify-sns.html)
After you follow the steps in the referenced document above to create a trigger, you need to create a notification rule under CodeCommit Settings as shown below to add a webhook URL.
Then select the "Enable raw message delivery" option while adding the webhook URL as a subscription to the topic.
---
## Branch Operations
# Build Profile Branch Operations
When you connect to a repository, all branches of that repository will be displayed with the last 100 commits. Appcircle provides a number of features for easy management of branches.
### Finding a Specific Branch
To find a specific branch, just start typing in the name in the branch search bar and the branches that include the phrase will be filtered as you type.
### Filtering Branches
You can filter the available branch list by build statuses. Once you select a build status from the filter list, the relevant branches will be displayed accordingly.
The available filter options are:
- **All**
- **Success**
- **Failed**
- **Canceled**
- **Running**
- **Timeout**
### Pinning Branches to the Top for Faster Access
If you are using a branch frequently, such as develop or master, you can pin it to the top. To pin a branch, click on the pin icon next to the branch name.
The branch will be moved to the top with a pinned indicator. You can unpin the branch by pressing the pin button again.
### Manually Fetching Branch and Commits
By clicking the refresh button next to the Branch List title, you can manually start a fetching process that will update your commits and branches from the remote repository.
---
## Workflows
A workflow is a ladder of steps taken to build your applications.
Each step has a different purpose, and the workflow can be customized by modifying step parameters and inputs, running custom scripts, or reordering steps.
Workflows allow you to have complete control over your build process and enhance it with third-party services and features.
:::caution
Please note that modifying workflow steps may cause your builds to fail, so utmost care is recommended when editing workflows.
:::
### Setting Up Workflows
To access the workflow editor for a build profile, click the Workflows button in the context menu of the build profile, accessible from the top of the profile details.
The workflow list will be displayed. To view the workflow steps of a workflow, click on it from the workflow list.
To create a new workflow, press the "New" button at the top of the workflow list and select a template from the default workflows. Then edit the workflow name and press enter. You can also upload your workflow as a YAML file.
To rename/delete a current workflow, press the "Edit" button at the top of the workflow list and then click on the context menu that appears next to the workflow items.
You can use the "Clone" option to create a new workflow based on the currently available ones. You can select different workflows for different build scenarios (e.g., separate workflows for production and development).
### Workflow Steps
Appcircle will build your application with the steps defined in the [workflow](/workflows). Steps will be executed in order from the top to the bottom.
You can customize each step for specific configurations with your application structure. Step parameters can be modified, outputs of each step can be used in another step, and step versions can be selected accordingly.
### Workflow Marketplace
Appcircle's powerful Workflow Editor has a built-in Workflow Marketplace that allows you to select and insert an unlimited number of steps into your workflow.
You can find the full list of available workflow steps in our workflow marketplace at:
[https://www.appcircle.io/integrations/](https://www.appcircle.io/integrations/)
You can add platform-specific workflow steps, custom scripts, and other steps into your workflow and reorder them as you like. You can also remove the steps you don't need. You can back up your current workflow by clicking the **Download YAML** button at the bottom.
To access the Workflow Marketplace, click on the **Manage Workflow** button. You will see the Workflow Marketplace on the right and your Workflow steps on the left.
You can now drag and drop steps into your workflow. Any unwanted workflow steps can be removed by clicking on the delete button on the right side of each step.
You can also reorder steps so that they will be executed in the order you specify.
### Editing Workflow Steps
Each workflow step has its own set of configuration options, which can be set by clicking on the step in the workflow screen.
The first three items are common for all steps, and they are set individually for each step:
- **Step Execution Active:** To enable/disable the step execution without removing it from the workflow.
- **Always run this step even if the previous step fails:** If this option is enabled, getting a failed result on a previous workflow step will not directly terminate the build process so this specific workflow step can run.
- **Continue with the next step even if this step fails:** If a step is optional or its result should not cause a build error, you can select this option to continue the workflow if this particular step fails. In default workflows, this option is `on` for specific steps. Since this step is active, the build status will appear as "Warning" if other steps in the build are successful.
- **Workflow Step Version:** You can select a specific version of a step with which to execute your build. If you select a version with an asterisk (\*), you will receive the minor updates to the workflow step automatically. The major versions may include added or removed input fields, and manual version selection is required for major version updates.
The items in the "Inputs" section are specific to that step. The reserved environment variables are assigned to these fields by default, and the values of these variables are set in the build configuration.
:::info
Please note that the Workflow Step Version is managed by Appcircle. Native steps that are being used have their own versions.
:::
When we start a build, if we have activated the "Continue with the next step even if this step fails" setting for a component we use in the workflow and this step fails during the build, Appcircle will show the build status as "Warning" if the build is completed successfully for other steps.
In order to simulate the warning state and see its results on the pipeline, we can basically write a script that will fail in Custom Script.
"Continue with the next step even if this step fails" must be `on` in this case.
We are starting a build, and we see that it fails in the pipeline.
And the build status will now appear as "Warning".
For more information regarding build statuses, please refer to [manual build](/build/build-process-management/manual-builds#build-statuses) documentation.
---
## Configurations
# Build Configuration
Configuring a build profile requires completing some basic steps before starting a build.
### Creating a configuration
You may create a configuration profile that allows you to set different certificates and distribution channels that can be used with different workflows.
- Click on **Configurations** to create configurations for different scenarios.
- Click on the **New** button to create your first configuration.
You can also create a configuration profile by uploading a saved YAML file.
- You may change the name of the configuration or delete the ones you don't need. To do that, click on the edit button shown and the three dots on the configuration you want to edit/delete.
If you have a configuration that you use constantly or want to quickly copy a configuration, you can use the "Configuration Clone" feature.
The configuration clone feature will speed up your projects where you use many configurations.
First, open the configuration process by clicking the edit button.
Then click on the three dots next to the configuration you want to copy and click the "Clone" button in the mini window that opens.
Another one is created identical to the configuration you want to clone.
:::info
The name here is created by adding "\_copy_1" to the end of the main configuration name. For each configuration copied from now on, the name will be incremented to remain unique.
:::
:::tip
Although the system gives a unique name for the copied configuration by default, you can give this configuration a new name using "Rename".
:::
You can download your **Configuration** in YAML format to perform actions like sharing the settings you've configured or creating a duplicate on another **Build Profile** page. Follow these steps to download your **Configuration**:
- Open the **Configuration** you've created.
- Locate the download button positioned at the bottom left of the Configuration interface. Click on the download button.
Your _configuration.yaml_ file will be downloaded to your local system.
:::tip
If you intend to copy the configuration to use on the same **Build Profile** page, consider using the **Clone Configuration** step as a quicker alternative.
:::
:::caution
The downloaded YAML file is specific to the project type and can only be used for configuring the same type of project. For example, a YAML file generated for an iOS Swift project cannot be applied to an Android React Native project. Ensure that you use the correct YAML file for seamless configuration.
:::
### Config Details
Every build profile needs to know project details regardless of whether the project is an iOS or Android project. Project details can be entered manually or can be fetched from your project automatically by Appcircle if you click on **Autofill** button.
Config details will show you your current Machine Plan. It's Standard by default but can be upgraded depending on your build requirements.
Machine Plans
You can also select your self-hosted runner from the **SELECT A POOL** dropdown.
Self-hosted Runners
#### Build Priority
The build priority configuration feature has three levels: Low, Medium, and High.
These priority levels determine the order in which queued builds start, ensuring that higher-priority builds are initiated first.
For example, if a high-priority build is added to the queue after a low-priority build, the high-priority build will start before the low-priority one.
This feature allows for better management of build processes, enabling teams to prioritize critical updates and improvements efficiently.
:::info
This feature is only available for organizations with Enterprise license.
:::
#### ACRP - Auto Cancel Redundant Pipeline
When enabled, this feature automatically cancels any previously running build that matches the same configuration, workflow, branch, and trigger type, if a new run is triggered.
This helps prevent unnecessary resource usage and reduces queue time by skipping outdated pipeline runs.
For further details, see [Auto Cancel Redundant Pipeline](/build/build-process-management/build-manually-or-with-triggers).
### Signing configuration
Both iOS and Android applications need to be digitally signed by their developers in order to be able to be installed on real devices or submitted to app stores.
iOS certificates and Android keystores can be generated within Appcircle, or pre-obtained certificates can be uploaded. iOS provisioning profiles need to be obtained from the Apple Developer account and uploaded to Appcircle.
:::info
Please note that the [Automatic Code Signing](/signing-identities/apple-profiles#automatic-signing) option is only available for iOS projects.
:::
You can either upload your iOS [certificate](/signing-identities/apple-certificates) and iOS [provisioning profile](/signing-identities/apple-profiles) or [Android Keystore](/signing-identities/android-keystores) from here or within the [Signing Identities](/signing-identities) module.
### Distribution configuration
Set up automated distribution for your builds by configuring distribution settings in Appcircle. This feature allows you to automatically send completed builds to selected modules, including Testing Distribution, Publish, or the Enterprise Store, ensuring a seamless deployment process.
Simply enable the toggle of the module that you need and select the required profiles.
#### Send to Testing Distribution
Distribution configuration allows you to set which testing groups will receive your application after the build is complete. You can manually submit your binary to [Testing Distribution](/testing-distribution) profiles, or Appcircle can do it for you.
In this window, you can select one or more of the previously created distribution profiles. You can use the "Manage Distribution Profiles" button above to quickly manage distribution profiles.
Finally, check "Automatically Distribute to Testers" if you want your build to be automatically distributed to the selected testers or testing groups.
:::caution Binary comes from Build Module
If the `Bundle/Package` validation option is turned on in the **Testing Distribution** profile you want to automatic distribution and the bundle or package of the binary to be submitted does not match the one specified in this profile, you will get an error during submission. Appcircle does not prevent the profile from being selected. Please make sure that the bundle/package identifier of the binary you want to submit matches the one in the **Testing Distribution** profile.
For more detailed information about identifier validation, please visit the **Bundle/Package validation** [documentation](/testing-distribution/create-or-select-a-distribution-profile#bundlepackage-identifier-validation).
:::
#### Send to Publish
Enabling "Automatically Distribute to Publish" will display the available [Publish](/publish-to-stores-module) profiles for distribution.
Simply select your relevant publish profiles, and Appcircle will automatically send your builds to the selected publish profiles.
Please note that the publish profiles should be created within the publish module prior to configuring the distribution settings in the build profile.
#### Send to Enterprise App Store
- Navigate to the configuration, then go to the Distribution tab, and ensure that **Automatically Distribute to Enterprise App Store** is enabled.
- Whenever a new **signed** build is created, it will be sent to the [Enterprise App Store](/enterprise-app-store).
:::info
If you are building a binary for the first time or distributing it to the Enterprise App Store for the first time, a new Enterprise App Store profile will be created automatically. If there is an existing Enterprise App Store profile for your build, it will be directed to the existing profile.
:::
### Versioning configuration
You can set custom rules to manage the versioning of your app. You can increase both the build number and version number according to the rules you set.
For more information please refer to the [Versioning](/versioning) documentation.
### Environment variables configuration
You can define variables and secrets to be incorporated during the build in the Environment Variables submodule so that you don't need to store certain keys and configurations within the repository.
For more information regarding creating environment variables for build profiles, please refer to the related [Environment Variables](/build/build-environment-variables) documentation.
---
## Build Profile
New to the Appcircle Build module? Follow our quick-start guide to build your iOS and Android apps in the cloud.
The Build Module allows you to streamline and automate your mobile app build flows.
## [Profile Creation](/build/build-process-management/profile-creation)
Discover how to create and manage build profiles in Appcircle. This section guides you through the process of setting up new build profiles and listing existing ones, ensuring a streamlined workflow for your development and deployment needs.
## [Configurations](/build/build-process-management/configurations)
Before initiating a build, certain essential steps must be completed to properly configure a build profile. This section outlines the fundamental configurations required to ensure a seamless build process.
## [Workflows](/build/build-process-management/build-workflows)
A workflow is a sequence of steps taken to build your applications.
Each step has a different purpose, and it can be customized by modifying step parameters and inputs, running custom scripts, or reordering steps.
## [Triggers](/build/build-process-management/build-manually-or-with-triggers)
Builds can be triggered with various triggers, such as every push to the repository, pull/merge requests, or tagged pushes.
## [Manual Builds](/build/build-process-management/manual-builds)
Learn how to initiate manual builds using your build profile in Appcircle. This section provides step-by-step guidance on triggering builds manually to streamline your development workflow.
## [Binary Actions](/build/build-process-management/binary-actions)
Explore the different binary actions available in Appcircle after completing your builds. This section guides you through utilizing these actions to manage, distribute, and optimize your build artifacts efficiently.
## [Branch Operations](/build/build-process-management/build-profile-branch-operations)
When you connect to a repository, all branches of that repository will be displayed with the last 100 commits. Appcircle provides several features for easy management of branches.
---
## Manual Builds
# Starting a Manual Build
To initiate a build in Appcircle, follow these steps:
- Click on the Start Build button to begin the process.
- Appcircle will prompt you to choose a configuration and workflow settings from the saved configurations. Select the appropriate settings that match your project requirements.
- Once the configurations are selected, click the Start button to start the build.
- Users can monitor the progress, results, and logs of the workflow steps in real-time via the interface.
- After the build is complete, you have the option to download the build logs for reference or troubleshooting purposes.
- Upon completion, the binary along with the artifacts will be displayed on the selected branch. These can be accessed for deployment or further use.
By following these steps, you can efficiently manage and monitor your builds in Appcircle.
For more detailed information on builds with different types of projects, please refer to the [Platform Build Guides](/build/platform-build-guides) documentation.
#### Build Statuses
- **Success**: The build has finished successfully with no failures in the workflow steps.
- **Failed**: The build has failed due to one or more workflow steps failing.
- **Warning**: The build has finished with a failed workflow step that does not affect the final outcome.
- **Timeout**: The build exceeded the timeout limit and ended prematurely.
- **Canceled**: The build was canceled by the user.
---
## Profile Creation
A Build profile can be created by following these steps:
## Creating a Profile
Click on the **Add New** button located in the middle of the screen. If you already have an existing profile displayed on the build profile list, this button will be in the top right corner.
Provide a unique name for the build profile and choose a target operating system (OS), which can be Android or iOS.
After selecting the target OS, specify the corresponding target platform to set up a compatible build environment:
iOS Platforms:
* [Objective-C / Swift](/build/platform-build-guides/building-ios-applications)
* [React Native](/build/platform-build-guides/building-react-native-applications)
* [Flutter](/build/platform-build-guides/building-flutter-applications)
Android Platforms:
* [Java / Kotlin](/build/platform-build-guides/building-android-applications)
* [React Native](/build/platform-build-guides/building-react-native-applications)
* [Flutter](/build/platform-build-guides/building-flutter-applications)
Click **Save** to proceed.
Choose from the available repository connection options to link your project source code:
* [GitHub](/build/manage-the-connections/connection-guides/connecting-to-github)
* [Azure](/build/manage-the-connections/connection-guides/connecting-to-azure)
* [Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket)
* [GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab)
* [Connect via SSH](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh)
* Connect via URL
* [Connecting to Multiple Instances](/build/manage-the-connections/connection-guides/connecting-multiple-instance)
:::info
If you have not previously connected to a Git provider on Appcircle, i.e., created a profile but have not connected a repository, you will not see any connection on this page.
For more information on creating repository connections, please refer to the [connections](/build/manage-the-connections) guide.
:::
To test drive Appcircle, you can find various sample projects on the [Appcircle GitHub page](https://github.com/appcircleio?q=sample) or you can just press the **Quick Start Using the Sample Repository** button to populate the repository with a compatible project based on the selected framework.
For detailed instructions on connecting to each repository, refer to the [Connection Guides](/build/manage-the-connections/connection-guides).
Once the repository connection is established, the build profile will be created successfully. Appcircle will then pull your branches, commits, and other information from your repository. You can now use the build profile to manage and deploy your projects.
### Profile Listing
Users can view their created build profiles by selecting the **Build Profiles** option in the left menu. They can also toggle between the profile card view and list view to easily locate profiles for different project types.
## Connection Settings
After connecting a build profile to a Git provider, we can see the **"Connection Settings"** button in the build profile details.
You can click on the "Connection Settings" button under the build profile name and URL to see detailed information about the connection. (PAT, OAuth)
### OAuth
### Personal Access Token (PAT)
:::caution
If you added your repository via **multiple instances** using PAT (Personal Access Token), the "Connection Settings" will look different.
You can review the [**Connecting Multiple Instances**](/build/manage-the-connections/connection-guides/connecting-multiple-instance#connection-settings-for-multiple-instances) page to learn how to use "Connection Settings" for multiple instances.
:::
---
## Build Module Overview
The Build Module in Appcircle streamlines your Continuous Integration and Continuous Deployment (CI/CD) workflows for mobile app development. It covers everything from code integration to managing your build profiles and post-build artifacts.
:::tip Learn More
For a complete overview of the Build Module’s capabilities, check out the [Appcircle's Build Section](https://appcircle.io/build).
:::
## [Build Profiles](/build/build-process-management)
Follow our getting started guide to build your iOS and Android apps in the cloud. This guide will walk you through creating a build profile, managing profiles, branches, configurations, triggers, and more.
Build Profiles
## [Environment Variables](/build/build-environment-variables)
Environment variables let you extend your build configuration. There are several read-only Appcircle variables, and you can add your own variables to export and use during the build process in custom build scripts.
Environment Variables
## [Connections](/build/manage-the-connections)
Set up integrations with version control systems to sync your repositories, allowing for automated builds and deployments.
Connections
## [Platform Build Guides](/build/platform-build-guides)
Find detailed instructions for building applications across various platforms, including iOS, Android, React Native, Flutter, and Ionic.
Platform Build Guides
## [Build History](/build/build-history)
The Build History Report provides a comprehensive list of build sessions initiated within a selected time period. Users can filter their search based on date and organization for more precise tracking. Additionally, the report can be exported in CSV format for further analysis and record-keeping.
Build History
## [Build Activity Log](/build/build-activity-log)
Build Activity Log allows you to monitor Build module related actions such as creating, deleting, and adding Build profiles or updating configurations performed on Build profiles in your Organization or Sub-Organizations.
Build Activity Log
---
## Accessing Internal Networks
# Accessing Repositories Within Internal Networks
In certain cases, the source codes of the apps may be stored in internal repositories instead of the cloud providers. If these internal repositories are accessible from the public internet, then you can use Appcircle without any additional configuration.
However, if your repositories are within an internal network/behind a firewall, which is usually the case with enterprises, the network configuration of these repositories must be configured for external access.;
Appcircle requires direct access to the repositories for the following use cases:
- For retrieving the repository information such as the branches and the commits.
- For cloning the repository to the build agent during the build.
If the repositories cannot be exposed to the public internet in general, the following Appcircle platform IP addresses must be allowed through the firewall (whitelisted) to access such repositories:
- 34.147.2.16
- 162.19.204.13
- 77.92.96.46
- 77.92.124.2/27
- 77.92.102.192/28
:::caution
If the provided IP address is a subnet defined in CIDR notation, you need to allow the entire subnet on your network.
For example, 77.92.124.2/27 means all IP addresses between 77.92.124.1 and 77.92.124.30 (`77.92.124.1`, `77.92.124.2`, `77.92.124.3`, and so on, all the way to and including `77.92.124.30`) that must be whitelisted on your firewall.
:::
You can then [connect to the repository](/build/manage-the-connections/connection-guides) with your favorite Git provider.
---
## Connecting to Multiple Instances
Multiple connection features have been introduced for connections made with PAT (Personnel Access Token) on Bitbucket, Azure DevOps, or GitLab. Thus, it is possible for a single user to add Bitbucket, Azure DevOps, or GitLab servers located in different environments.
For example, the same user can connect to two different instances, such as dev1.azure.companyname.com and dev2.azure.companyname.com.
Similar examples are dev1.gitlab.companyname.com and dev2.gitlab.companyname.com or dev.bitbucket.companyname.com and prod.bitbucket.companyname.com.
:::caution
In order to use this feature, it is necessary to create a PAT on the provider.
:::
:::info
To add a git provider, PAT support is sufficient. There is no distinction between self-hosted and cloud-based.
:::
See below for steps for an example case from Azure DevOps.
First of all, we select the relevant Git provider from the add new repository screen.
Then click on the "Connect to an Azure DevOps Server" button in the window that opens.
In the next window, fill in the relevant fields and click on the "Connect" button.
After the connection, the connected instances will appear on the new repository adding screen as follows.
Additionally, when we click on an instance, we can see it here with the name we gave it.
:::caution
The instance name for each Git provider must be unique.
For example, if you create an instance named "Instance" for Azure DevOps Server, you cannot reconnect an instance named "Instance" for Azure DevOps Server.
However, you can connect an instance with that name for GitLab or Bitbucket Server.
:::
### Connection Settings for Multiple Instances
When we connect a repository using PAT (Personal Access Token) on multiple instances, you can use the "Connection Settings" button to view the PAT information and change the PAT information if there is a previously defined connection.
When we connect a repository using PAT over multiple instances, the user email and PAT list appear in the "Connection Settings".
:::caution
In order to change the Personal Access Token (PAT), you must have provided more than one connection for the same Git provider. If you have more than one connection, you can switch between PATs.
:::
---
## Connecting to Azure DevOps
### Requirements
You must enable third-party application access via OAuth. To do that, you can follow the steps:
- Go to https://dev.azure.com
- Click on the Organization setting from the left sidebar.
- Go to your policy settings below security.
- Enable third-party application access via OAuth.
:::important Third-party application access via OAuth
To successfully connect your Azure DevOps Cloud Repository with an Appcircle Build Profile, the “**Third-party application access via OAuth**” policy must be enabled in your Azure DevOps organization settings.
This setting allows Appcircle to authenticate and interact with your repositories securely. If this policy is turned off, Appcircle will be unable to establish a connection, and repository integration will fail.
:::
### Configuration Azure DevOps Services Setting on Appcircle
If you authorize Appcircle to access your repositories on Azure DevOps, you can select the repository that you want to connect in the next screen.
After you click on **Azure**, the following screen will appear. This will let you choose between selecting a repository, which you have already authorized Appcircle to do, or asking your consent about authorizing more repositories.
When you successfully authorize your account, the following screen will appear to let you select one for connection:
After the connection is successful, you can [view your newly created profile](/build/build-process-management/profile-creation#profile-listing) and start building!
## Connecting to Azure DevOps Cloud Repository
To connect to a Azure DevOps Cloud repository using either OAuth or Personal Access Token,
- **OAuth2 Connection**
Click **Get Repositories from Azure DevOps (OAuth2)** to authenticate Appcircle using your Azure DevOps account credentials. This will grant Appcircle access to your repositories through the authorized scope.
- **Personal Access Token (User)**
Use your Azure DevOps username and [Personal Access Token (PAT)](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops) to connect manually. Required fields:
- Connection Name
- Azure DevOps Server URL (e.g., `https://dev.azure.com`)
- Collection Name (e.g., `DefaultCollection`)
- Personal Access Token
### OAuth2 Permissions for Azure DevOps Integration
The following table details the OAuth permissions required for Appcircle to connect with Azure DevOps. These permissions grant read access to projects, repositories, pull requests, and webhooks, ensuring proper functionality when integrating with Azure DevOps via OAuth.
| Scope | Permission | Description |
|------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Code | Read , Status | Provides read access to repositories, enabling applications to fetch and view source code. Allows applications to post and update build or commit statuses in repositories. |
| PR threads | Full | Enables access to pull request comments and discussions (threads), including reading and posting messages. |
| Service Endpoints| Read , Query | Grants read, query access to service endpoints. Allows listing external service integrations and retrieving details of existing connections, but does not permit creating or modifying.|
| Project and team | Read | Provides read access to project and team-related information, such as project details and team memberships. |
| Notifications | Read | Grants read-only access to notification settings. |
## Connecting to Azure DevOps Server Repository
The overall process is similar to a private repository connection through SSH, but Appcircle allows you to directly connect through the Azure DevOps Server URL.
:::caution
TFS is not compatible with Azure DevOps Server on Appcircle.
:::
:::caution
Azure DevOps Server version must be **Azure DevOps Server 2020** or higher.
:::
First, select **Azure** and then **Personal Access Token (User)** under **Create a new Azure Devops Connection** through the menu:
Fill in the relevant information about your Azure DevOps Server. If you are not sure what those are, contact your system administrator.
- **Connection Name**: Give a name to this connection for easier identification in your list of integrations.
- **Azure DevOps Server URL**: Provide the base URL of your Azure DevOps Server (e.g., `https://azuredevops.mycompany.com`).
- **Collection Name**: Specify the name of the collection on your Azure DevOps Server (e.g., `DefaultCollection`).
- **Personal Access Token**: Enter the token generated in your Azure DevOps Server profile settings for Git access.
Required permissions are listed below:
| Scope | Permission | Description |
|------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Identity | Read | Allows reading identity information, such as users and groups within the organization |
| Code | Read , Status | Provides read access to repositories, enabling applications to fetch and view source code. Allows applications to post and update build or commit statuses in repositories.|
| Notifications | Read | Grants read-only access to notification settings. |
### Azure Devops Server That Is Upgraded From a TFS Server
:::caution
If your Azure DevOps Server is upgraded from a TFS server, you should identify your Azure DevOps Server URL.
- Copy a repository clone URL for any git repository.
- Check if your URL has an unexpected **path** in the URL.
- For example: `https://azure.spacetech.com/tfs/DefaultCollection/MOBILE_IOS/_git/wallet`
- If there is a path between your domain (`azure.spacetech.com`) and your collection name (`DefaultCollection`), you must give that path (`tfs`) as a prefix in the "Owner Username".
- For example, the fields should have values like below.
- Azure DevOps Server URL: `https://azure.spacetech.com`
- Owner Username: `tfs/DefaultCollection`
- Personal Access Token: `54rdrkce6wa4d22kf75lhmq4hosgx7iy7h76cc62y77oguombnnq`
:::
:::caution Connection Notice
For Appcircle to connect to the Azure DevOps Server instance, your connection must be reachable over the network.
:::
Is your Azure DevOps Server instance under the enterprise firewall? Learn which IP addresses and ports Appcircle uses to function under the whitelist documentation:
Accessing Repositories in Internal Networks (Firewalls)
### Token Creation
- [Personal Access Token Azure DevOps Documentation](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows)
A user’s **Personal Access Token** enables connection to their repository through Appcircle. It is used to authorize access to all repositories the user can access.
### Check Token
You can follow the steps below to check if your token is valid.
- Open the terminal and issue the following command:
```bash
personalAccessToken=abcde && \
serverUrl=https://azure.spacetech.com && \
organizationName=Appcircle && \
curl -H "Authorization: Basic $(echo -n :${personalAccessToken} | base64)" \
"${serverUrl}/${organizationName}/_apis/projects?api-version=6.0" | jq
```
The above command should print out your projects. If you don't see an output, please check your token, Azure DevOps Server address, or collection name.
:::caution
Please also make sure that the output doesn't show any reference to `localhost`. If you see `localhost`, you need to configure Azure DevOps Server and put the correct address of the instance.
:::
---
## Connecting to Bitbucket
If you authorize Appcircle to access your repositories on Bitbucket, you can select the repository that you want to connect in the next screen.
After you click on **Bitbucket**, the following screen will appear. This will let you choose between selecting a repository that you are already authorized to do with Appcircle or asking your consent about authorizing more repositories.
When you successfully authorize your account, the following screen will appear to let you select one for connection:
After the connection is successful, you can [view your newly created profile](/build/build-process-management/profile-creation#profile-listing) and start building!
## Connecting to Bitbucket Cloud Repository
To connect to a Bitbucket Cloud repository, you can choose from the following connection types:
- **OAuth2 Connection**
Click **Get Repositories from Bitbucket Cloud (OAuth2)** to authorize Appcircle using your Bitbucket Cloud credentials. This provides secure and seamless integration.
- **App Password - User** (Deprecated)
Choose this to authenticate using your Bitbucket username and an [App Password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/). You will need to provide:
- Connection Name
- Bitbucket Server URL (e.g., `https://bitbucket.org`)
- Username
- App Password
:::caution
Bitbucket has replaced **App Passwords** with **API Tokens**. However, existing App Passwords can still be used until mid-2026. For more information, please refer to the [official Bitbucket documentation](https://support.atlassian.com/bitbucket-cloud/docs/api-tokens/).
:::
- **API Token - User**
Choose this to authenticate using your Bitbucket username and an [API Tokens](https://support.atlassian.com/bitbucket-cloud/docs/api-tokens/). You will need to provide:
- Connection Name
- Bitbucket Server URL (e.g., `https://bitbucket.org`)
- Email Address
- API Token
- **Access Tokens - Repo**
Use a repository-specific token for limited-scope access to individual repositories.
### OAuth2, App Password (Deprecated) and Access Token Permissions for Bitbucket Cloud Integration
The following table details the OAuth permissions required for Appcircle to connect with Bitbucket. These permissions grant read access to projects, repositories, pull requests, and webhooks, ensuring proper functionality when integrating with Bitbucket via OAuth2, App Password and Access Token.
| Scope | Permission | Description |
|--------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Account | Email | Provides access to view the user's primary email address. |
| Project | Read | Provides access to view the projects the user has access to view. Read access (repository) to all the repositories in the projects is also granted. |
| Repository | Read | Provides access to view all the repositories the user has access to view, including the source code, Issues, and Wiki. This does not include pull requests. |
| Pull Request | Read | Provides access to view and list pull requests on the repositories the user has access to view. This permission (scope) also allows the user to create and resolve tasks. |
| Webhooks | Read & Write | Needed for enabling Appcircle triggers through webhook operations. |
### API Token Permissions for Bitbucket Cloud Integration
The following table details the API Token permissions required for Appcircle to connect with Bitbucket. These permissions grant read access to projects, repositories, pull requests, and webhooks, ensuring proper functionality when integrating with Bitbucket via API Token.
- While creating an API Token, select the **Create API Token with scopes**, then choose **Bitbucket Application** as the API Token App.
| Scope | Description |
|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| read:account | Provides access to view the user's primary email address. |
| read:project:bitbucket | Provides access to view the projects the user has access to view. Read access (repository) to all the repositories in the projects is also granted. |
| read:repository:bitbucket | Provides access to view all the repositories the user has access to view, including the source code, Issues, and Wiki. This does not include pull requests. |
| read:pullrequest:bitbucket | Provides access to view and list pull requests on the repositories the user has access to view. This permission (scope) also allows the user to create and resolve tasks. |
| read:webhook:bitbucket | Needed for enabling Appcircle triggers through webhook operations. |
| write:webhook:bitbucket | Needed for enabling Appcircle triggers through automaticly creating webhooks. |
| delete:webhook:bitbucket | Needed for enabling Appcircle triggers through removing automaticly created webhooks. |
## Connecting to Bitbucket Server (Self-Hosted) Repository
The overall process is similar with a private repository connection through SSH, but Appcircle allows connections to self-hosted Bitbucket servers via HTTP Access Tokens.
:::caution
Bitbucket's version must be **7.14** or higher.
:::
1. Select **Bitbucket** > **HTTP Access Token - User** or **HTTP Access Token - Repo** based on your token type.
2. Fill in the connection form with:
- Connection Name
- Bitbucket Server URL
- Username
- HTTP Access Token
If you are not sure what those are, contact your system administrator.
:::info
Appcircle requires admin-level access to automatically create the necessary webhooks. After the webhooks are successfully created, the associated access token can be safely downgraded to read access.
:::
:::caution Connection Notice
For Appcircle to connect to the self-hosted Bitbucket instance, your connection must be reachable over the internet.
:::
Is your self-hosted Bitbucket instance under an enterprise firewall? Learn which IP addresses and ports Appcircle uses to function under the whitelist documentation:
Accessing Repositories in Internal Networks (Firewalls)
### Token Creation
Bitbucket has **Personal Access Token** to authorize the user. Relevant guide:
https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html
:::info
Appcircle needs admin permission to function properly. The admin permission is needed to create relevant WebHooks automatically.
:::
:::danger
Bitbucket doesn't allow scoped repository permissions like GitHub. Therefore the token you add can access all the repositories of the token's owner. When you're adding a token, it's better to create a new bot user or a project and give access to only the required repositories for build to succeed.
:::
### Check Token
You can follow the steps below to check if your token is valid.
- Open the terminal and issue the following command
```bash
curl --user name:password http://YOUR_BITBUCKET_HOST/rest/api/1.0/repos
```
Above command should print out your projects. If you don't see an output, please check your token and Bitbucket address.
:::caution
Please also make sure that the output doesn't show any reference to `localhost`. If you see `localhost`, you need to configure Bitbucket and put the correct address of your Bitbucket instance.
:::
---
## Connecting to GitHub
If you authorize Appcircle to access your repositories on GitHub, you can select the repository that you want to connect in the next screen. Only the selected repositories will be listed.
:::info
If you are a part of an organization, you can also connect your organization's repositories too. To grant Appcircle permission to access the repositories of an organization, you need to have the necessary privileges at the organization level. For GitHub, you have to provide selective access to specific repositories.
:::
:::info
For connection to GitHub, Appcircle uses GitHub App instead of GitHub OAuth. GitHub App is a more secure and newer way that implemented by GitHub uses OAuth2 for external apps to communicate within GitHub in a better fashion.
:::
After you click on **GitHub**, the following screen will appear. This will let you choose between selecting a repository that you are already authorized to do with Appcircle.
When you successfully authorize your repository or repositories, the following screen will appear to let you select one for connection:
After the connection is successful, you can [view your newly created profile](/build/build-process-management/profile-creation#profile-listing) and start building!
## Connecting to GitHub Cloud Repository
To connect to a GitHub cloud repository, you can use two different authentication methods:
- **GitHub App Cloud**
Authenticate and authorize Appcircle to access your GitHub repositories using GitHub App OAuth2 integration. This is the recommended and default method.
- **GitHub Cloud**
Use this method to manually connect using a GitHub Fine-Grained Personal Access Token (PAT). You will be required to fill out:
- Connection Name
- GitHub Server URL (e.g., `https://github.com`)
- GitHub Username
- Fine-Grained Personal Access Token
### OAuth2 and Personal Access Token Permissions for GitHub Integration
The following table details the OAuth2 and fine-grained personal access token permissions required for Appcircle to connect with GitHub. These permissions grant read access to projects, repositories, pull requests, and webhooks, ensuring proper functionality when integrating with GitHub via OAuth2 and Personal Access Token.
| Scope | Permission | Description |
|----------------------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Commit statuses | Read & Write | Allows read and write access to commit statuses. This enables an application to create, update, and retrieve statuses for specific commits. |
| Contents | Read | Read-only access to a repository's contents, including files, commits, branches, and directories. This scope allows an application to fetch and display repository data without modifications.|
| Metadata (Mandatory) | Read | Grants read access to repository metadata, such as repository names, descriptions, and other settings. This scope is essential for accessing basic repository information. |
| Pull requests | Read | Allows read access to pull requests and related comments. |
| Webhooks | Read & Write | Provides the ability to manage repository webhooks. This includes creating, updating, listing, and deleting webhooks |
## Connecting to GitHub Enterprise Repository
The overall process is similar to a private repository connection through cloud personal access token, but Appcircle allows you to directly connect through GitHub Enterprise self-hosted URL.
First, select **GitHub** and then **GitHub Enterprise** under **Create a New GitHub Enterprise Connection** through the menu:
To connect to a self-hosted GitHub Enterprise instance, use the following fields when selecting the **GitHub Enterprise** option:
- **Connection Name**: A custom name to identify this connection.
- **GitHub Server URL**: Your GitHub instance URL (e.g., `https://github.company.com`)
- **Username**: The GitHub username of the account owning the token.
- **Personal Access Token**: The fine-grained token generated in your GitHub profile for API or repository access.
If you are not sure what those are, contact your system administrator.
## FAQ
### Unable to grant access to a GitHub organization
If you are unable to grant access to a specific organization while connecting to GitHub, it is likely that the permission for Appcircle needs an update from the organization application access settings.
To resolve, go to Organization Settings -> Third-party access and press edit next to Appcircle to authorize it for the organization.
---
## Connecting to GitLab
If you authorize Appcircle to access your repositories on GitLab, you can select the repository that you want to connect in the next screen.
After you click on **GitLab**, the following screen will appear. This will let you choose between selecting a repository that you are already authorized to do with Appcircle or asking your consent about authorizing more repositories.
When you successfully authorize your account, the following screen will appear to let you select one for connection:
After the connection is successful, you can [view your newly created profile](/build/build-process-management/profile-creation#profile-listing) and start building!
## Connecting to GitLab Cloud Repository
Appcircle allows connecting to GitLab Cloud repositories using two different authentication methods:
- **OAuth2 Connection**
Click **Get Repositories from GitLab Cloud (OAuth2)** to authorize Appcircle via your GitLab account. You will be redirected to GitLab to approve repository access.
- **Personal Access Token (User-Level)**
Use this method to manually connect using a GitLab Personal Access Token (PAT). You will be required to fill out:
- Connection Name
- GitLab Server URL (e.g., `https://gitlab.com`)
- Username
- Personal Access Token
### OAuth2 and Personal Access Token Permissions for GitLab Integration
The following table details the OAuth permissions required for Appcircle to connect with GitLab. These permissions grant read access to projects, repositories, pull requests, and webhooks, ensuring proper functionality when integrating with GitLab via OAuth2 and Personal Access Token.
| Scope | Description |
|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| api | Grants complete read and write access to the scoped project API, including the container registry, the dependency proxy, and the package registry. |
## Connecting to GitLab Self Hosted Repository
The overall process is similar to a private repository connection through SSH, but Appcircle allows you to directly connect through GitLab Self Hosted URL.
:::caution
GitLab's version must be **13.12.9** or higher.
:::
First, select **GitLab** and then **Personal Access Token (User-Level)** under **Create a New Gitlab Server Connection** through the menu:
To connect to a self-hosted GitLab instance, use the following fields when selecting the **Personal Access Token (User)** option:
- **Connection Name**: A custom name to identify this connection.
- **GitLab Server URL**: Your GitLab instance URL (e.g., `https://gitlab.company.com`)
- **Username**: The GitLab username of the account owning the token.
- **Personal Access Token**: The token generated in your GitLab profile for API or repository access.
If you are not sure what those are, contact your system administrator.
:::caution
### Outbound Requests
When you connect to a GitLab repository by creating a profile on Appcircle, Appcircle tries to create webhooks on the GitLab repository.
If your Appcircle server has a local IP address like `10.10.140.20`, you may get an error while connecting to the repository.
To solve this issue, the IP or the Appcircle API subdomain name should be allowed for outbound requests on the GitLab admin panel.
You can follow the steps below to update outbound requests:
1. You must get access to the **Admin Area** of the GitLab server.
2. Expand the "Settings" button at the bottom left.
3. Click on the "Network" button to access network settings.
4. Expand the "Outbound" requests.
5. Add the IP address or the `api` subdomain of the Appcircle server.
For example, if you are accessing to the Appcircle server dashboard via
- `my.appcircle.spacetech.com`
then, for default server configuration, the `api` domain should be
- `api.appcircle.spacetech.com`
:::
:::caution Connection Notice
For Appcircle to connect to the Self Hosted GitLab Instance, your connection must be reachable over the network.
:::
Is your self-hosted GitLab instance under enterprise firewall? Learn which IP addresses and ports Appcircle uses to function under the whitelist documentation:
Accessing Repositories in Internal Networks (Firewalls)
### Token Creation
- [Personal Access Token GitLab Documentation](https://docs.gitlab.com/ee/security/token_overview.html#personal-access-tokens)
Personal Access Token from user works to connect your repository through Appcircle. That being said, **Personal Access Token** is used to authorize every repository the user has access to.
### Check Token
You can follow the steps below to check if your token is valid.
- Open the terminal and issue the following command
```bash
curl "http://YOUR_GITLAB_HOST/api/v4/projects?private_token=YOUR_TOKEN"
```
Above command should print out your projects. If you don't see an output, please check your token and GitLab address.
:::caution
Please also make sure that the output doesn't show any reference to `localhost`. If you see `localhost`, you need to configure GitLab and put the correct address of your GitLab instance.
:::
### Webhook SSL Verification
When integrating GitLab with your self-hosted Appcircle server using HTTPS, webhooks are sent securely over an encrypted connection (HTTPS). To establish this connection, GitLab must trust the SSL certificate of your Appcircle server. This requires the GitLab to trust the SSL certificate of the Appcircle server.
If you encounter a "self-signed certificate in certificate chain" error during integration, you have two options to resolve the issue:
#### 1. Trust the SSL Certificate (recommended)
To establish a secure connection between your self-hosted Appcircle server and the GitLab server, you need to trust either the SSL certificate of the Appcircle server or the issuer certificate of the server's certificate in your GitLab configuration.
For detailed instructions on how to install custom public certificates and configure trust in GitLab, refer to GitLab's documentation: [Install Certificates](https://docs.gitlab.com/omnibus/settings/ssl/#install-custom-public-certificates).
#### 2. Disable the SSL verification (not recommended)
Alternatively, you can choose to disable SSL verification for your AppCircle server's webhook connection in GitLab. While this means that GitLab will not attempt to validate the certificate, it is important to note that webhooks will still be sent over an encrypted HTTPS connection but in an insecure way.
:::caution
This approach can create security vulnerabilities such as man-in-the-middle (MITM) attacks.
:::
Take the following steps to disable the SSL verification of the webhook:
1. Go to the Git repository that you have connected to the Appcircle.
2. Open the webhook settings of that Git repository.
3. Click on the **Edit** button next to the webhook.
4. Scroll down to see the **SSL verification** setting.
5. Deselect the **Enable SSL verification** checkbox.
---
## Connecting to Private Repository via SSH
### Using Direct SSH Key
If you use a private repository using an SSH Key, you need to have an SSH key pair ready and enter your private key into Appcircle so Appcircle can access your repository.
:::caution
For the SSH key field in the repository connection, the private key is required. The public key is entered/stored in the Git provider while the private key is entered in Appcircle.
:::
:::caution
If you are using Azure DevOps Server as a Git provider, its version must be 2022 or later.
Azure DevOps Server 2020 and older versions are not supported due to reduced security.
:::
To generate a new key pair, you can run the following command:
```bash
ssh-keygen -t rsa -b 4096 -P '' -f ./appcircle-ssh -m PEM
```
**PowerShell**
```bash
ssh-keygen -t rsa -b 4096 -P '""' -f ./appcircle-ssh -m PEM
```
**Command Prompt**
```bash
ssh-keygen -t rsa -b 4096 -P "" -f ./appcircle-ssh -m PEM
```
:::caution
SSH keys generated should not contain a password. If ssh-keygen prompts you for a password, simply press Enter to skip the password prompt. Verify that your `appcircle-ssh` file was created without the header `Proc-Type: 4, ENCRYPTED`.
:::
Two files will be created as `appcircle-ssh.pub` (Public key) and `appcircle-ssh` (Private key).
You can then run the `cat ./appcircle-ssh` command and enter its output to Appcircle and run the `cat ./appcircle-ssh.pub` command and enter its output to the SSH keys section of the Git provider.
Select **Connect via SSH** through the connection selection.
Then, enter your relevant information to connect to the private repository:
After the connection is successful, you can [view your newly created profile](/build/build-process-management/profile-creation#profile-listing) and start building!
:::info
To enable triggered auto builds with webhooks for SSH repository connections, please refer to the following guide: [Build Manually or Automatically with Webhooks and Triggers](/build/build-process-management/build-manually-or-with-triggers)
:::
:::caution
### Connection Notice
If your SSH server runs on a different port, you should add the port number to your connection string.
`ssh://git@mydomain.com:port/path/to/repo.git`
For Appcircle to connect to the self hosted repositories, your connection must be reachable over the internet.
:::
Is your self-hosted GitLab instance under an enterprise firewall? Learn which IP addresses and ports Appcircle uses to function under the whitelist documentation:
Accessing Repositories in Internal Networks (Firewalls)
### How to connect to AWS CodeCommit repositories through SSH?
AWS CodeCommit requires the creation of a dedicated user for repository connections through SSH (i.e. the root user cannot be used for this purpose).
- First, create a user in AWS IAM and assign the following permissions to the user:
- Go to IAM -> Users -> User -> Security credentials and select "Upload SSH key".
- Take a note of the SSH key ID generated by AWS as follows:
- Once you log in with the newly generated user and copy the repository URL in SSH format, you will receive the URL as follows: `ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo`
- For the SSH connection to be initialized, you need to add the public key to your URL to have it in the following format, which then can be entered in Appcircle to be used in SSH connections.`ssh://Your-SSH-Key-ID@git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo`
## FAQ
### Issues in connecting to the repositories with SSH
For the SSH connections, a key pair in PEM format is required. The public key is entered/stored in the Git provider while the private key is entered in Appcircle.
Please refer to [this guide for the commands to generate a compatible key pair](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) for SSH connections.
Using multiple SSH keys is not recommended. Instead, you should create a single SSH key that has access to all the private modules.
If you want to use multiple SSH keys, you need to complete the below steps:
- Add your SSH key(s) as an environment variable group as a file.
- Select that environment group on your config screen.
- Use the below custom script to add that key.
- Each key name should be unique. Appcircle's Activate SSH component uses `appcircle_ssh` as a key name.
```bash
set -e
if [ -z "$MY_OTHER_SSH_KEY" ]
then
echo "MY_OTHER_SSH_KEY is not provided. Skipping step."
exit 0
fi
echo "Create a file to save the RSA SSH private key"
mkdir -p ~/.ssh
echo "$AC_REPOSITORY_SSH_KEY" >> ~/.ssh/appcircle_new_ssh
chmod 600 ~/.ssh/appcircle_new_ssh
echo "Starting a new ssh-agent"
eval $(ssh-agent)
echo "Add the SSH private key to the ssh-agent"
ssh-add ~/.ssh/appcircle_new_ssh
echo "Exporting SSH_AUTH_SOCK=$SSH_AUTH_SOCK"
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $AC_ENV_FILE_PATH
```
### Accessing internal/on-premise repositories
The only available option for connecting to the internal/on-premise repositories is to use SSH and whitelist Appcircle resources if the repositories are not accessible from the public internet.
Please refer to [this guide for connecting to the repositories in internal networks](https://docs.appcircle.io/build/manage-the-connections/accessing-repositories-in-internal-networks-firewalls).
### How to connect to AWS CodeCommit repositories through SSH?
AWS CodeCommit requires the creation of a dedicated user for repository connections through SSH (i.e. the root user cannot be used for this purpose).
Please refer to [this guide for creating a user for SSH connections](https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-ssh-unixes.html).
- First, create a user in AWS IAM and assign the following permissions to the user:
- Go to IAM -> Users -> User -> Security credentials and select "Upload SSH key".
- Take a note of the SSH key ID generated by AWS as follows:
- Once you log in with the newly generated user and copy the repository URL in SSH format, you will receive the URL as follows: `ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo`
- For the SSH connection to be initialized, you need to add the public key to your URL to have it in the following format, which then can be entered in Appcircle to be used in SSH connections.`ssh://Your-SSH-Key-ID@git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo`
---
## Connecting to Public Repository
Since public repositories don't require any authentication or connection, the actions that can be taken with public repositories are limited. You will only have read-only access to the specified repository. Only use public repositories if you plan to use the profile for:
- Testing & Previewing Appcircle
- Benchmarking build times to see how fast we are 🚀
- Not planning to use the profile for the long term.
#### Using a Git Provider?
If your repository is located under these providers, Appcircle has built-in support to automatically connect and do the automated work for you. All you need to do is click on the appropriate button in the profile setup page (image below).
For more information on your provider, see the links below:
- [Github](/build/manage-the-connections/connection-guides/connecting-to-github)
- [Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket)
- [GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab)
#### Using a Private Git Server?
If you plan to use Appcircle to connect your private repository, please refer to [connecting to private repositories documentation](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) for more information.
### Public Repository Connection
When you enter the profile after the build, the following screen will appear. Click on **Connect via URL** to connect a public repository.
:::tip
Clicking **Quick start using the sample repository** will also connect the relevant sample project with a public connection.
:::
After you click on **Connect via URL**, the following screen will appear and let you enter an URI.
Enter the URL of your repository, or continue with the sample project if you plan to preview Appcircle.
:::tip
Public connection refers to the HTTP(s) connection by Git Providers. SSH links in public repositories are not accepted.
:::
After the connection is successful, you can [view your newly created profile](/build/build-process-management/profile-creation#profile-listing) and start building!
:::info
### Webhook Events
Keep in mind that certain hook events **will not work** with a public connection.
:::
---
## Adding a Build Profile & Connecting a Repository
# Connection Guides
You can connect GitHub through a GitHub app or Bitbucket and GitLab repositories to your build profile through OAuth apps. Alternatively, you can connect private repositories through SSH and public repositories directly on GitHub, Bitbucket, GitLab, and other compatible Git providers such as Azure DevOps and AWS CodeCommit. ([Please refer here for more information on AWS CodeCommit connections.](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh#how-to-connect-to-aws-codecommit-repositories-through-ssh-1))
You can also connect to your self-hosted Bitbucket and GitLab account directly within Appcircle.
If you authorize Appcircle to connect to your Github, BitBucket, or GitLab account, you can auto-build your project with hooks, get build statuses, and the full list of commits. If you connect to a repository through SSH or through a public URL, you need to [set up webhooks manually](/build/build-process-management/build-manually-or-with-triggers#setting-up-manual-webhooks-for-ssh-and-public-repositories).
When the "Autofill" toggle is activated on the **Select Repository** popup, Appcircle will try to create a default configuration using the selected repository and fill in the necessary fields.
:::caution
When you have exceeded the build limit of your plan, Appcircle will not be able to **Autofill** your build profile, although you activated the toggle.
:::
You can refer to the links below for a detailed explanation on connecting a repository from GitHub, GitLab, Azure, and other platforms:
* [Connecting to GitHub](/build/manage-the-connections/connection-guides/connecting-to-github)
* [Connecting to GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab)
* [Connecting to Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket)
* [Connecting to Azure DevOps](/build/manage-the-connections/connection-guides/connecting-to-azure)
* [Connecting to Public Repository](/build/manage-the-connections/connection-guides/connecting-to-public-repository)
* [Connecting to Private Repository via SSH](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh)
* [Connecting to Multiple Instances](/build/manage-the-connections/connection-guides/connecting-multiple-instance)
## FAQ
## Repository Connection Issues
Please note that currently only Git repositories are supported. Any third party version control repositories need to be transferred to a proper Git repository on either GitHub or Bitbucket.
### **How to change your connected GitHub, Bitbucket, or GitLab account?**
You will need to go to your GitHub, Bitbucket, or GitLab account and revoke access to Appcircle and then reconnect your account from Appcircle.
### Unable to see the repositories in the connected repository provider
Please check if you have owner/admin access in the specific organization from which the repositories will be connected. Appcircle does not allow connections to the repositories with a member-level access.
### Error accessing the repository. Please check if the repository exists or if you have the required privileges.
- Only members who have an admin role on the repository or are owners of the organization can install the GitHub app in an organization that owns that repository.
- Only members who have an admin role on a repository or are owners of the organization can connect a repository to a profile.
If you still can't solve your issues, ask on our Slack page. Our community and our support engineers will help you whenever they're available:
---
## Manage the Connections
# Connections
The Connections page is a feature where we can check and edit the connections of the Git providers we are connected to. You can access this page from the left bar in the Build module.
On this page, you can view **OAuth** and **PAT** (Personal Access Token) connections.
The tags next to the connections on your list display the connection type — whether it’s Cloud, Self-Hosted, and whether it uses an HTTP Token or a Personal Access Token.
:::info
If you have not previously connected to a Git provider on Appcircle, i.e., created a profile and not connected a repository, you will not see any connection on this page.
:::
## Connection Guides
You can connect GitHub through a GitHub app or Bitbucket and GitLab repositories to your build profile through OAuth apps. Alternatively, you can connect private repositories through SSH and public repositories directly on GitHub, Bitbucket, GitLab, and other compatible Git providers such as Azure DevOps and AWS CodeCommit.
## Connection Management
You can connect GitHub, GitLab, Bitbucket and Azure remote repositories. Different types of connections have different connection details in the connection settings.
## Accessing Internal Networks
In certain cases, the source codes of the apps may be stored in internal repositories instead of the cloud providers. If these internal repositories are accessible from the public internet, then you can use Appcircle without any additional configuration.
---
## Connection Management
## Connection Settings
You can see the connection details by clicking the **"Connection Settings"** button in the build profile.
Different types of connections have different connection details in the connection settings.
### OAuth Connection
For an OAuth connection, the details will be **"Provider"**, **"Token Owner"**, **"Code"**, **"Expire Access Token Date"**, **"Expire Refresh Token Date"**, **"Refresh Token"**, and **"Token"**.
### PAT Connection
For a PAT (personal access token) connection, the details will be **"Token Owner"**, and **"Personal Access Token"**.
:::info
In this section, you can view the PATs you have previously added, if any, and change them profile-specific.
You only need to make sure that the modified token has the required authorizations for the relevant repository.
:::
## Disconnect Build Profile
You can disconnect the build profile from the Git provider by using the **Disconnect** button below.
When you click on the "Disconnect" button, Appcircle will bring up a warning dialog box for confirmation.
When we open a disconnected build profile, Appcircle will bring us a popup to quickly **Reconnect** build the profile.
If you do not want to connect again at that moment, you can do it later by clicking the "Reconnect" button next to the "Connection Settings".
:::info
If you disconnect a build profile, only that build profile is disconnected from the Git provider.
When you reconnect a build profile again, only the relevant build profile will be connected again.
:::
:::caution
On the other hand, connection operations done from the **[Connections](/build/manage-the-connections)** page affect all relevant build profiles using those connections.
:::
## Change Git Provider and Reconnect
Appcircle allows changing the Git provider while reconnecting a profile that has been disconnected.
For example, assume that a build profile was previously connected to GitLab and then its Git repository had been moved to GitHub. In this case, you can select the new Git provider for that build profile by clicking the "Reconnect" button next to "Connection Settings".
Appcircle will display the Git providers and "Connect via SSH" connection options in a selectable list.
Here you can select the Git provider you want to change or the "Connect via SSH" method regardless of the Git provider.
Once the connection operations are completed, the Git provider redirects to the Appcircle build profile with the repository selection window.
After you select the relevant Git repository and "Save", the build profile will be connected to the new Git provider.
:::caution
After changing the Git provider and reconnecting the repository, you can use the existing branches that are also available in the new repository. When you try to **Start Build** with these branches, you should see the up-to-date "Commit ID" from the new repository.
Unavailable branches from the old repository connection will be inactive. You can see them in the branch list, but Appcircle does not allow building with the branches that do not exist in the new repository. These kinds of branches will be unusable.
:::
:::tip
While switching from one connection to another type of connection, the older connection method is not important.
You can select one of the listed options and switch to that one without considering anything about the previous one.
:::
:::info
While changing the Git provider, your previous builds, tests, configurations, workflows, triggers, and branch list will not be deleted.
:::
## Change Owner
The **token owner** of a build profile can now be changed without the need to create a new build profile on Appcircle. The **Change Owner** button in the build profile **Connection** detail will help you change the connection ownership so that you can resolve the broken connections or misconfigured repository authorization cases easily by yourself.
:::info
To use this feature, the user must have previously connected to the relevant Git provider on Appcircle via [OAuth](/build/manage-the-connections/reconnect-change-provider#managing-oauth-connections).
:::
:::info
The build profile owners will not see the **Change Owner** button in the **Connection** detail for their build profiles.
:::
When you browse the same build profile with a different member within the same organization, the **Change Owner** button will be visible in the window that's opened when we click on the **Connection Settings** button.
After clicking on the **Change Owner** button and giving approval on the confirmation screen that appears, the process of taking token ownership of the build profile connection will begin.
:::caution
The connection ownership change will be permitted for users who are in the same organization (team members) and have **Manager** role in the **build profile** scope.
In addition, the user who wants to take ownership of the connection must also have access to the repository on the relevant Git provider.
:::
When the process is completed successfully, you can click on the **Connection Settings** button again to see the changed ownership of the build profile connection. In the window that's opened, there won't be a **Change Owner** button because you are now the profile owner.
## Managing OAuth Connections
### Revoke OAuth Connections
**Revoke Token** revokes the token of the Git provider on the Appcircle side. On the Git provider side, the token is still active and available. Appcircle cannot revoke the token from the provider.
A revoked connection disconnects all build profiles connected to the respective Git provider. In this case, Appcircle shows a clear warning message. Here, you can see all the affected profiles.
When we revoke a Git provider successfully, the "Revoke Token" button disappears. If we reconnect using the **Refresh Token** button, the "Revoke Token" button will appear again.
:::info
If we open one of the affected build profiles after applying a revoke for a Git provider, we should see the disconnected build profile state in the UI.
If we reconnect this profile, not only the related build profile but also all other build profiles belonging to that Git provider will be connected.
:::
### Reconnect OAuth Connections
If we want to reconnect to the Git provider, we can use the **Refresh Token** button.
The `refresh token` is received while connecting to the Git provider, and it's used when needed, for instance, in reconnection or token expiration cases.
The refreshing connection action reconnects all previously linked and disconnected build profiles of the corresponding Git provider in Appcircle. Here again, all affected build profiles will be shown.
When the **Refresh Token** button is clicked, Appcircle redirects to the relevant Git provider's page. After giving the necessary permissions there, the connection will be restored.
:::info
If the connection to the Git provider is active and the **Refresh Token** button is clicked, Appcircle will re-establish the connection.
:::
## Managing PAT Connections
The PAT connection list section on the right-hand side has a list of connections that were made using a personal access token.
The list first shows the logo of the Git provider we're connecting to, then the name we gave to the connection (when multiple instances are used), and finally the URL of the Git provider we're connecting to.
### Adding PAT Connection
The "Add New" button at the top of the PAT connection list on the right side allows us to add PAT (Personal Access Token) without creating a new build profile. Then you can use that PAT connection on existing build profiles or while adding a new build profile.
After clicking on the "Add New" button, Appcircle will ask us to select a Git provider and fill in the necessary information according to the Git provider, just like in the build profile PAT connection.
:::info
The name you defined in the **Connection Name** section must be unique for each Git provider.
For example, if you have created a PAT named "my-secret-pat" for GitHub, you cannot create another PAT with the same name for GitHub.
But you can create a PAT named "my-secret-pat" for GitLab or Bitbucket, for instance.
:::
:::info
In Azure DevOps Server connections, the **Owner Username** field on Appcircle corresponds to the **Collection Name** on Azure.
:::
Now you're ready to use the added PAT connection in your build profiles. While making a new connection, you can see the PAT connection in the available connections list after selecting the Git provider.
### Editing PAT Connections
We can see the details of the PAT connection with the **Edit** button on the right side. These are **Provider**, **Instance URL**, **Token Owner**, **Token**, and **PAT**.
In the **Connection Edit**, we can change the PAT (Personal Access Token) value.
However, we must make sure that the value we change here is correct and that it was created on the Git provider correctly. Otherwise, the affected build profile or profiles will not be connected.
:::caution
In the **Connection Edit**, you can see the build profiles where PAT is used under "Affected Build Profiles".
Changing a PAT value will affect all the build profiles shown here.
:::
:::tip
While editing PAT connections, you can also write the PAT value using environment variables.
You can review [Using Environment Variables For SSH And PAT (Personal Access Token) Connections](/build/build-environment-variables#using-environment-variables-for-ssh-and-pat-personal-access-token-connections-of-the-git-provider) page for details.
:::
### Deleting PAT Connections
You can delete a Personal Access Token (PAT) connection by clicking on the **Delete** next to the respective entry in your list of PAT connections.
Upon clicking the **Delete** button, Appcircle will prompt you to enter the name of the PAT Connection to confirm the deletion operation. After entering the connection name, simply click **Delete** on the pop-up screen.
:::warning
If you have an existing Build profile that would be affected by the deletion of the PAT Connection, Appcircle will display a warning message listing the affected builds.
You will need to disconnect them before you can delete the PAT connection.
For more information about disconnecting a build profile please refer to the related [documentation](/build/manage-the-connections/reconnect-change-provider#disconnect-build-profile).
:::
---
## Android 11+ Signing for Google Play
As per Google's update on Android 11 behavior changes, there is an important (breaking) change regarding app signing.
https://developer.android.com/about/versions/11/behavior-changes-11#minimum-signature-scheme
> Apps that target Android 11 (API level 30) that are currently only signed using APK Signature Scheme v1 must now also be signed using [APK Signature Scheme v2](https://source.android.com/security/apksigning/v2) or higher. Users can't install or update apps that are only signed with APK Signature Scheme v1 on devices that run Android 11.
In order to adapt your application, you need to enable V2 signing through either:
- Appcircle (Recommended)
- In your project
### Enable V2 Sign in Appcircle
In order to keep your config in Appcircle, you need to navigate through:
1. Your workflows.
2. Select a workflow.
3. Edit the **Android Sign** workflow.
4. Set V2 Sign to either **true** or **false**.
Alternatively, you can accomplish the same within environment variables. The environment variable for this action is `AC_V2_SIGN`.
:::tip
You can find more information about why to use them and how to use them in the [Environment Variables](/environment-variables) section.
:::
### Enable V2 Sign Through the Android Project (build.gradle)
Alternatively, you can use `build.gradle` instead to specify the signing you will use.
The current Android Sign step in Appcircle utilizes [jarsigner to sign apps](https://developer.android.com/studio/build/building-cmdline#bundle_build_gradle) with the APK Signature Scheme v1 and the alternative _apksigner_ cannot be used to sign app bundles (AAB).
The solution for this is to utilize signing in Gradle within the app. A sample build.gradle file that utilizes APK Signature Scheme v2 can be found at [https://github.com/appcircleio/appcircle-sample-android/blob/v2-sign/app/build.gradle](https://github.com/appcircleio/appcircle-sample-android/blob/v2-sign/app/build.gradle) and the sample code can be seen below:
```groovy
signingConfigs {
release {
if (System.getenv('AC_APPCIRCLE')) { // new configuration for Appcircle
println 'Running on Appcircle'
keyAlias "${System.getenv("AC_ANDROID_ALIAS")}"
keyPassword "${System.getenv("AC_ANDROID_ALIAS_PASSWORD")}"
storeFile file("${System.getenv("AC_ANDROID_KEYSTORE_PATH")}")
storePassword "${System.getenv("AC_ANDROID_KEYSTORE_PASSWORD")}"
} else {
println 'Running on local' // Your old configuration
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
}
// Rest of your build.gradle
```
```kotlin
signingConfigs {
create("release") {
if (System.getenv()["AC_APPCIRCLE"].toBoolean()) { // new configuration for Appcircle
println("Running on Appcircle")
storeFile = file(System.getenv()["AC_ANDROID_KEYSTORE_PATH"])
storePassword = System.getenv()["AC_ANDROID_KEYSTORE_PASSWORD"]
keyAlias = System.getenv()["AC_ANDROID_ALIAS"]
keyPassword = System.getenv()["AC_ANDROID_ALIAS_PASSWORD"]
} else {
println("Running on local") // Your old configuration
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
}
}
}
// Rest of your build.gradle.kts
```
:::danger
You need to either sign with Appcircle Android Sign Step or via Gradle. If you're using Appcircle's Android sign step, remove `signingConfig signingConfigs.release` block from your `build.gradle`.
:::
:::info
If you're using **Gradle** to sign your APK file, you may need to add `v1SigningEnabled` and `v2SigningEnabled` to your signing configurations to install your APK file on both old and new Android versions.
```groovy
signingConfigs {
release {
if (System.getenv('AC_APPCIRCLE')) { // new configuration for Appcircle
println 'Running on Appcircle'
keyAlias "${System.getenv("AC_ANDROID_ALIAS")}"
keyPassword "${System.getenv("AC_ANDROID_ALIAS_PASSWORD")}"
storeFile file("${System.getenv("AC_ANDROID_KEYSTORE_PATH")}")
storePassword "${System.getenv("AC_ANDROID_KEYSTORE_PASSWORD")}"
v2SigningEnabled true
v1SigningEnabled true
} else {
println 'Running on local' // Your old configuration
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
}
// Rest of your build.gradle
```
```kotlin
signingConfigs {
create("release") {
if (System.getenv()["AC_APPCIRCLE"].toBoolean()) { // new configuration for Appcircle
println("Running on Appcircle")
storeFile = file(System.getenv()["AC_ANDROID_KEYSTORE_PATH"])
storePassword = System.getenv()["AC_ANDROID_KEYSTORE_PASSWORD"]
keyAlias = System.getenv()["AC_ANDROID_ALIAS"]
keyPassword = System.getenv()["AC_ANDROID_ALIAS_PASSWORD"]
isV1SigningEnabled = true
isV2SigningEnabled = true
} else {
println("Running on local") // Your old configuration
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
}
}
}
// Rest of your build.gradle.kts
```
:::
---
## Building Android Applications
# Android Applications
Before starting your first Android app build, please make sure you first create a build profile and connect your Git repository to your build profile. You can refer to the page below for this step:
Connection Guides
After connecting your repository, please add or create your Android Keystore. You can refer to the page below for this step:
Android Keystores
When you are done with the steps above, you can now start building your Android application.
### Build Configuration
First, we need to set up a build configuration. Select the configuration from the **Configuration** section. The first step will be to enter project details. You can enter details manually or click on the "Autofill" button to retrieve them from your project.
### Private Modules
If your project uses private modules, don't forget to add the necessary SSH keys to your workflow steps. You can use `Activate SSH Private Key` step to add your private SSH keys.
Connecting to Private Repository via SSH
You may also use `Authenticate with netrc` step to access your private modules.
https://github.com/appcircleio/appcircle-netrc-component
### Sending the Build Status to the Repository Providers
At the bottom of the config tab, you will see the **Set Commit Build Status** option.
When this option is enabled, the build status for that commit is shared with the repository provider.
### Build Triggers
Appcircle allows you to trigger builds manually or automatically using build triggers.
- On push: Whenever code is pushed to a configured branch, the build is triggered.
- On a tagged push: Whenever a tagged commit is pushed, the build is triggered for that commit. Commits without any tags are ignored.
- On push with selective tags: Whenever a commit includes one of the typed in tags, the build is triggered. You can specify tags with Unix shell-style wildcards to trigger builds.
You can visit the following page for details on build triggers:
Build Manually or Automatically with Webhooks and Triggers
### Signing
The next step on build configuration is Signing. Here, please select the Android Keystore you added at [Android Keystores](/signing-identities/android-keystores) page.
:::info
You can get both unsigned and signed build artifacts based on your configuration. Please note that unsigned builds will not be distributed by email.
:::
### Distribution
The next step on build configuration is Distribution. You can create a new distribution profile at this screen or select a previous profile you created earlier. You can also enable auto deployment features if you need to.
Create a Distribution Profile and Sharing with Testers
:::info
Any previous build can be deployed to the Testing Distribution without the need for rebuilding.
:::
### Environment Variables
The final step on build configuration is Environment Variables.
Appcircle Build module is simple and powerful. You can get your builds instantly just with a few clicks, advanced management of builds is also possible with the environment variables and workflows.
You can define variables and secrets to be incorporated during the build in the Environment Variables submodule so that you don't need to store certain keys and configurations within the repository.
Please see the following page for more information about environment variables:
Why Use Environment Variables and Secrets?
Please click on the Save button and close this modal.
### Workflow Editor
You can use the workflow editor for in-depth configuration of all build steps. Please click on the workflow icon to open and use the workflow editor.
:::info
Any custom operation during the build can be executed through the Custom Script step in the workflow.
:::
For details on using Appcircle's workflow editor, please see the related page below:
What are Workflows and How to Use Them?
### Start Build
You are now ready to start your first build. Select the branch from the left side and click on the **Start Build** button.
Select a configuration, workflow, commit ID and click on **Start Build button**
Appcircle will start building your application. The build log window will open, and you can follow the build process in real time.
:::info
You can safely close the build log window; it won't affect the status of your build. You can come back and click on the build to track the status of your build.
:::
**Distribute Your Build**
Your build will be distributed automatically if you had set up Auto Distribute earlier. You can also manually distribute builds at any time you like.
## FAQ
### chmod: cannot access './gradlew': No such file or directory
Every Android project has a `gradlew` file in the main repository directory. If the Android Build step can't find this file, you need to edit your workflow, find the Android Build Step, and edit the `PROJECT PATH`. If your `gradlew` file is in the `android` folder, you need to write, `./android` in the edit box.
### How can I change the JDK version for autofill?
Appcircle currently has OpenJDK 17 (default), OpenJDK 8, OpenJDK 11 and OpenJDK 21. If you want to use a different Java version for your build pipeline, you can add the [**Select Java Version**](/workflows/common-workflow-steps/select-java-version) step to your workflow.
But unfortunately, you cannot use custom scripts for autofill operations, which make it easy to fill in configuration details while adding a new build profile.
For the autofill, we have two options to choose from.
#### 1. Change `JAVA_HOME` using `gradle.properties`
You can add the `org.gradle.java.home` entry to the `gradle.properties` file in your Android project.
For example, the below entry can be used to change the default Java version to 17 for the "Appcircle Standard macOS Pool (arm64)".
```properties
org.gradle.java.home=/Users/appcircle/.sdkman/candidates/java/17.0.9-zulu
```
You can get the JDK home paths for each build pool from [Android's build infrastructure](/infrastructure/android-build-infrastructure#java-version) Java section.
#### 2. Change `JAVA_HOME` using environment variables
You can use the [environment variables](/build/build-environment-variables) to enable the JDK version your project requires.
For example, you can take the following steps to change the default Java version to 17.
1. Create a variable group that has a variable with the properties below.
1. The key should be `JAVA_HOME`.
2. Value should be `/Users/appcircle/.sdkman/candidates/java/17.0.9-zulu`.
2. Go to the configuration section of the build profile that you want to autofill.
3. Go to the 'Env. Variables' tab in configuration.
1. You should see the variable group that you created in the list.
4. Select the variable group that has `JAVA_HOME` and 'Save' settings.
5. Go back to the config tab and start autofilling there.
You can get the JDK home paths for each build pool from [Android's build infrastructure](/infrastructure/android-build-infrastructure#java-version) Java section.
### Gradle build after Bintray shutdown
```
> Could not resolve com.google.protobuf:protobuf-java-util:3.09.0.
> Could not get resource 'https://jcenter.bintray.com/com/google/protobuf/protobuf-java-util/3.09.0/protobuf-java-util-3.09.0.pom'.
> Could not GET 'https://jcenter.bintray.com/com/google/protobuf/protobuf-java-util/3.09.0/protobuf-java-util-3.09.0.pom'. Received status code 502 from server: Bad Gateway
```
You may experience Gradle build errors if your project uses Bintray resources. Since JFrog has shut down Bintray on May 1, 2021. You should update your Gradle file and move to Maven Central. Replace `jcenter()` with `mavenCentral()` in all your `build.gradle` files. Please be aware that some of your dependencies may not exist on Maven.
### Gradle build daemon disappeared unexpectedly
If you receive a Gradle error similar to the following, it can happen due to 2 reasons:
```
org.gradle.launcher.daemon.client.DaemonDisappearedException: Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)
at org.gradle.launcher.daemon.client.DaemonClient.handleDaemonDisappearance(DaemonClient.java:222)
at org.gradle.launcher.daemon.client.DaemonClient.monitorBuild(DaemonClient.java:198)
at org.gradle.launcher.daemon.client.DaemonClient.executeBuild(DaemonClient.java:162)
at org.gradle.launcher.daemon.client.DaemonClient.execute(DaemonClient.java:125)
```
```
Unexpected error while writing dex file using d8: Java heap space
java.lang.OutOfMemoryError: Java heap space
java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space
```
- Problem with UTF-8 characters in your project or environment variable. Please edit your **gradle.properties** file and add `-Dfile.encoding=UTF-8` argument to `org.gradle.jvmargs` section.
- You have edited **gradle.properties** and put some arguments to the `org.gradle.jvmargs` section. When you modify default JVM arguments, it resets the default `MaxMetaspaceSize` property. You should always add `-XX:MaxMetaspaceSize=256m` to this section to prevent unlimited memory allocation.
If you're using DexGuard, you may need to make the above modifications to your DexGuard configuration as well.
### I received a google-services.json Error but I don't want to push this file to the repository
Secret files such as the google-services.json can be added as a [secret environment variable](/build/build-environment-variables#adding-files-as-environment-variables) and then [selected in the build configuration](/build/build-process-management/configurations#environment-variables-configuration).
Then, you can add a custom script step before the Android build step and move the file to the expected path during the build with a code like the following (where the secret environment variable is named as `GOOGLE_SERVICES_JSON`) :
```bash
cd $AC_REPOSITORY_DIR/
mv $GOOGLE_SERVICES_JSON $AC_REPOSITORY_DIR/app
```
### Android Keystore Errors
#### Missing keystore path error on Android builds
You may want to build unsigned Android applications. The most common mistake done with this is Appcircle users usually forget to disable the Sign Application step in the workflow.;
If you do not select a keystore in the build configuration, you need to disable the Sign Application step, or your build will fail.
#### Keystore was tampered with or password was incorrect
You may get this error message when the provided password doesn't match the keystore file.
If you are using a debug keystore, simply re-generate it. Otherwise, please make sure you have the correct keystore/password combination.
After a Build
---
## .NET MAUI Applications
This guide gives necessary information about the steps that should be followed to successfully build and publish a [.NET MAUI](https://dotnet.microsoft.com/en-us/apps/maui) app with Appcircle.
It's an introduction to the basic steps such as building, code signing, and app publishing. Although these steps are minimum requirements for a mobile app build pipeline, you should go on with other sections of the Appcircle documentation for numerous advanced CI/CD features.
If you don't have a .NET MAUI app already or want to follow the steps quickly for a fast evaluation, you can use the [sample app](https://github.com/dotnet/maui-samples/tree/main/8.0/Apps/Calculator) Calculator from the `dotnet/maui-samples` repository. To simulate a .NET MAUI repository, it will be good to clone the app folder and add it as a repository to your own Git provider.
:::tip
Some Appcircle features might not be supported for .NET MAUI build profiles on the dashboard, or you might need to do some extra customizations in the custom scripts to use them.
In this case, do not hesitate to [contact us](https://appcircle.io/support/) for support. We will do our best to support your build pipeline for .NET MAUI apps.
Additionally, **official .NET MAUI support is on our roadmap**, and we are actively working on it to give you the best solution for your .NET MAUI apps.
:::
### .NET MAUI Build for iOS
In order to build a .NET MAUI iOS app on Appcircle follow the steps below.
**1.** [Create](/build/manage-the-connections/connection-guides) a new build profile for your app.
- `iOS` should be selected as the **Target Operating System**, and `Objective-C / Swift` should be selected as the **Target Platform**.
**2.** Connect your repository using a compatible connection method.
:::tip
You can disable the **Autofill** toggle or ignore the output of **Autofill** run since it does not support .NET MAUI app metadata processing.
:::
:::info
As of now, Appcircle does not have a sample repository for .NET MAUI apps. So the **quick start using the sample repository** option will not work for .NET MAUI build profiles. You should use your own repository.
:::
**3.** Configure [Apple Certificates](/signing-identities/apple-certificates) and [Apple Profiles](/signing-identities/apple-profiles) using the **Signing Identities** module on Appcircle.
These certificates and provisioning profiles will be used while building the signed app in the build pipeline.
:::info
Keep in mind that, in order to use iOS Signing Identities in the build pipeline, the [workflow](/workflows) should also have an [**Install Certificates & Profiles**](/workflows/ios-specific-workflow-steps/install-certificates-provisions) step.
:::
**4.** In the [build profile configuration](/build/build-process-management/configurations#config-details), open the **Config** tab and edit the settings below.
- **XCODE VERSION**: Select the Xcode version that's compatible with your app. For instance, `15.4.x`. You can take a look at the table [here](https://github.com/dotnet/maui/wiki/Release-Versions) for the compatible Xcode versions.
- **XCODE PROJECT OR WORKSPACE PATH**: Enter the project or workspace file name. For instance, `Calculator.xcodeproj`.
- **BUILD SCHEME**: Enter a build scheme from your project for the release configuration. For instance, `Calculator`.
:::info
Keep in mind that, in order to switch to the selected Xcode version in the build pipeline, the [workflow](/workflows) should also have an [**Xcode Select**](/workflows/ios-specific-workflow-steps/xcode-select) step.
:::
:::caution
The selected pool in the **SELECT A POOL** list should be the `Appcircle Standard macOS Pool (arm64)` for the Appcircle Cloud or a pool that has **`arm64`** macOS runners for the self-hosted Appcircle.
Intel-based runners are not supported or documented as of now, and you might need extra customizations done in the custom scripts.
:::
**5.** In the [build profile configuration](/build/build-process-management/configurations#config-details), open the **Signing** tab and **add provisioning profile** by selecting from the list of Signing Identities.
:::caution
Currently, **Automatic Code Signing** is not supported for iOS .NET MAUI builds. For this reason, do not enable that toggle and go on with manual code signing as mentioned above.
:::
**6.** In your [workflow](/workflows), use the below custom script as a replacement for the default **Xcodebuild for Devices** step.
:::info
When you remove the **Xcodebuild for Devices** step from the default workflow, the workflow editor might give some errors or warnings for other components that depend on the **Xcodebuild for Devices** step.
Just ignore them and go on with the **Save** button when you remove the **Xcodebuild for Devices** step in the workflow editor.
As an alternative, you can disable the **Step Execution Active** toggle in **Xcodebuild for Devices** step details, which will also make it inactive in the build pipeline.
:::
```bash
set -e
set -x
dotnetVersion="8.0.303"
framework="net8.0-ios"
project="$AC_REPOSITORY_DIR/src/Calculator/Calculator.csproj"
appleCertificate="Apple Distribution: APPCIRCLE, INC. (8U2Z24R99J)"
appleProfile="AppStore Appcircle Sample"
curl -sS -O https://cdn.appcircle.io/dotnet-install.sh
chmod u+x dotnet-install.sh
./dotnet-install.sh --version $dotnetVersion
dotnet="$HOME/.dotnet/dotnet"
$dotnet workload install maui-ios
$dotnet build $project -p:TargetFrameworks=$framework
$dotnet publish $project -p:TargetFrameworks=$framework \
-f $framework -c Release \
-p:ArchiveOnBuild=true \
-p:RuntimeIdentifier=ios-arm64 \
-p:CodesignKey="\"$appleCertificate\"" \
-p:CodesignProvision="\"$appleProfile\"" \
-o "$AC_OUTPUT_DIR"
```
The custom script above does the following operations in order to build a .NET MAUI iOS app:
- Install .NET SDK.
- Install `maui-ios` workload.
- Build the project with dependencies.
- Publish the app for deployment.
The custom script has some **variables that should be changed or customized** for your pipeline.
- **`dotnetVersion`**: You can select a .NET SDK version that's compatible with your project or solution. See [here](https://github.com/dotnet/maui/wiki/Release-Versions) for details.
- **`framework`**: You should select a target framework that the app will be built for, considering your project requirements and .NET SDK version. See [here](https://learn.microsoft.com/en-us/dotnet/standard/frameworks) for details.
- **`project`**: It should be the path to the project file for your app. `$AC_REPOSITORY_DIR` is a [reserved environment variable](/environment-variables/appcircle-specific-environment-variables) that should not be changed since it has the repository path value. You can change the rest of the path to customize it for your project structure.
- **`appleCertificate`**: You should use the certificate name as seen on the [Apple Certificates](/signing-identities/apple-certificates) list. It should also be compatible with the selected provisioning profile that you have selected from the [build profile configuration](/build/build-process-management/configurations#config-details) **Signing** tab.
- **`appleProfile`**: It should be the name of the selected provisioning profile at the [build profile configuration](/build/build-process-management/configurations) **Signing** tab. You can also see the name on the [Apple Profiles](/signing-identities/apple-profiles) list.
When the build pipeline is completed successfully, you will see the signed `.ipa` in the [build artifacts](/build/build-process-management/binary-actions#download-artifacts).
#### References
You can find more information in the following resources for customizing and troubleshooting the .NET MAUI build pipeline.
- .NET Multi-platform App UI [documentation](https://learn.microsoft.com/en-us/dotnet/maui)
- `dotnet-install.sh` script [documentation](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script)
- `dotnet workload install` [documentation](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-workload-install)
- `dotnet build` [documentation](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build)
- `dotnet publish` [documentation](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish)
- [Publish an iOS app](https://learn.microsoft.com/en-us/dotnet/maui/ios/deployment/publish-cli?view=net-maui-8.0) using the command line
### .NET MAUI Build for Android
In order to build a .NET MAUI Android app on Appcircle follow the steps below.
**1.** [Create](/build/manage-the-connections/connection-guides) a new build profile for your app.
- `Android` should be selected as the **Target Operating System**, and `Java / Kotlin` should be selected as the **Target Platform**.
**2.** Connect your repository using a compatible connection method.
:::tip
You can disable the **Autofill** toggle or ignore the output of **Autofill** run since it does not support .NET MAUI app metadata processing.
:::
:::info
As of now, Appcircle does not have a sample repository for .NET MAUI apps. So the **quick start using the sample repository** option will not work for .NET MAUI build profiles. You should use your own repository.
:::
**4.** Add your keystore to [Android Keystores](https://docs.appcircle.io/signing-identities/android-keystores) using the **Signing Identities** module on Appcircle.
These keystores will be used while building the signed app in the build pipeline.
:::info
Keep in mind that, in order to use Android Signing Identities in the build pipeline, the [workflow](/workflows) should also have an [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) step.
:::
**5.** In the [build profile configuration](/build/build-process-management/configurations), open the **Signing** tab and select your app's keystore from the list of Signing Identities.
**6.** In your [workflow](/workflows), use the below **Custom Script** as a replacement of the default **Android Build** step.
:::info
When you remove the **Android Build** step from the workflow, the workflow editor might give some errors or warnings for other components that depend on the **Android Build** step.
Just ignore them and go on with the **Save** button when you remove the **Android Build** step in the workflow editor.
As an alternative, you can disable the **Step Execution Active** toggle in **Android Build** step details, which will also make it inactive in the build pipeline.
:::
```bash
set -e
set -x
dotnetVersion="8.0.303"
framework="net8.0-android"
project="$AC_REPOSITORY_DIR/src/Calculator/Calculator.csproj"
packageFormat="apk"
curl -sS -O https://cdn.appcircle.io/dotnet-install.sh
chmod u+x dotnet-install.sh
./dotnet-install.sh --version $dotnetVersion
dotnet="$HOME/.dotnet/dotnet"
$dotnet workload install maui-android
$dotnet build $project -p:TargetFrameworks=$framework
$dotnet publish $project -p:TargetFrameworks=$framework \
-f $framework -c Release \
-p:AndroidPackageFormats="\"$packageFormat\"" \
-p:AndroidKeyStore=false \
-o "$AC_REPOSITORY_DIR/build/outputs"
# The code section below is for passing unsigned artifacts
# to the Android Sign step. So it should not be customized.
#
# Changing it might cause incompatibility issues for the next step.
$(which ruby) <
### Creating a Flutter Build Profile
Simply create a new build profile as usual and select your target operating system as iOS or Android. Select **Flutter **for **Target Platform**.
Once your build profile is created, click on it and connect your Git repository. For details on this step, please follow the directions on the following page:
Connection Guides
To test drive the Appcircle platform for Flutter app builds, you can also use our sample Flutter App by forking it or adding it as a public repository: [https://github.com/appcircleio/appcircle-sample-flutter](https://github.com/appcircleio/appcircle-sample-flutter)
### Build Configuration for Flutter Applications
Build configuration options are very similar to native iOS or Android applications. You can select configuration details, build triggers, signing identities and distribution options.
### Private Modules
If your project uses private modules, don't forget to add the necessary SSH keys to your workflow steps. You can use `Activate SSH Private Key` step to add your private SSH keys.
Connecting to Private Repository via SSH
You may also use `Authenticate with netrc` step to access your private modules.
https://github.com/appcircleio/appcircle-netrc-component
### Build Configuration for Flutter iOS applications
First, we need to set up a build configuration. Select the configuration from the **Configuration** section. The first step will be to enter project details. You can enter details manually or click on the "Autofill" button to retrieve them from your project.
Your iOS project needs to have an **Xcode project** or an **Xcode workspace** and a **shared scheme** to complete the build configuration successfully. Appcircle can fetch these workspaces and shared schemes from your branch automatically.
You can also select a specific Xcode version if you have certain dependencies or if you want to test your build on a specific version.
### Build Configuration for Flutter Android applications
First, we need to set up a build configuration. Select the configuration from the **Configuration** section. The first step will be to enter project details. For Flutter Android apps, the fetch operation is not required. You can simply select the build mode (e.g. debug or release) and the output type (APK or Splik APK as AAB).
### Build Configuration for Flutter Web applications
Flutter Web apps are built alongside iOS or Android Flutter apps. For more information, please refer to the following guide:
Building Flutter Web Applications
### Sending the Build Status to the Repository Providers
At the bottom of the config tab, you will see the **Set Commit Build Status **option.
When this option is enabled, the build status for that commit is shared with the repository provider.
### Build Triggers
The next section, Triggers, is common for both iOS and Android.
Appcircle allows you to trigger builds manually or automatically using build triggers.
- On push: Whenever code is pushed to a configured branch, the build is triggered.
- On a tagged push: Whenever a tagged commit is pushed, the build is triggered for that commit. Commits without any tags are ignored.
- On push with selective tags: Whenever a commit includes one of the typed in tags, the build is triggered. You can specify tags with Unix shell-style wildcards to trigger builds.
Build Manually or Automatically with Webhooks and Triggers
### Signing Flutter iOS Applications
The next step in the build configuration is Signing. Here, please select the provisioning profile you added in the [Apple Certificates & Provisioning Profiles](/signing-identities) section.
For signing iOS apps, press add, select the bundle ID from the first dropdown and then select a compatible provisioning profile (added from the signing identities module) from the second dropdown.
### Signing Flutter Android Applications
Here, please select the Android Keystore you added in the [Android Keystores](/signing-identities/android-keystores) section. For signing Android apps, simply select a keystore (added from the signing identities module).
### Distribution (Deployment) Configuration
The next step on build configuration is Distribution.
You can select a previously created distribution profile or create a new one in this window. Use the top input box to enter a name for the new distribution profile you want to create. Press enter or click on the green + icon on the right to create the distribution profile.
Finally, check Auto Distribute if you want your build to be deployed to the Testing Distribution automatically and Auto Deployment if you want the build to be deployed to Store Submission automatically.
Create a Distribution Profile and Sharing with Testers
:::info
Any previous build can be deployed to the Testing Distribution without the need for rebuilding.
:::
### Environment Variables
The final tab is to add environment variables to the build. For advanced use cases, you can define variables and secrets to be incorporated during the build in the Environment Variables submodule so that you don’t need to store certain keys and configurations within the repository.
Please refer to the following document for more information on environment variables:
Why Use Environment Variables and Secrets?
### Build Workflows for Flutter Applications
Once you complete your build configuration, you can edit your build workflow. Flutter builds have additional steps for Flutter commands. You can also arrange, add or remove workflow steps using Appcircle's workflow editor and Workflow Marketplace.
To learn more about Appcircle's Workflow editor, see the corresponding page below:
What are Workflows and How to Use Them?
### How to Set a Specific Flutter Version for the Build
To change the Flutter version, open the Flutter Install workflow step from the workflow editor and set the version under the "Selected Flutter Version" field.
You can also set the preferred Flutter version on the config screen. If you don't set any version, `stable` version will be used.
### Starting a Flutter Build and After a Build
You are now ready to start your first build. Select the branch from the left side and click on the **Start Build** button.
Select a configuration, workflow, and commit ID and click on **Start Build button**
:::info
As of Flutter 1.21, the Flutter SDK includes the full Dart SDK. So if you have Flutter installed, you might not need to explicitly download the Dart SDK. If you need to use a different Dart version than the bundled one, you can install it using the below commands.
:::
```bash
brew tap dart-lang/dart
brew install dart
```
```bash
sudo apt-get update
sudo apt-get install apt-transport-https
sudo sh -c 'wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
sudo sh -c 'wget -qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
sudo apt-get install dart
```
## FAQ
### Flutter release mode binaries do not work on the Android emulator
To run a Flutter release mode APK in an emulator, please make sure that the emulator runs with the `x86_64` ABI type and the app is configured accordingly. Emulators with `x86` ABI type are not supported by Flutter . (Please refer to the following GitHub issue on the Flutter repository for more information: [https://github.com/flutter/flutter/issues/28432](https://github.com/flutter/flutter/issues/28432))
### No pubspec.yaml file found error
If the pubspec.yaml file is not present in the default project path, it cannot be detected automatically by the fetch process. In such cases, the file path must be manually defined in the Flutter Build workflow step as the value of the `$AC_FLUTTER_PROJECT_DIR` environment variable.
For reference, please refer to the [Android Flutter Build](https://github.com/appcircleio/appcircle-android-flutter-build-component) and [iOS Flutter Build](https://github.com/appcircleio/appcircle-ios-flutter-build-component) components.
### File not found error
You may get an error like the one below when you're building an Android project.
```
lib/src/core/dependency/myservice.dart:12:8: Error: Error when reading ‘lib/src/data/repositories/CustomerRepository.dart’: No such file or directory
```
This error usually indicates that you didn't name your files according to Dart convention. Linux file system is case sensitive whereas Windows and macOS are not. So if your repository has `customerrepository.dart` but you're importing as `CustomerRepository.dart`, it will not work on Linux machines. To prevent this error, please rename your files and make them all lower case. Please read the following documentation related to styling and naming your files.
Effective Dart: Style | name packages, directories, and source files
### Firebase Version
Your build may fail with following error
```
[!] `GoogleAppMeasurement` requires CocoaPods version `>= 1.10.2`, which is not satisfied by your current version, `1.10.1`.
```
Please edit your workflow and add **Cocoapods Install** step and change the Cocoapods version. You may also set the Cocoapods version if you commit your `Podfile.lock` to your repository.
### CocoaPods could not find compatible versions for pod "Amplify"
When does this occur?
On the first iOS build after upgrading the version of the Amplify packages in your pubspec.yaml.
Example
Below is an example of what the error will look like:
```
[!] CocoaPods could not find compatible versions for pod "Amplify":
In snapshot (Podfile.lock):
Amplify (= 1.6.0)
In Podfile:
amplify_auth_cognito (from `.symlinks/plugins/amplify_auth_cognito/ios`) was resolved to 0.0.1, which depends on
Amplify (> 1.9.2)
You have either:
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
* changed the constraints of dependency `Amplify` inside your development pod `amplify_auth_cognito`.
You should run `pod update Amplify` to apply changes you've made.
```
**Suggested resolution**
- Option 1 (recommended): Run `pod update Amplify AWSPluginsCore AmplifyPlugins` from the iOS dir. This will update the pods that are used by the amplify flutter packages.
- Option 2: Delete the `Podfile.lock` (in the iOS dir) and rebuild. A new Podfile.lock will be generated. Please note, this may cause other non amplify related dependencies to be updated as well.
- Option 3: Run pod update from the iOS dir. This should update your `Podfile.lock` file. Please note, this may cause other non amplify related dependencies to be updated as well.
### Cocoapods Error
`Signing for "MyPod" requires a development team. Select a development team in the Signing & Capabilities editor`
If you are using Xcode 14 and your Flutter version is less than 3.3, your build may fail with the above message. You should modify your Podfile according to the below snippet. Flutter 3.3 fixes this bug. [Related Flutter Issue](https://github.com/flutter/flutter/issues/111757)
```ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
target_is_resource_bundle = target.respond_to?(:product_type) && target.product_type == 'com.apple.product-type.bundle'
target.build_configurations.each do |build_configuration|
if target_is_resource_bundle
build_configuration.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
build_configuration.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
build_configuration.build_settings['CODE_SIGNING_IDENTITY'] = '-'
build_configuration.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = '-'
end
end
end
end
```
---
## Flutter Web Applications
If your app supports Flutter Web, you can also build the Flutter web app along with the [Flutter iOS or Android build](/build/platform-build-guides/building-flutter-applications).
With Appcircle, you can manage your entire Flutter build workflows both for mobile and web without the need for any third party solutions.
Flutter Web Build is available as a workflow step in the workflow marketplace. Just configure your project as you would for iOS or Android and add the Flutter Build for Web step anywhere after the Flutter Install step to include a web build in the workflow.
If you want to build your Flutter project only for the web, you can [add a Flutter Android project in the standard way](/build/platform-build-guides/building-flutter-applications), save your project configuration once, and then remove all the Android-related steps from the build workflow.
:::caution
Make sure to not remove **Export Build Artifacts** from the steps.
:::
In this case, after removing Android-related steps, the workflow will look like the following:
For more information about workflows, refer to the workflow documentation below:
What are Workflows
If you want to deploy your web output automatically, you can use a [Custom Script](https://github.com/appcircleio/appcircle-custom-script-component/) or [upload it to Amazon S3](/workflows/common-workflow-steps/upload-files-to-amazon-s3).
Once your build is configured, it can be built [manually or automatically in the same way as other apps](/build/build-process-management/build-manually-or-with-triggers). With Flutter 2.0, you can build your Flutter web apps in the stable channel. (In Flutter 1.x, it was necessary to use the beta channel.)
After a build, you can download the web build output manually [from the build artifact list](/build/platform-build-guides/building-flutter-applications#starting-a-flutter-build-and-after-a-build) as the `web.zip` file.
:::info
As of Flutter 1.21, the Flutter SDK includes the full Dart SDK. So if you have Flutter installed, you might not need to explicitly download the Dart SDK. If you need to use a different Dart version than the bundled one, you can install it using the below commands.
:::
```bash
brew tap dart-lang/dart
brew install dart
```
```bash
sudo apt-get update
sudo apt-get install apt-transport-https
sudo sh -c 'wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
sudo sh -c 'wget -qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
sudo apt-get install dart
```
---
## Ionic Applications
# Ionic Applications with Custom Scripts
Appcircle supports Ionic applications through custom scripts.
You can use the following project as an example for running Ionic builds on Appcircle:[ https://github.com/appcircleio/appcircle-sample-ionic](https://github.com/appcircleio/appcircle-sample-ionic)
The sample project is built with Vue though other Ionic application types can also be built in a similar manner. For the build, Capacitor is recommended, and this document is based on projects configured to be built with Capacitor in Android Studio or Xcode.
To build an Ionic application, first, add and configure it like a [React Native application](building-react-native-applications).
:::warning `capacitor-cordova-android-plugins`
One important point to note is that the `capacitor-cordova-android-plugins` folder is automatically added to the `.gitignore` file, but it is required during the build process. You can either remove this folder from `.gitignore` or allow it to be regenerated during the build; however, the former is recommended to ensure a successful [fetch](/build/build-process-management/configurations#config-details) operation. For more information, you can refer to the following Git issue for Capacitor: [https://github.com/ionic-team/capacitor/issues/1628](https://github.com/ionic-team/capacitor/issues/1628)
:::
You can then add the custom scripts right before the build steps and run the build normally.
:::warning "npm/Yarn Commands" step
Make sure the "npm/Yarn Commands" step is included in your workflow before the build steps. It doesn’t need to be placed immediately before, but it must come earlier in the sequence.
:::
### Android Custom Script for Ionic Builds
For Android, add the following custom script **immediately before** the "Android Build" step.
```bash
set -e
set -x
cd $AC_REPOSITORY_DIR
sudo npm install -g @ionic/cli
ionic build
ionic capacitor copy android
```
:::tip
If you encounter issues such as missing plugins, outdated configurations, or build failures after adding new dependencies, you can run:
```bash
ionic capacitor sync android
```
This ensures web assets, plugin installations, and config updates are fully synchronized with your native platforms.
:::
### iOS Custom Script for Ionic Builds
For iOS, add the following custom script **immediately before** the "Xcodebuild for Devices" step.
```bash
set -e
set -x
cd $AC_REPOSITORY_DIR
sudo npm install -g @ionic/cli
ionic build
ionic capacitor copy ios
```
:::tip
If you encounter issues such as missing plugins, outdated configurations, or build failures after adding new dependencies, you can run:
```bash
ionic capacitor sync ios
```
This ensures web assets, plugin installations, and config updates are fully synchronized with your native platforms.
:::
---
## iOS Applications
Building iOS applications may be complex and confusing. Appcircle will help you smooth the process and doesn't require any additional configuration files from you.
Before starting your first iOS app build, please make sure you first create a build profile and connect your Git repository to your build profile. You can refer to the page below for this step:
Connection Guides
After connecting your repository, please add or create your iOS certificate and provisioning profile. You can refer to the page below for this step:
Apple Certificates and Provisioning Profiles
When you are done with the steps above, you can now start building your iOS application.
### Build Configuration
First, we need to set up a build configuration. Select the configuration from the **Configuration** section. The first step will be to enter project details. You can enter details manually or click on the "Autofill" button to retrieve them from your project.
Your iOS project needs to have an **Xcode project** or an **Xcode workspace** and a **shared scheme** to complete the build configuration successfully. Appcircle can fetch these workspaces and shared schemes from your branch automatically.
**Share your iOS schemes**
iOS schemes must be marked as shared in order to build your application outside of Xcode. If your application doesn't have a shared scheme, it can only be built using Xcode.
You can check the shared option in your Xcode's scheme manager to mark your application's scheme as shared.
:::caution
Please don't forget to add additional scheme files to your version control.
:::
### Private Modules
If your project uses private modules, don't forget to add the necessary SSH keys to your workflow steps. You can use `Activate SSH Private Key` step to add your private SSH keys.
Connecting to Private Repository via SSH
You may also use `Authenticate with netrc` step to access your private modules.
https://github.com/appcircleio/appcircle-netrc-component
#### Selecting the Xcode Version and Switching to the Xcode Beta
Major Xcode versions are available for building in Appcircle. You can select the preferred Xcode version in the Build Configuration window.
:::caution
It is recommended that the same Xcode version used during development be used for building to avoid potential compatibility issues.
:::
The list of currently available Xcode versions can be found in the following document: [iOS Build Infrastructure](/infrastructure/ios-build-infrastructure)
By default, the most recent stable version of Xcode is selected. If available, you can also switch to the most recent Xcode beta at the top of the list.
### Sending the Build Status to the Repository Providers
At the bottom of the config tab, you will see the **Set Commit Build Status** option.
When this option is enabled, the build status for that commit is shared with the repository provider.
### Build Triggers
Appcircle allows you to trigger builds manually or automatically using build triggers.
- On push: Whenever code is pushed to a configured branch, the build is triggered.
- On a tagged push: Whenever a tagged commit is pushed, the build is triggered for that commit. Commits without any tags are ignored.
- On push with selective tags: Whenever a commit includes one of the typed in tags, the build is triggered. You can specify tags with Unix shell-style wildcards to trigger builds.
You can visit the following page for details on build triggers:
Build Manually or Automatically with Webhooks and Triggers
### Signing
The next step on build configuration is Signing. Here, please select the provisioning profile you added at [Apple Certificates & Provisioning Profiles](/signing-identities) page.
:::info
You can get both unsigned and signed build artifacts based on your configuration.
:::
### Distribution
The next step on build configuration is Distribution. You can create a new distribution profile on this screen or select a previous profile you created earlier. You can also enable auto deployment features if you need to.
Create a Distribution Profile and Sharing with Testers
:::info
Any previous build can be deployed to the Testing Distribution without the need for rebuilding.
:::
### Versioning
The versioning tab will allow you to change the build or version number during the build. You can increase the build number or version number by using different sources and strategies.
Managing iOS Build and Version Numbers
### Environment Variables
The final step on build configuration is Environment Variables.
Appcircle Build module is simple and powerful. You can get your builds instantly just with a few clicks; advanced management of builds is also possible with the environment variables and workflows.
You can define variables and secrets to be incorporated during the build in the Environment Variables submodule so that you don't need to store certain keys and configurations within the repository.
Please see the following page for more information about environment variables:
Why Use Environment Variables and Secrets?
Please click on the Save button and close this modal.
### Workflow Editor
You can use the workflow editor for in-depth configuration of all build steps. Please click on the workflow icon to open and use the workflow editor.
:::info
Any custom operation during the build can be executed through the Custom Script step in the workflow.
:::
For details on using Appcircle's workflow editor, please see the related page below:
What are Workflows and How to Use Them?
### Start Build
You are now ready to start your first build. Select the branch from the left side and click on the **Start Build** button.
Select a configuration, workflow, commit id and click on **Start Build button**
Appcircle will start building your application. The build log window will open, and you can follow build process in real time.
:::info
You can safely close the build log window; it won't affect the status of your build. You can come back and click on the build to track the status of your build.
:::
---
**Distribute your build**
Your build will be distributed automatically if you had set up auto build earlier. You can also manually distribute builds at any time you like.
After a Build
## FAQ
### Xcode Scheme Errors
Your iOS application project needs to have a shared scheme in order to be built outside Xcode. Xcode doesn't share schemes by default, so you will have to do it manually.
1. On Xcode, select **Product** > **Scheme** > **Manage Schemes**
2. Select **Shared** for your `xcproject` or `xcworkspace`
3. The scheme container needs to be set to the corresponding Xcode project or workspace.
4. Please do not forget to add your `.xcscheme` file to version control so it will be uploaded to your Git repository.
### Cocoapods Errors Due to Missing xcworkspace
If you receive a pod error similar to the following, this usually indicates that although pods are used, the build is done with an xcodeproj file:
`error: .../_appcircle_temp/Repository/Obj-C/Pods/Target Support Files/Pods-AEPSampleAppObjC/Pods-AEPSampleAppObjC.release.xcconfig: unable to open file (in target "AEPSampleAppObjC" in project "AEPSampleAppObjC") (in target 'AEPSampleAppObjC' from project 'AEPSampleAppObjC')`
If a pod is used, the xcworkspace must be pushed to the repository, and it must be selected in the build configuration for a successful build.
If you don't want to push the xcworkspace to the repository, you can alternatively enter the xcworkspace path manually in the build configuration. In this case, the xcworkspace will be generated by the Cocapods workflow component.
### Cocoapods Errros Due to Version Mismatch
If you don't set the version of Cocoapods in your Cocoapods Install step, Appcircle installs Cocoapods according to your _Podfile.lock_ file. Don't forget to commit your Podfile.lock file to have the correct version.
### Xcode 15 Known Issue
After the release of Xcode 15, some notable known issues have surfaced. One of them is the `DT_TOOLCHAIN_DIR cannot be used to evaluate` error.
When encountering this error, you will see the following log during the Xcode build for Devices step;
```
DT_TOOLCHAIN_DIR cannot be used to evaluate LIBRARY_SEARCH_PATHS, use TOOLCHAIN_DIR instead (in target 'One of Project Target Name' from project 'Pods')
```
This error typically occurs with Cocoapods version 1.12.1 and older. To resolve it, update your local Cocoapods to a newer version and commit the changes, or update Cocoapods during the workflow at the Cocoapods Install step.
:::info
The resolution for this error is available in Cocoapods version 1.13.0 or higher.
:::
:::danger
If the issue persists after updating Cocoapods, consider updating your iOS minimum deployment target to iOS 13.0 or higher. If the problem still remains, use the script provided below.
:::
:::caution
If you still encounter the same error, you can address it by making the following changes at the end of your `Podfile`:
```ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR")
File.open(xcconfig_path, "w") { |file| file << xcconfig_mod }
end
end
end
```
:::
### Xcode 16 Known Issues
Apple introduces significant changes with each annual Xcode update. Errors and solutions encountered for the first time following the transition to Xcode 16 can be found under this section.
#### Error: `PBXGroup` attempted to initialize an object with unknown ISA `PBXFileSystemSynchronizedRootGroup`
Following the Xcode 16 migration, adding a new target to your project may result in a reference error if the target is not configured correctly. This error occurs because Xcode now writes the reference differently in the `.pbxproj` file, which is essential for compiling the project and contains all project references.
```
Error: PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes:
{
"isa"=>"PBXFileSystemSynchronizedRootGroup", "exceptions"=>["5E7769042CAEDA6A0010DF2F"],
"explicitFileTypes"=>{}, "explicitFolders"=>[], "path"=>"ImageNotification", "sourceTree"=>""
}
```
This error is caused when target files are added to the project as a `folder` rather than as a `group`. Xcode uses a `group` structure to organize files within the project directory and creates references accordingly. If a `folder` is manually created in the project directory outside of Xcode, a misspelled reference may result, leading to the error during the build process.
To resolve this error, follow these steps:
- Open your project on **Xcode**.
- In Xcode, find the relevant file using the project navigator on the left panel.
- Right click and select **`Convert to Group`**.
After this operation, the references of the relevant files will be rewritten.
:::info
After the release of Xcode 16, this issue experienced in older versions was fixed in Ruby's gem library with `1.26.0` or later version of the [**`xcodeproj`**](https://rubygems.org/gems/xcodeproj/versions/1.26.0) library. At Appcircle, we have also applied these updates to our infrastructure and deployed them to our cloud environment.
However, for our customers using self-hosted setups, an image update is required. If you are using Appcircle in a self-hosted environment, the version of the `xcodeproj` library may be **outdated**. To resolve this, either update the runner image or manually increase the version in the build pipeline using a [**Custom Script**](/workflows/common-workflow-steps/custom-script).
You can update the `xcodeproj` library using the following Bash script in your workflow:
```bash
gem update xcodeproj
```
For more information about our infrastructure, please visit the [**iOS Build Infrastructure**](/infrastructure/ios-build-infrastructure#ios-build-environment) documents.
:::
#### Error: Cycle inside `Application Target Name`; building could produce unreliable results
If the necessary dependencies are installed with **SPM** (Swift Package Manager) in the project and there are some `Run Scripts` in the **Build Phase** section in Xcode, you may encounter this error when these scripts do not run in a certain order.
```
Error: Cycle inside ; building could produce unreliable results.
That command depends on command in Target 'Target Name': script phase “Google Plist Run Scrip”
That command depends on command in Target 'Target Name': script phase “Crashlytics”
Target '' has Swift tasks blocking downstream compilation
```
This error may occur if **`Embed Foundation Extensions`** is located under **`Copy Bundle Resources`**. To resolve this issue, try moving **`Embed Foundation Extensions`** to a higher position in the list.
:::info
This issue can also occur in **Xcode 16 and earlier**. However, it is more likely to occur during Xcode 16 migration.
:::
### Provisioning Profile Error
If you receive a provisioning profile error similar to the following, it usually indicates a mismatch between the bundle ID selected in the build configuration and the provisioning profile.
`error: "MyProject" requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor. (in target MyProject from project MyProject)`
In such an error, please check if the correct bundle ID is selected for the build. This is especially the case if you are using different bundle IDs for different release types such as debug or release.
`Signing for "MyPod" requires a development team. Select a development team in the Signing & Capabilities editor`
Your Cocoapods dependencies may also show this error when you try to build your project with Xcode 14. To prevent this, you may try one of the following workarounds.
1. Signing with your own certificates. This requires uploading both development and distribution certificates. Therefore you either need to upload appropriate provisioning profiles or turn on [Automatic Code Signing](/signing-identities/apple-profiles#automatic-signing).
```ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings["DEVELOPMENT_TEAM"] = "YOUR Team ID"
end
end
end
```
2. Skip signing pod bundles.
```ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
config.build_settings['CODE_SIGNING_IDENTITY'] = '-'
config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = '-'
end
end
end
end
```
### iOS Minimum Deployment Target Error
Following the release of new Xcode, and iOS versions, projects containing pods or targets below certain iOS versions may experience simulator-related errors due to unsupported older iOS versions.
During the 'Xcodebuild for Devices' step, you may encounter an error similar to this:
```
ld: file not found: /Volumes/xcode.14.x/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
To prevent this error, please update the minimum deployment iOS versions for the targets in your project.
For your pods, append the following script to the end of your `Podfile`:
```
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
```
```ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
...
## Other config settings
...
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
end
end
end
end
```
### Swift Version Error
If you receive an error similar to the following, the selected Xcode version in the build configuration may be incompatible with the selected Swift version in the project settings.
`SWIFT_VERSION '3.0' is unsupported, supported versions are: ...`
In this case, you need to upgrade the Swift version in the project settings in Xcode and once the build is confirmed to be working locally in the specific Xcode version, it can be retried in Appcircle with the same Xcode version.
---
## React Native Applications
You can build your React Native applications in Appcircle for iOS or Android platforms.
:::info
Appcircle will use your `package.json` file to determine and use the dependencies of your application.
:::
### Creating a React Native Build Profile
Simply create a new build profile as usual and select your target operating system as iOS or Android. Select **React Native** for **Target Platform**.
Once your build profile is created, click on it and connect your Git repository. For details on this step, please follow the directions on the following page:
Connection Guides
### Build Configuration for React Native Applications
Build configuration options are very similar to native iOS or Android applications. You can select configuration details, build triggers, signing identities, and distribution options.
### Private Modules
If your project uses private modules, don't forget to add the necessary SSH keys to your workflow steps. You can use `Activate SSH Private Key` step to add your private SSH keys.
Connecting to Private Repository via SSH
You may also use `Authenticate with netrc` step to access your private modules.
https://github.com/appcircleio/appcircle-netrc-component
### Build Configuration for React Native iOS applications
First, we need to set up a build configuration. Select the configuration from the **Configuration** section. The first step will be to enter project details. You can enter details manually or click on the "Autofill" button to retrieve them from your project.
Your iOS project needs to have an **Xcode project** or an **Xcode workspace** and a **shared scheme** to complete the build configuration successfully. Appcircle can fetch these workspaces and shared schemes from your branch automatically.
**Share your iOS schemes**
iOS schemes must be marked as shared in order to build your application outside of Xcode. If your application doesn't have a shared scheme, it can only be built using Xcode.
You can check the shared option in your Xcode's scheme manager to mark your application's scheme as shared.
:::caution
Please don't forget to add additional scheme files to your version control.
:::
Major Xcode versions are available for building in Appcircle. You can select the preferred Xcode version in the Build Configuration window. You can also set the preferred NodeJS version on this screen. If you don't set any version, `lts` version will be used.
### Build Configuration for React Native Android applications
First, we need to set up a build configuration. Select the configuration from the **Configuration** section. The first step will be to enter project details. You can enter details manually or click on the "Autofill" button to retrieve them from your project.
### Sending the Build Status to the Repository Providers
At the bottom of the config tab, you will see the **Set Commit Build Status **option.
When this option is enabled, the build status for that commit is shared with the repository provider.
### Build Triggers
Triggers is common for both iOS and Android.
Appcircle allows you to trigger builds manually or automatically using build triggers.
- On push: Whenever code is pushed to a configured branch, the build is triggered.
- On a tagged push: Whenever a tagged commit is pushed, the build is triggered for that commit. Commits without any tags are ignored.
- On push with selective tags: Whenever a commit includes one of the typed in tags, the build is triggered. You can specify tags with Unix shell-style wildcards to trigger builds.
### Signing React Native iOS applications
The next step on build configuration is Signing. Here, please select the provisioning profile you added in the [Apple Certificates & Provisioning Profiles](/signing-identities) section.
:::info
You can get both unsigned and signed build artifacts based on your configuration.
:::
### Signing React Native Android applications
Here, please select the Android Keystore you added in the [Android Keystores](/signing-identities/android-keystores) section.
:::info
You can get both unsigned and signed build artifacts based on your configuration. Please note that unsigned builds will not be distributed by email.
:::
### Distribution (Deployment) Configuration
The next step on build configuration is Distribution.
You can select a previously created distribution profile or create a new one in this window. Use the top input box to enter a name for the new distribution profile you want to create. Press enter or click on the green + icon on the right to create the distribution profile.
Finally, check Auto Distribute if you want your build to be deployed to the Testing Distribution automatically and Auto Deployment if you want the build to be deployed to Store Submission automatically.
Create a Distribution Profile and Sharing with Testers
:::info
Any previous build can be deployed to the Testing Distribution without the need for rebuilding.
:::
### Environment Variables
The final tab is to add environment variables to the build. For advanced use cases, you can define variables and secrets to be incorporated during the build in the Environment Variables submodule so that you don’t need to store certain keys and configurations within the repository.
Please refer to the following document for more information on environment variables:
Why to Use Environment Variables and Secrets?
### Build workflows for React Native applications
Once you complete your build configuration, you can edit your build workflow. React Native builds have additional steps for Node and Yarn commands. You can also arrange, add or remove workflow steps using Appcircle's workflow editor and the Workflow Marketplace.
To learn more about Appcircle's Workflow editor, see the corresponding page below:
What are Workflows and How to Use Them?
### Starting a React Native Build and After a Build
To start your first build, just press the start build button – the play button under the actions columns (or push some code to your repo if autobuild is configured.) You will see the build progress and the log in real time.
Once your build is complete, you can now download the binary file or deploy it to Testing Distribution manually (if autodistribute is enabled, it will be sent automatically after a successful build). You can also view or download your build logs at any time.
After a Build
## FAQ
### ERR_OSSL_EVP_UNSUPPORTED
If you receive an error similar to the following, it’s likely that your application or a module you’re using is attempting to use an algorithm or key size that is no longer allowed by default with OpenSSL 3.0.
```
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
```
You can either add the command-line option, `--openssl-legacy-provider` to your build scripts or change your node version to v16.x
### NPM/Yarn specific errors
If you face problems during NPM/Yarn install steps on Appcircle but not on your local machine, you should confirm the following steps:
- [x] Make sure that your packages support the node version you use.
- [x] Make sure that the file interactions that is done on `preinstall` and/or `postinstall` scrips are suitable to be executed on a different machine.
#### Queries to registry.yarnpkg.com return a `404/500/...`
First, you should check the [NPM status page](https://yarnpkg.com/getting-started/qa#queries-to-registryyarnpkgcom-return-a-404500-is-it-down) for possible availability issues.
Our runners have yarn classic (1.x) by default. See the [iOS build agent stacks](/infrastructure/ios-build-infrastructure#ios-build-environment) and the [Android build agent stacks](/infrastructure/android-build-infrastructure#android-build-environment) pages for the exact versions.
On the other hand, yarn modern (2.x) has stability improvements that can fix these kinds of network errors. You can see [here](https://yarnpkg.com/getting-started/qa#why-should-you-upgrade-to-yarn-modern) for details.
Upgrading to the latest versions is critical to a fast and stable yarn experience. So, if you're getting these kinds of errors in your build pipeline, we recommend upgrading your yarn version.
You can see the steps to do the upgrade in the following section. 👇
#### Upgrading From Yarn 1 to Yarn 2 in Pipeline
1. Add a "Custom Script" step to your workflow before the "npm/Yarn Commands" step.
2. It should be a bash script and should have the below content.
```bash
cd $AC_REPOSITORY_DIR
yarn set version berry
yarn --version
yarn config set -H enableImmutableInstalls false
```
When you run the pipeline again with an up-to-date workflow, you should see the upgraded Yarn version in your build logs.
### Disable Flipper SDK on iOS
Flipper can be a good tool for debugging your applications. It still gets built even if it's not being used for release builds. To speed up your builds, Flipper can be disabled on Appcircle by making the Flipper SDK inclusion conditional.
Example Podfile modification:
```ruby
if !ENV['AC_APPCIRCLE']
use_flipper!
post_install do |installer|
flipper_post_install(installer)
end
end
```
:::tip
Appcircle uses the LTS (Long Term Support) node version by default.
:::
You can access how to change your node version and other relative information about workflow steps and configurations on the page below:
React Native Specific Workflow Steps
---
## Xamarin Applications
This guide gives necessary information about the steps that should be followed to successfully build and publish a [Xamarin](https://dotnet.microsoft.com/en-us/apps/xamarin) app with Appcircle.
It's an introduction to the basic steps such as building, code signing, and app publishing. Although these steps are minimum requirements for a mobile app build pipeline, you should go on with other sections of the Appcircle documentation for numerous advanced CI/CD features.
If you don't have a Xamarin app already or want to follow the steps quickly for a fast evaluation, you can use the [sample app](https://github.com/appcircleio/appcircle-sample-xamarin) repository. To simulate a Xamarin repository, it will be good to clone the app folder and add it as a repository to your own Git provider.
:::danger
As of May 1, 2024, Xamarin is no longer supported or updated by Microsoft. **Therefore, Appcircle does not officially support Xamarin and does not guarantee that all Xamarin projects will build without issues.** See the [Xamarin support policy](https://dotnet.microsoft.com/en-us/platform/support/policy/xamarin) for details.
Some Appcircle features might not be supported for Xamarin build profiles on the dashboard, or you might need to do some extra customizations in the custom scripts to use them.
In this case, do not hesitate to [contact us](https://appcircle.io/support/) for support. We will do our best to support your build pipeline for Xamarin apps.
:::
### Xamarin Build for iOS
In order to build a Xamarin iOS app on Appcircle, follow the steps below.
**1.** [Create](/build/manage-the-connections/connection-guides) a new build profile for your app.
- `iOS` should be selected as the **Target Operating System**, and `Objective-C/Swift` should be selected as the **Target Platform**.
**2.** Connect your repository using a compatible connection method.
:::tip
You can disable the **Autofill** toggle or ignore the output of the **Autofill** run since it does not support Xamarin app metadata processing.
:::
:::info
As of now, Appcircle does not have a sample repository for Xamarin apps. So the **quick start using the sample repository** option will not work for Xamarin build profiles. You should use your own repository.
:::
**3.** Configure [Apple Certificates](/signing-identities/apple-certificates) and [Apple Profiles](/signing-identities/apple-profiles) using the **Signing Identities** module on Appcircle.
These certificates and provisioning profiles will be used while building the signed app in the build pipeline.
:::info
Keep in mind that, in order to use iOS Signing Identities in the build pipeline, the [workflow](/workflows) should also have an [**Install Certificates & Profiles**](/workflows/ios-specific-workflow-steps/install-certificates-provisions) step.
:::
**4.** In the [Build Profile Configuration](/build/build-process-management/configurations), open the **Config** tab and edit the settings below.
- **XCODE VERSION**: Select the Xcode version that's compatible with your app. For instance, `14.3.x`.
- **XCODE PROJECT OR WORKSPACE PATH**: The custom script we will use does not require a valid Xcode project path. If you haven't exported your Xamarin project to Xcode yet, you can provide a temporary path. For instance, `temp.xcodeproj`.
- **BUILD SCHEME**: Enter a build scheme from your project for the release configuration. For instance, `TempDev`.
:::info
Keep in mind that, in order to switch to the selected Xcode version in the build pipeline, the [workflow](/workflows) should also have an [**Xcode Select**](/workflows/ios-specific-workflow-steps/xcode-select) step.
:::
:::caution
The selected pool in the **SELECT A POOL** list should be the `Appcircle Standard macOS Pool (arm64)` for the Appcircle Cloud or a pool that has **`arm64`** macOS runners for the self-hosted Appcircle.
Intel-based runners are not supported or documented as of now, and you might need extra customizations done in the custom scripts.
:::
**5.** In the [Build Profile Configuration](/build/build-process-management/configurations#config-details), open the **Signing** tab and **add provisioning profile** by selecting from the list of Signing Identities.
:::caution
Currently, **Automatic Code Signing** is not supported for iOS Xamarin builds. For this reason, do not enable that toggle and go on with manual code signing as mentioned above.
:::
**6.** In your [workflow](/workflows), use the below custom script as a replacement of the default **Xcodebuild for Devices** step. Remove the **CocoaPods Install** and **Increment Build and Version Number** steps from your workflow.
:::info
When you remove the **Xcodebuild for Devices** step from the default workflow, the workflow editor might give some errors or warnings for other components that depend on the **Xcodebuild for Devices** step.
Just ignore them and go on with the **Save** button when you remove the **Xcodebuild for Devices** step in the workflow editor.
As an alternative, you can disable the **Step Execution Active** toggle in **Xcodebuild for Devices** step details, which will also make it inactive in the build pipeline.
:::
```bash
set -e
MONO_VERSION="6.12.0.206"
DOTNET_VERSION="8.0.402"
XAMARIN_IOS_SDK_DOWNLOAD_URL="https://download.visualstudio.microsoft.com/download/pr/ceb0ea3f-4db8-46b4-8dc3-8049d27c0107/3960868aa9b1946a6c77668c3f3334ee/xamarin.ios-16.4.0.23.pkg"
PROJECT_ROOT_DIR="$AC_REPOSITORY_DIR"
IOS_PROJECT_DIR="AppcircleXamarin.iOS/AppcircleXamarin.iOS.csproj"
APPLE_PROFILE_NAME="Adhoc Appcircle Sample"
APPLE_CERTIFICATE_NAME="Apple Distribution: APPCIRCLE, INC. (8U2Z24R99J)"
APPLE_CERTIFICATE_ID=$(security find-identity -v -p codesigning | grep "$APPLE_CERTIFICATE_NAME" | awk '{print $2}' | head -n 1)
APPLE_PROFILE_ID=$(for profile in ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision; do
if security cms -D -i "$profile" | grep -q "Name" && \
security cms -D -i "$profile" | grep -A 1 "Name" | grep -q "$APPLE_PROFILE_NAME"; then
security cms -D -i "$profile" | grep "UUID" -A 1 | grep "" | awk -F '[<>]' '{print $3}'
fi
done)
curl -sS -O https://cdn.appcircle.io/docs/assets/mono_install.sh
chmod u+x mono_install.sh
./mono_install.sh --version $MONO_VERSION
export PATH=$PATH:/Library/Frameworks/Mono.framework/Versions/Current/bin/
curl -sS -O https://cdn.appcircle.io/dotnet-install.sh
chmod u+x dotnet-install.sh
sudo ./dotnet-install.sh --version $DOTNET_VERSION --install-dir /usr/local/share/dotnet
export PATH=$PATH:/usr/local/share/dotnet:$HOME/.dotnet/tools
dotnet tool install --global boots
sudo boots $XAMARIN_IOS_SDK_DOWNLOAD_URL
cd $PROJECT_ROOT_DIR
nuget restore $IOS_PROJECT_DIR
dotnet restore
msbuild $IOS_PROJECT_DIR /t:Build /p:Configuration=Release /p:Platform=iPhone /p:BuildIpa=true /p:OutputPath=$AC_OUTPUT_DIR /p:KeychainPath=$AC_KEYCHAIN_PATH /p:KeychainPassword=$AC_KEYCHAIN_PASSWORD /p:CodesignKey=$APPLE_CERTIFICATE_ID /p:ProvisioningProfileId=$APPLE_PROFILE_ID
```
The custom script above does the following operations in order to build a Xamarin iOS app:
- Install [Mono](https://www.mono-project.com/)
- Install .NET SDK.
- Install Xamarin iOS SDK.
- Build the project with dependencies.
- Publish the app for deployment.
The custom script has some **variables that should be changed or customized** for your pipeline.
- **`MONO_VERSION`**: You can select a Mono version that's compatible with your project or solution. See [here](https://www.mono-project.com/) for details.
- **`DOTNET_VERSION`**: You can select a .NET SDK version that's compatible with your project or solution. See [here](https://versionsof.net) for details.
- **`XAMARIN_IOS_SDK_DOWNLOAD_URL`**: The download link for the Xamarin iOS SDK version you want to install. Copy the link for the version from [here](https://github.com/xamarin/xamarin-macios/blob/main/DOWNLOADS.md).
- **`PROJECT_ROOT_DIR`**: The location of your `.sln` file. Your Git repository is typically saved within the `$AC_REPOSITORY_DIR` inside the runner. However, your .sln file may be located in a subdirectory of this folder. Please specify this. For instance, `$AC_REPOSITORY_DIR/src`
- **`IOS_PROJECT_DIR`**: The location of the `.csproj` file is required for performing iOS-specific builds. In this script, it is `AppcircleXamarin.iOS/AppcircleXamarin.iOS.csproj`.
- **`APPLE_CERTIFICATE_NAME`**: You should use the certificate name as seen on the [Apple Certificates](/signing-identities/apple-certificates) list. It should also be compatible with the selected provisioning profile that you have selected from the [Build Profile Configuration](/build/build-process-management/configurations) **Signing** tab.
- **`APPLE_PROFILE_NAME`**: It should be the name of the selected provisioning profile at the [Build Profile Configuration](/build/build-process-management/configurations) **Signing** tab. You can also see the name on the [Apple Profiles](/signing-identities/apple-profiles) list.
When the build pipeline is completed successfully, you will see the signed `.ipa` in the [build artifacts](/build/build-process-management/binary-actions#download-artifacts).
### Xamarin Build for Android
In order to build a Xamarin Android app on Appcircle, follow the steps below.
**1.** [Create](/build/manage-the-connections/connection-guides) a new build profile for your app.
- `Android` should be selected as the **Target Operating System**, and `Java/Kotlin` should be selected as the **Target Platform**.
**2.** Connect your repository using a compatible connection method.
:::tip
You can disable the **Autofill** toggle or ignore the output of the **Autofill** run since it does not support Xamarin app metadata processing.
:::
:::info
As of now, Appcircle does not have a sample repository for Xamarin apps. So the **quick start using the sample repository** option will not work for Xamarin build profiles. You should use your own repository.
:::
**4.** Add your keystore to [Android Keystores](/signing-identities/android-keystores) using the **Signing Identities** module on Appcircle.
These keystores will be used while building the signed app in the build pipeline.
:::info
Keep in mind that, in order to use Android Signing Identities in the build pipeline, the [workflow](/workflows) should also have an [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) step.
:::
**5.** In the [Build Profile Configuration](/build/build-process-management/configurations), open the **Signing** tab and select your app's keystore from the list of Signing Identities.
**6.** In your [workflow](/workflows), use the below **Custom Script** as a replacement of the default **Android Build** step. Remove the **Android App Post-Processor** and **Increment Build and Version Number** steps from your workflow.
:::info
When you remove the **Android Build** step from the workflow, the workflow editor might give some errors or warnings for other components that depend on the **Android Build** step.
Just ignore them and go on with the **Save** button when you remove the **Android Build** step in the workflow editor.
As an alternative, you can disable the **Step Execution Active** toggle in **Android Build** step details, which will also make it inactive in the build pipeline.
:::
```bash
set -e
MONO_VERSION="6.12.0.206"
DOTNET_VERSION="8.0.402"
XAMARIN_ANDROID_SDK_DOWNLOAD_URL="https://aka.ms/xamarin-android-commercial-d17-5-macos"
PROJECT_ROOT_DIR="$AC_REPOSITORY_DIR"
ANDROID_PROJECT_DIR="AppcircleXamarin.Android/AppcircleXamarin.Android.csproj"
ANDROID_PACKAGE_FORMAT="apk"
curl -sS -O https://cdn.appcircle.io/docs/assets/mono_install.sh
chmod u+x mono_install.sh
./mono_install.sh --version $MONO_VERSION
export PATH=$PATH:/Library/Frameworks/Mono.framework/Versions/Current/bin/
curl -sS -O https://cdn.appcircle.io/dotnet-install.sh
chmod u+x dotnet-install.sh
sudo ./dotnet-install.sh --version $DOTNET_VERSION --install-dir /usr/local/share/dotnet
export PATH=$PATH:/usr/local/share/dotnet:$HOME/.dotnet/tools
dotnet tool install --global boots
sudo boots $XAMARIN_ANDROID_SDK_DOWNLOAD_URL
cd $PROJECT_ROOT_DIR
nuget restore $ANDROID_PROJECT_DIR
dotnet restore
msbuild $ANDROID_PROJECT_DIR /t:Package /p:Configuration=Release /p:Platform=AnyCPU /p:AndroidPackageFormat=$ANDROID_PACKAGE_FORMAT /p:OutputPath=$AC_REPOSITORY_DIR/build/outputs
# The code section below is for passing unsigned artifacts
# to the Android Sign step. So it should not be customized.
#
# Changing it might cause incompatibility issues for the next step.
$(which ruby) <.sln` file. Your Git repository is typically saved within the `$AC_REPOSITORY_DIR` inside the runner. However, your .sln file may be located in a subdirectory of this folder. Please specify this. For instance, `$AC_REPOSITORY_DIR/src`
- **`ANDROID_PROJECT_DIR`**: The location of the `.csproj` file is required for performing iOS-specific builds. In this script, it is `AppcircleXamarin.Android/AppcircleXamarin.Android.csproj`.
- **`ANDROID_PACKAGE_FORMAT`**: Please specify the type of your application package. It can be either `apk` or `aab`.
When the build pipeline is completed successfully, you will see the signed `.apk` or `.aab` in the [build artifacts](/build/build-process-management/binary-actions#download-artifacts).
### Next Steps
The document above has introduced the basic steps such as build, code signing, and app publishing for [Xamarin](https://dotnet.microsoft.com/en-us/apps/xamarin) apps on Appcircle.
Although these steps are the minimum requirements for a mobile app build pipeline, they are certainly not the end. Appcircle has some other advanced features that can help your mobile operations.
We suggest you check out the following modules for specific use cases mentioned below:
- Use [Testing Distribution](/testing-distribution) to deploy the Xamarin app to your tester groups to get feedback.
- Ready to release? Then [Publish](/publish-to-stores-module) the Xamarin app to public stores such as Google Play, App Store, or Huawei App Gallery.
- Use the [Enterprise App Store](/enterprise-app-store) if you want to distribute the Xamarin app to your in-house or private users.
___
---
## Platform Build Guides
Find detailed instructions on building applications for various platforms using Appcircle:
### [iOS Applications](/build/platform-build-guides/building-ios-applications)
Comprehensive guide for setting up iOS app builds, from provisioning to distribution.
### [Android Applications](/build/platform-build-guides/building-android-applications)
Step-by-step instructions on how to configure and optimize the Android build process.
### [React Native Applications](/build/platform-build-guides/building-react-native-applications)
Tailored guidance for building React Native apps, covering both iOS and Android builds.
### [Flutter Applications](/build/platform-build-guides/building-flutter-applications)
Everything you need to know to build Flutter applications for multiple platforms.
### [Ionic Applications](/build/platform-build-guides/building-ionic-projects-with-custom-scripts)
Learn how to use custom scripts to build and customize Ionic applications for any requirements.
### [.NET MAUI Applications](/build/platform-build-guides/building-dotnet-maui-apps)
Learn how to use custom scripts to build and customize .NET MAUI apps on Appcircle.
### [Xamarin Applications](/build/platform-build-guides/building-xamarin-apps)
Learn how to use custom scripts to build and customize Xamarin apps on Appcircle.
## FAQ
### General Build Troubleshooting
There may be a bunch of reasons for a build to fail.
The best way to learn the reason is to check the build logs. See [**Working With Build Logs**](/build/build-process-management/binary-actions#working-with-build-logs) section for details on this.
Build logs will display everything that happened in each workflow step in detail and let you examine what went wrong during the build.
If you are unable to determine the exact cause, feel free to get in touch with Appcircle using the in-app messaging for additional support.
### Troubleshooting Workflow Steps for Build Failures
Most build failures are related to the following build steps. If you encounter any errors, [please remove or edit the following steps](/workflows) and get a build to help isolate the cause of the issue.
- **iOS Sign Errors:** If the selected provisioning profile does not match with the selected bundle ID or if the certificate is not valid, you may have an issue in the iOS signing step. In this case, you may try getting an unsigned build.
- **Xcode Build for Simulator step:** This step builds your target for either x86_64 or arm64 architecture. In some projects, there may be dependencies that are not compatible with the given architecture. In this case, please remove this step from the workflow or remove the conflicting dependencies to get a successful build.
- **Android Sign Errors:** If you encounter errors while signing your Android app, you can remove this step to get an unsigned build, or you can configure the app signing within your project.
### The Build is Taking Too Long
With every build, a brand new virtual machine is started to perform your workflow and build your application.
Some applications may have 3rd party dependencies which need to be installed before the build is performed. With every new build, these dependencies need to be re-installed.
One way to speed up the build time may be to manage your dependencies in your project. This will speed up your builds significantly if your application has an excess amount of dependencies to be installed.
If you still think that your build is taking significantly longer than it should, please feel free to [**get in touch with Appcircle**](https://appcircle.io/support/) for additional support.
---
## CodePush CLI
The Appcircle CodePush CLI enables developers to interact with the CodePush service directly from the command line. With this tool, you can create and manage releases, assign deployments, and monitor rollout progress without needing to access the Appcircle UI. This section provides detailed instructions and examples for using the CLI effectively in your update workflows.
https://www.npmjs.com/package/@appcircle/codepush-cli
## Installing
To get started with the **Appcircle CodePush CLI**, you need to install it via `npm`. This CLI tool allows you to perform CodePush-related operations from your terminal environment.
Use the following command to install it globally:
```bash
npm i -g @appcircle/codepush-cli
```
Once installed, you can run `appcircle-code-push --help` to see the list of available commands.
## Login
Before you can use the CLI to manage your CodePush deployments, you need to authenticate your session.
Run the following command to start the login process:
```bash
appcircle-code-push login --accessKey
```
### Self-hosted Login
:::caution Self-hosted Version
Self-hosted CodePush is available in Appcircle self-hosted version `3.28.2` and above. If you are using an earlier version, you must upgrade to enable self-hosted CodePush.
:::
Run the following command to start the login process for your self-hosted environment:
```bash
appcircle-code-push login --accessKey --serverUrl --authUrl
```
- `--serverUrl`: Specifies the CodePush API server URL used by self-hosted Appcircle instances (e.g. `https://api-appcircle.spacetech.com/codepush`).
- `--authUrl`: Specifies the authentication endpoint used by self-hosted Appcircle instances (e.g. `https://auth-appcircle.spacetech.com`).
## CLI Experience
This section explains all the necessary details to use Appcircle’s CodePush functionality via the CLI. You’ll find all the required commands and their execution logic below.
### Creating a CodePush Application in Appcircle
To start using CodePush via CLI, you first need to create a CodePush app. This app acts as a container for your deployment channels and releases.
Use the following command to create a new app:
```bash
appcircle-code-push app add
```
Replace `` with a unique name for your app. This name will be used to associate future deployments and manage them accordingly.
In addition, all necessary parameters for aplication can be found in table below;
| Command | Description |
|------------------------------------|--------------------------------------------------------------------|
| `appcircle-code-push app add` | Creates a new CodePush app with the specified name. |
| `appcircle-code-push app remove` | Deletes an existing CodePush app from your account. |
| `appcircle-code-push app rename` | Changes the name of an existing CodePush app. |
| `appcircle-code-push app list` | Displays a list of all CodePush apps associated with your account. |
| `appcircle-code-push app transfer` | Transfers ownership of an app to another user or organization. |
### Adding a Deployment Channel in Appcircle
Deployment channels help organize and separate your release flows; this section explains how to add a new channel using the CLI so you can manage environments like staging and production effectively.
Use the following command to create a new deployment channel:
```bash
appcircle-code-push deployment add
```
Replace `` and `` with a unique names for your app and deployment channel.
In addition, all necessary parameters for aplication can be found in table below;
| Command | Description |
|------------------------------------------|--------------------------------------------------------------|
| `appcircle-code-push deployment add` | Creates a new deployment channel under the specified app. |
| `appcircle-code-push deployment remove` | Deletes an existing deployment channel from a CodePush app. |
| `appcircle-code-push deployment rename` | Renames a deployment channel within a CodePush app. |
| `appcircle-code-push deployment list` | Lists all deployment channels for a specific CodePush app. |
| `appcircle-code-push deployment history` | Shows the release history for a specific deployment channel. |
### Releasing a New Version
To publish a new CodePush update using the CLI, you can use the `release-react` command. This command bundles your React Native app and pushes the update to the specified deployment channel.
Example:
```bash
appcircle-code-push release-react ios -d --targetBinaryVersion [OtherOptions]
```
Replace `MyAppName` with your app name, `` with the name of your deployment channel, and `` with the version of the binary that this update targets.
:::caution Target Binary Version
When sending a CodePush release, you must specify the binary version that the release targets. The Appcircle CodePush SDK determines the binary version based on the `version` field in `Info.plist` (for iOS) or `build.gradle` (for Android). The version specified in `package.json` is not considered by the SDK.
:::
The table below summarizes the parameters used in this `release-react` command:
| Parameter | Description |
|--------------------------|---------------------------------------------------------------------------------------------------------------|
| `MyAppName` | The name of the app you registered via CodePush CLI. |
| `ios` or `android` | The target platform (`ios` or `android`). |
| `-d ` | The deployment channel to which the update will be released. |
| `--targetBinaryVersion` | The binary version of the app that this CodePush release is compatible with (e.g `1.0.0`). |
| `--rollout` | The percentage of users that will receive the update (e.g., `50` for 50%). |
| `--mandatory` | Marks the update as mandatory; users will be forced to update immediately. |
| `--disabled` | Disables the release so it won’t be delivered to any devices. |
| `--description` | A short note describing the content of the release. |
| `--privateKeyPath` | Relative path to the private `.pem` key used to sign the release so that devices can verify its authenticity. |
| `--diffEnabled` | Enables package diff so users will download only the changed files instead of the full package. |
### Releasing Signed CodePush Version
With the Appcircle CodePush signing feature, you can safely deliver CodePush releases to every device running your application. The signing mechanism ensures that updates are ignored if the public and private keys do not match, preventing users from installing unverified bundles.
For full details and usage instructions, please refer to the CodePush Code Signing [documentation.](/code-push/code-push-code-signing)
---
## CodePush Code Signing
CodePush Code Signing ensures that every over‑the‑air (OTA) JavaScript bundle your React Native application receives originates from a trusted source and has not been altered in transit. In this guide, you will learn how to generate signing keys, configure Appcircle to sign your CodePush releases automatically, and enable runtime verification so that your React Native app installs only properly signed updates.
## Configuration of Code Signing
Before you can sign your CodePush release, you must perform a few prerequisite configuration steps. Appcircle leverages these settings to verify the signature and safeguard your CodePush releases. The configuration details are explained step‑by‑step below.
- Generate the key pairs. Use OpenSSL (or your preferred cryptographic toolkit) to create a 4096‑bit RSA key pair—or an ECC key with curve P‑256—store the private key securely. And then store the private key securely.
```bash
# generate private RSA key
openssl genrsa -out private_codepush_signing_key.pem
# export public key
openssl rsa -pubout -in private_codepush_signing_key.pem -out public_codepush_signing_key.pem
```
## Setup and Installation
After generating the private and public keys locally, you must make a few configuration changes in your application. Begin by adding the generated **public key** to the project that you intend to sign, ensuring it is accessible at build time for signature verification.
```swift
CodePushPublicKey-----BEGIN PUBLIC KEY-----
Here is your public key
-----END PUBLIC KEY-----
```
```java
my_app-----BEGIN PUBLIC KEY-----
Here is your public key
-----END PUBLIC KEY-----
```
### Signing CodePush Release
To create a signed CodePush release, you must first generate a build from your codebase with the public key already embedded. The resulting `.ipa` and `.apk` artifacts now contain the public key, enabling them to identify properly signed CodePush releases and safely apply OTA updates.
Once your binary is configured with the public key, you can publish a **signed** CodePush release through the **Appcircle CodePush CLI**:
```bash
appcircle-code-push release-react -d --privateKeyPath
```
Replace `` with the CodePush Profile name shown in the Appcircle dashboard, update the `-d` flag as needed (e.g., *Staging*). The `--privateKeyPath` flag must reference the **same private key** you used to generate the public key embedded in the app; the CLI will sign the bundle before uploading it to Appcircle.
For a full list of commands and advanced options, see the Appcircle CodePush CLI [documentation.](/code-push/code-push-cli).
---
## Appcircle CodePush Profile
# CodePush Profile
This section explains how to create and manage a CodePush profile in Appcircle to enable over-the-air (OTA) updates for your React Native projects. A properly configured profile allows you to connect your CodePush deployments with your Appcircle workflows, manage versioning, and control release behaviors through a user-friendly interface. Follow the steps below to get started.
## Creating CodePush Profile
To use CodePush in your project, you must first create a CodePush profile in Appcircle, which links your application to the update delivery system. In Appcircle, click the `Add New` button to create a new CodePush profile and assign a name to it.
:::info CodePush Profile Name
The name you assign to your profile will be used as the `App Name` for your over-the-air updates.
:::
:::caution CodePush Profiles
To ensure better manageability of your updates, we recommend creating two separate profiles for iOS and Android platforms. For example: `MyApp-iOS` and `MyApp-Android`.
:::
## Profile Actions
By clicking the three dots on the profile card, you can:
- Rename the profile
- Pin the profile
- Delete the existing profile
:::caution Changing Profile Name
Remember, the name given to the profile is used as the **App Name** parameter during the CodePush update process. If you change the profile name, you must also **update** this parameter when delivering updates.
:::
## Profile Management
This section provides an overview of how to manage your existing CodePush profiles in Appcircle.
### Deployment Channels
Deployment channels allow you to categorize and manage your CodePush releases, enabling different update strategies such as `Staging` and `Production` deployments.
### Deployment Channel Actions
This section explains how to rename and delete existing deployment channels and view their release history for better control over your update workflow.
By clicking the three dots on the channels, you can:
- Rename the channel
- Delete the existing channel
### Adding new Deployment Channel
- To add a new deployment channel, click on the `+` button
- Provide a unique channel name in the opened modal, and save your configuration.
---
## CodePush Release
This section describes how to manage and distribute CodePush updates through Appcircle, including versioning, release strategies, and common practices for efficient update delivery.
## Deployment Keys
Deployment keys are used to link your deployment channels with the CodePush SDK, ensuring that updates are delivered to the correct target environment. For each newly created deployment channel, Appcircle will automatically generate a unique deployment key.
## Upload New Release
With the Appcircle CodePush **Upload New Release** feature, you can manually release a bundle file that you have generated in your local environment.
To use this feature, you need to upload the bundle file you created as a `.zip` archive. Below you can find a detailed explanation of the required inputs for the Upload Release feature.
- **App Version:** Specifies which app version the update is targeted for. Make sure it matches the version defined in your project settings.
- **Release Note:** A description of the changes or improvements included in this release. This helps users and team members understand what the update contains.
- **Package Diff:** When enabled, users will download only the changed files instead of the full package, reducing update size and speeding up installation.
- **Mandatory Update:** When enabled, users are required to install the update immediately upon app launch.
- **Disable:** Disables the current release, making it unavailable to users, even if it was previously deployed.
- **Rollout Percentage:** Defines what percentage of users who will receive the update initially. This allows for a gradual rollout and safer deployments.
## Managing Versions
The version management section allows you to view and compare previous CodePush releases for better control and organization of your update history. All fields in the version list are explained below.
- **Release Version:** Indicates the version of the CodePush update you have uploaded.
- **Target Version:** Shows which app version this release is intended to run on.
- **Status:** Displays the current status of the release (e.g., Enabled, Disabled).
- **Mandatory:** Specifies whether the update is mandatory for users or optional.
- **Active Devices:** The number of devices currently running this release version.
- **Rollout%:** The percentage of users to whom the release has been deployed.
- **Date:** The timestamp of when the release was uploaded.
## Version Actions
In this section, you can perform actions such as viewing details, disabling, or enabling a specific CodePush version to manage your release lifecycle more effectively.
All version actions are detailed below.
### Details
This option allows you to view all the information and configuration details of a specific CodePush release.
- **Released on:** Displays the exact date and time when this release was created.
- **Channel:** Indicates the deployment channel (e.g., Staging or Production) to which this release belongs.
- **Release Method:** Shows whether the release was uploaded manually, promoted from another channel, or generated automatically by the Build Module.
- **Target Version:** Specifies the binary version of the app that this release is compatible with.
- **Size:** The file size of the update bundle, giving users an idea of the download footprint.
- **Mandatory:** States whether this update must be installed immediately by users or can be skipped.
- **Status:** Reflects the current state of the release (Enabled or Disabled).
- **Rollout:** Indicates the percentage of devices that will receive this release based on rollout settings.
- **Description:** A short summary of the changes or improvements included in this release.
### Promote
Use this action to promote a release from one deployment channel to another, such as from Staging to Production.
- **Released Version:** Displays the exact version identifier of the release you are promoting.
- **Released on:** Shows the original date and time when this release was first created.
- **Promote To:** Specifies the target deployment channel (e.g., Production) where the release will be promoted.
- **Package Diff:** When enabled, users will download only the changed files instead of the full package.
- **Description:** A brief note explaining the purpose of this promotion or summarizing the changes included in the release.
### Rollback
This action reverts your app to the previous stable CodePush version in case of issues with the latest update. You can also roll back to any specific version if needed.
### Settings
Allows you to modify release configurations such as rollout percentage or mark the release as mandatory.
- **Description:** A brief note summarizing what this specific version includes. Useful for internal tracking and user communication.
- **Package Diff:** Ensures users download only the modified files instead of the full package, reducing update size and speeding up delivery.
- **Mandatory:** Indicates whether this version must be installed immediately by users or can be deferred.
- **Enable or Disable Version:** Allows you to control the availability of a version by toggling it on or off.
- **Rollout Percentage:** Lets you define what proportion of users will receive the update, enabling staged rollouts to monitor stability.
:::caution Setting Fields
The **Package Diff**, **Mandatory**, **Disable**, and **Rollout Percentage** parameters in the Settings section are applied in real time. This means that any changes you make will be immediately reflected across all user devices.
For example, when a version is released, some users may download it. If you disable the version later, users who haven't received the update yet will no longer see this release.
Similarly, if an update was initially published as optional but later marked as **Mandatory**, all users who haven't received the update yet will be required to install the new version.
:::
:::info Rollout Percentage
The rollout percentage distributes updates randomly across devices based on the specified percentage. It is not possible to determine exactly which devices will receive the update.
For example, if you release an update with a 70% rollout percentage, 7 out of 10 devices with the app installed will receive the update at random. The remaining 3 devices will not get the update.
:::
### Download Bundle
Use this option to download the `.zip` bundle file associated with a specific CodePush release.
---
## CodePush Profile
This section provides an overview of how to manage your CodePush profile within Appcircle, including how to create, configure, and maintain deployments for React Native applications.
## [CodePush Profile](/code-push/code-push-profile/appcircle-code-push-profile)
Learn how to create and manage CodePush profiles within Appcircle. This section also explains how deployment keys work and how they are associated with each profile and channel.
## [CodePush Release](/code-push/code-push-profile/code-push-release-management)
Discover how to create new CodePush releases, manage rollout strategies, configure mandatory updates, and track the status of past releases. This section also includes guidance on rollback operations and release new versions.
---
## CodePush SDK
This section provides comprehensive guidance on how to integrate the Appcircle CodePush SDK into your React Native project, enabling seamless over-the-air (OTA) updates that improve user experience by delivering updates without requiring users to download a new version from the app store.
https://www.npmjs.com/package/@appcircle/react-native-code-push
## React Native Project Integration
To start using the Appcircle CodePush feature, the first step is to integrate the [**Appcircle CodePush SDK**](https://www.npmjs.com/package/@appcircle/react-native-code-push) into your project. You can do this by installing the SDK directly via npm or by adding the dependency to your `package.json` file.
1. To install the SDK using the command line, run the following command in the root directory of your project.
```bash
npm i @appcircle/react-native-code-push
```
2. Using `package.json` file to add the SDK:
Add the SDK to dependencies section in your `package.json` file.
```json package.json
"dependencies": {
"@appcircle/react-native-code-push": "0.0.3",
//Other Dependencies here
}
```
**Note:** If you add the SDK directly to your `package.json` file instead of using the command line, you must run `npm install` in the project directory afterwards to install the dependency.
## CodePush Configurations in Project
To ensure that your app receives the correct updates, you must configure the appropriate deployment key in your project. Each deployment channel created in Appcircle has a unique key, which must be specified in your CodePush configuration. This allows your app to connect to the correct environment, such as `Staging` or `Production`.
To ensure that apps can properly receive updates, the `Server URL` and `Deployment Key` must be correctly added to the native code of your project. For more information, please visit the [**Deployment Keys**](/code-push/code-push-profile/code-push-release-management#deployment-keys) documentation.
Instructions on how to add these configurations for both iOS and Android platforms are provided below.
:::info Server URL
If you are using a self‑hosted version of Appcircle, use the **ServerURL** value defined for your self‑hosted instance.
For Appcircle Cloud, the **ServerURL** is `https://api.appcircle.io/codepush`.
:::
```swift
CodePushServerURLhttps://api.appcircle.io/codepushCodePushDeploymentKeyYOUR_DEPLOYMENT_KEY
```
```java
https://api.appcircle.io/codepushYOUR_DEPLOYMENT_KEY
```
#### Enabling CodePush Code Signing
To leverage Appcircle's CodePush Code Signing capability for release validation, you must integrate the public key you generated locally into your project configuration. Using this key pair, the Appcircle CodePush SDK verifies the signature of each incoming release against the key embedded in the app and decides whether the update can be applied. If verification fails, the update is blocked and will not be installed by the device.
For complete setup instructions, refer to the CodePush Code Signing [documentation.](/code-push/code-push-code-signing)
### SDK Installation and Configuration
The SDK installation and configuration steps for `iOS` and `Android` are detailed below.
#### Compatible React Native Versions
**Appcircle CodePush SDK** supports React Native **0.76+** and **the new architecture**.
If you are using React Native version **0.75 or earlier**, you need to use the **Microsoft CodePush SDK** to enable Appcircle CodePush functionality.
| React Native Version(s) | SDK |
|--------------------------------------------|-------------------------------------|
| Below 0.76 | Use [**Microsoft SDK**](https://github.com/microsoft/react-native-code-push)|
| 0.76 and above | Use [**Appcircle CodePush SDK**](https://www.npmjs.com/package/@appcircle/react-native-code-push) |
:::caution If Using Microsoft SDK
If you are using Microsoft SDK, make sure to add the **Appcircle Server URL** and **Deployment Key** correctly in your `info.plist` and `strings.xml` file. For detailed information, please navigate to the [**React Native Project Configuration**](/code-push/code-push-sdk#react-native-project-integration) section.
:::
#### For iOS
Follow the installation steps below to use the CodePush SDK in your iOS applications.
1. Run `cd ios && pod install && cd ..` to install all the necessary **CocoaPods** dependencies.
2. Open up the AppDelegate.m file, and add an import statement for the CodePush headers:
```swift
#import
```
3. Find the following line of code, which sets the source URL for bridge for production releases:
```swift
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
```
4. Replace it with this line:
```swift
return [CodePush bundleURL];
```
This change configures your app to always load the most recent version of your app's JS bundle. On the first launch, this will correspond to the file that was compiled with the app. However, after an update has been pushed via CodePush, this will return the location of the most recently installed update.
Your sourceURLForBridge method should look like this:
```swift
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [CodePush bundleURL];
#endif
}
```
#### For Android
1. In your `android/settings.gradle` file, make the following additions at the end of the file:
```java
include ':app', ':appcircle_react-native-code-push'
project(':appcircle_react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/@appcircle/react-native-code-push/android/app')
```
2. In your `android/app/build.gradle` file, add the `codepush.gradle` file as an additional build task definition to the end of the file:
```java
apply from: "../../node_modules/@appcircle/react-native-code-push/android/codepush.gradle"
```
3. Update the MainApplication file to use CodePush via the following changes:
Update the `MainApplication.kt`.
```java
// 1. Import the plugin class.
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
...
// 2. Override the getJSBundleFile method in order to let
// the CodePush runtime determine where to get the JS
// bundle location from on each app start
override fun getJSBundleFile(): String {
return CodePush.getJSBundleFile()
}
};
}
```
### SDK Basic Example Usage
After installing the SDK, you need to import and configure it within your React Native project. Below is a basic example of how to use the Appcircle CodePush SDK:
Wrap your root component with the CodePush higher-order component:
- For class component
```javascript
class MyApp extends Component {
}
MyApp = codePush(MyApp);
```
- For functional component
```javascript
let MyApp: () => React$Node = () => {
}
MyApp = codePush(MyApp);
```
If you would like your app to discover updates more quickly, you can also choose to sync up with the CodePush server every time the app resumes from the background.
- For class component
```javascript
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
class MyApp extends Component {
}
MyApp = codePush(codePushOptions)(MyApp);
```
- For functional component
```javascript
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
let MyApp: () => React$Node = () => {
}
MyApp = codePush(codePushOptions)(MyApp);
```
Alternatively, if you want fine-grained control over when the check occurs (such as a button press or timer interval), you can call `CodePush.sync()` at any time with your desired `SyncOptions`. You can also disable CodePush’s automatic checking by setting the `checkFrequency` to manual.
```javascript
let codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
class MyApp extends Component {
onButtonPress() {
codePush.sync({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
});
}
render() {
return (
Check for updates
)
}
}
MyApp = codePush(codePushOptions)(MyApp);
```
This configuration ensures that your app checks for updates when it starts, and installs them on the next app restart. You can customize the behavior further using CodePush options based on your needs.
## FAQ
### How to Customize When and How Often to Check for an Update?
By default, CodePush will check for updates on every app start. If an update is available, it will be silently downloaded, and installed the next time the app is restarted (either explicitly by the end user or by the OS), which ensures the least invasive experience for your end users. If an available update is mandatory, then it will be installed immediately, ensuring that the end user gets it as soon as possible.
Alternatively, if you want fine-grained control over when the check happens (like a button press or timer interval), you can call [CodePush.sync()](https://github.com/microsoft/react-native-code-push/blob/master/docs/api-js.md#codepushsync) at any time with your desired `SyncOptions`.
For all customization options, you can check this [API documentation](https://github.com/microsoft/react-native-code-push/blob/master/docs/api-js.md).
### How to Deploy CodePush Updates to Multiple Environments (Debug, Release etc.)?
#### iOS
Xcode allows you to define custom build settings for each "configuration" (like debug, release), which can then be referenced as the value of keys within the `Info.plist` file (like the CodePushDeploymentKey setting). This mechanism allows you to easily configure your builds to produce binaries, which are configured to synchronize with different CodePush deployments.
For details on how to setup, visit [Multiple Deployment Testing-iOS](https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-ios.md).
#### Android
The Android Gradle plugin allows you to define custom config settings for each "build type" (like debug, release). This mechanism allows you to easily configure your debug builds to use your CodePush staging deployment key and your release builds to use your CodePush production deployment key.
For details on how to setup, visit [Multiple Deployment Testing-Android](https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-android.md).
### How to Use CodePush with New Architecture on Android?
[**Appcircle CodePush SDK**](https://www.npmjs.com/package/@appcircle/react-native-code-push) supports the new architecture on Android for React Native versions 0.76 and above.
If you are **having trouble** using CodePush with new architecture in your Android app, you can update
your `MainApplication.kt` file as follows:
```kotlin
// 1. import UnstableReactNativeAPI
@OptIn(UnstableReactNativeAPI::class) // 2. add this line here
class MainApplication : Application(), ReactApplication {
...
// 3. replace these lines
override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)
// with the following lines
override val reactHost: ReactHost
get() = getDefaultReactHost(
applicationContext,
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
},
jsMainModulePath = "index",
jsBundleAssetPath = "index.android.bundle",
jsBundleFilePath = CodePush.getJSBundleFile(),
isHermesEnabled = BuildConfig.IS_HERMES_ENABLED,
useDevSupport = BuildConfig.DEBUG,
)
```
### How to Fix `A JS bundle file named "null" could not be found within the downloaded contents` Error on Android?
If you are using [**Microsoft CodePush SDK**](https://github.com/microsoft/react-native-code-push) with the new architecture enabled, you may encounter this error when attempting to push OTA updates. If that happens, you can follow [**these instructions**](https://github.com/microsoft/react-native-code-push/issues/2083#issuecomment-1411745157) to resolve it.
Alternatively, you can use the [**Appcircle CodePush SDK**](https://www.npmjs.com/package/@appcircle/react-native-code-push), which supports the new architecture for React Native 0.76 and above.
### Does Appcircle CodePush Support Self-Hosted Version?
Yes. Appcircle CodePush is available for self-hosted environments (version 3.28.2 and above), so you can manage and distribute OTA updates within your own infrastructure. For setup and configuration, see [DMZ documentation](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz).
### Does Appcircle CodePush Support Expo Projects?
No, Appcircle CodePush currently supports only bare React Native projects. Managed Expo apps are not supported at this time.
### Does Appcircle CodePush SDK Support Codegen?
No. The Appcircle CodePush SDK currently does not support React Native projects that rely on Codegen.
---
## CodePush via Build Module
This section explains how to configure and use Appcircle's Build Module to automatically upload CodePush updates as part of your CI/CD pipeline.
## Using Build Module for CodePush
Appcircle's Build Module allows you to trigger a CodePush release automatically at the end of a successful build by configuring the necessary environment variables and using the Appcircle CodePush Step.
With Appcircle's Build Module, you can both send a new CodePush release to active devices and generate a new binary for a fresh distribution of your React Native project.
With the end-to-end automation capability of the Build Module, you can also include CodePush releases in your automated workflows. Please follow the documentation below for detailed instructions.
- [**Build Module Overview:**](/build) Learn about the core functionalities and capabilities of the Appcircle Build Module and how it fits into your CI/CD workflow.
- [**Building React Native Projects:**](/build/platform-build-guides/building-react-native-applications) A step-by-step guide for configuring and building React Native applications using Appcircle's Build Module.
- [**Appcircle CodePush Step:**](/workflows/react-native-specific-workflow-steps/appcircle-codepush) Details on how to add and configure the CodePush step in your workflow to automate the release of OTA updates.
---
## Appcircle CodePush
Appcircle CodePush is a module that enables seamless over-the-air updates for React Native applications. This document explains how to configure and use the CodePush profile within Appcircle step by step.
:::caution Appcircle CodePush
The Appcircle CodePush feature is specifically designed for **React Native** projects. Other mobile technologies in the ecosystem **are not** supported. This feature **should only be used** in **React Native** projects.
:::
:::tip Learn More
For a complete overview of the Appcircle CodePush feature's capabilities, check out the [Appcircle's CodePush Section](https://appcircle.io/codepush).
:::
## [Appcircle CodePush Profile](/code-push/code-push-profile/appcircle-code-push-profile)
To start using CodePush in your React Native project, you first need to create a CodePush profile in Appcircle.
CodePush Profile
## [Appcircle CodePush SDK](/code-push/code-push-sdk)
The Appcircle CodePush SDK is required to integrate CodePush functionality into your React Native application and to handle update processes on the client side.
CodePush SDK
## [Appcircle CodePush CLI](/code-push/code-push-cli)
The Appcircle CodePush CLI allows you to manage your CodePush deployments, upload new bundles, and interact with your CodePush profile from the command line.
CodePush CLI
## [CodePush Code Signing](/code-push/code-push-code-signing)
CodePush Code Signing ensures that every over‑the‑air (OTA) JavaScript bundle your React Native application receives originates from a trusted source and has not been altered in transit.
CodePush Code Signing
## [CodePush via Build Module](/code-push/code-push-via-build-module)
You can also use the CodePush feature directly through the Appcircle Build Module to automate bundle uploads as part of your CI/CD pipeline.
CodePush via Build Module
---
## Android Testing
Ensure the quality and stability of your Android applications with a robust testing strategy.
## [Running Unit Tests](/continuous-testing/android-testing/running-android-unit-tests)
Execute unit tests to validate the individual units of source code, helping you to identify and fix issues early in the development process. Unit tests are crucial for maintaining code quality and ensuring that each component behaves as expected.
---
## Running Unit Tests
# Running Android Unit Tests
Application tests are essential when it comes to improving and maintaining product quality and performing routine checks which are difficult for humans to perform regularly.
Unit tests are usually considered first as they run really fast and are relatively easier to write and measure.
We will create a local unit test here as an example and show you how to run the test during your build process.
## Creating unit tests
First, please add test dependencies to your `build.gradle` file:
```groovy
dependencies {
// Required for local unit tests (JUnit 4 framework)
testImplementation 'junit:junit:4.12'
}
```
Create your test file in your project’s `module-name/src/test/java/` folder.
```java
package com.example.appcircle_sample_android;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see Testing documentation
*/
public class URLValidatorUnitTest {
@Test
public void invalid_url_test() {
boolean isValid = URLValidator.isValid("http:/www.google.com");
assertFalse(isValid);
}
@Test
public void valid_url_test() {
boolean isValid = URLValidator.isValid("https://www.google.com");
assertTrue(isValid);
}
}
```
This example checks to see if the provided URL is valid.
## Running your unit tests in Appcircle
To run your unit test during the build process, you can simply use a custom script in your build profile.
Simply go to your build workflow and add a custom script after the **Sign Application** step.
See the following page on our documentation to learn more about creating custom workflow steps:
Working with Custom Scripts
Add the following Bash script to your custom script step:
```bash
cd $AC_REPOSITORY_DIR
./gradlew testRelease # or you can use 'testDebug'
mv app/build/reports/tests $AC_OUTPUT_DIR
mv app/build/test-results $AC_OUTPUT_DIR
```
This simple Bash script will trigger your unit test and output the test results to be packed along with your binary files. You will get the test results both in `xml` and `html` formats.
## Generating Test Report
Appcircle has [Test Report Component](https://github.com/appcircleio/appcircle-test-report-component) which can show the result of your tests and code coverage in a beautiful UI.
You must add this component **after** running your tests so that it can parse test results. Your workflow should look like the below.
[Test Report Component](https://github.com/appcircleio/appcircle-test-report-component) shows both test and coverage results. This component supports the following test and coverage formats:
- [**JUnit**](https://junit.org)
- [**JaCoCo**](https://www.jacoco.org)
- [**Cobertura**](https://cobertura.github.io/cobertura)
- [**lcov.info**](https://lcov-viewer.netlify.app)
You must configure the **Test Report Component** and enter the path of code coverage and test results paths. For example, if you run your tests with an emulator, your files will be generated in the following folders.
- **Code Coverage Files:** `$AC_COVERAGE_RESULT_PATH`
- **Test Results:** `$AC_OUTPUT_DIR/test-results`
You must configure the component to parse those folders.
:::caution
If you're using UI tests with emulators, you must select an Intel device (**Appcircle Linux Pool (x86_64)**) since M-series virtual machines (**Appcircle Standard macOS Pool (arm64)**) don't support nested virtualization. Unit tests can work for both pools.
:::
## Jacoco Test Coverage
If you use the Jacoco tool for test coverage in your project, you can obtain coverage percentages from the test reports Jacoco generates. Jacoco calculates coverage percentages using six different methods, and the coverage percentage will be calculated based on the selected method.
:::info
These methods range from the most detailed coverage percentage to the most general:
- **INSTRUCTION**: JaCoCo counts the smallest unit of single Java bytecode instructions.
- **BRANCH**: JaCoCo also calculates branch coverage for all if and switch statements.
- **COMPLEXITY**: JaCoCo also calculates cyclomatic complexity for each non-abstract method and summarizes complexity for classes, packages and groups.
- **LINE**: For all class files that have been compiled with debug information, coverage information for individual lines can be calculated.
- **METHOD**: JaCoCo considers a method as executed when at least one instruction has been executed. Since JaCoCo works at the bytecode level, it counts constructors and static initializers as methods.
- **CLASS**: JaCoCo considers a class as executed when at least one of its methods has been executed. JaCoCo counts constructors and static initializers as methods.
:::
:::danger
Each calculation type has different coverage percentages. This is because each type has its own level of detail. Therefore, the coverage percentages are different for each one.
:::
## Showing Test Reports
Appcircle can show passing and failing tests in compact UI. If your tests generate artifacts, those artifacts are also displayed with your test cases.
## Automated Tests
Appcircle currently supports the following mobile automation testing tools:
- [Appium](/workflows/common-workflow-steps/#appium-server)
- [BrowserStack App Automate - Espresso](/workflows/android-specific-workflow-steps/browserstack-app-automate-espresso)
- [Maestro](/workflows/common-workflow-steps/maestro-cloud-upload)
- [Testinium](/workflows/common-workflow-steps/testinium-steps/testinium)
Each service allows you to run your tests on real devices, and test scenarios can be started with the artifacts created on Appcircle. Rich reports can be managed by visiting the web site of each service.
However, if your tool supports producing the following test report formats, you can also see the test results on Appcircle. Appcircle's Test Report currently supports the following test and coverage formats:
**Test Format**
- JUnit `.xml`
**Coverage Format**
- JaCoCo `.xml`
- Cobertura `.xml`
- Lcov `lcov.info`
For example, BrowserStack allows you to [export test results](https://www.browserstack.com/docs/app-automate/espresso/view-test-reports) as JUnit. You can get the results of your tests and code coverage results from BrowserStack by using a simple bash script.
```bash
curl -u "$AC_BROWSERSTACK_USERNAME:$AC_BROWSERSTACK_ACCESS_KEY" \
--output $AC_OUTPUT_DIR/myreport.xml \
-X GET "https://api-cloud.browserstack.com/app-automate/espresso/v2/builds/$BUILD_ID/sessions/$SESSION_ID/report"
```
:::info
Appcircle's [**BrowserStack App Automate - Espresso**](/workflows/android-specific-workflow-steps/browserstack-app-automate-espresso) step already parses JUnit Test reports. The above code sample is only given as an example.
:::
## FAQ
### Firebase Errors
#### Authentication Error: Your credentials are no longer valid.
Error detail:
```txt
Error: failed to upload release. Authentication Error: Your credentials are no longer valid. Please run firebase login --reauth
For CI servers and headless environments, generate a new token with firebase login:ci
⚠ Unable to fetch the CLI MOTD and remote config.
```
If you encounter this error message, please review the following two points:
1. **Verify Your Firebase Credentials**: Ensure that your login information is valid, as per the token or service account you are using. You can test it locally using the same token or service account to confirm its authenticity.
2. **Check CA Certificates**: If you are a **self-hosted Appcircle user** and you are certain that your credentials are correct, then you should also confirm that your CA certificates are properly defined for NodeJS. You can check CA certificates using the following command:
```bash
cat $NODE_EXTRA_CA_CERTS
```
:::caution
Point 2 exclusively applies to users who have opted for self-hosted solutions. For those utilizing Appcircle from the cloud platform (appcircle.io), there is no need to consider this particular point.
:::
---
## Continuous Testing
You can easily run your Unit and UI tests for your applications during builds.
---
## iOS Testing
Maximize the reliability and user experience of your iOS applications through effective testing.
## [Running Unit & UI Tests](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests)
Leverage unit testing to verify the correctness of individual code units and UI tests to ensure the user interface works as intended. These tests are integral parts of iOS development, helping you catch and resolve issues before release.
By incorporating both unit and UI tests, you can create a comprehensive test coverage that improves the overall quality of your iOS applications.
---
## Running Unit & UI Tests
# Running iOS Unit & UI Tests
You can easily run your Unit and UI tests for your iOS applications during builds.
Unit tests usually test a piece of your code and confirm the code behaves as expected in certain conditions.
### Creating tests for iOS applications
Unit tests are created in Xcode using the XCTest framework. Test methods are stored in `XCTestCase` subclass.
You can create unit tests in Xcode using the **Test Navigator**. Open the **Test Navigator** and click on the + icon in the lower left corner. Select **New Unit Test Target**. You should see the bundle and the `XCTestCase` subclass created.
You can now use XCTAssert functions to test your models or other assets.
### Performing iOS application tests in Appcircle
To run your tests during the build process, you can simply add the **Xcodebuild for Unit and UI Tests** step in your workflows.
Make sure the step is after the **Xcode Select** step and before **Export Build Artifacts**. You can optionally run a regular build afterwards by adding **Xcodebuild for Devices/Simulators** step after the **Xcodebuild for Unit and UI Tests** step.
See the following page on our documentation to learn more about adding new workflow steps:
What are Workflows and How to Use Them?
To learn more about **Xcodebuild for Unit and UI Tests** step, visit its source on Github:
https://github.com/appcircleio/appcircle-ios-test-component
### Getting test results
#### Code Signing Enabled Builds
If you have **Xcodebuild for Unit and UI Tests** step in your workflow, Unit & UI test results will be created along with the .ipa file in the **Export Build Artifacts** step. You can download test results in the same `.zip` archive and you will see the `test.xcresult.zip` file that includes test data.
#### Not Signed Builds
If you don't sign your builds, your test results will be included in the `xcarchive` file created during **Export Build Artifacts**. You can alternatively disable your build and sign steps in your workflow and get only test results without building or signing your application.
---
:::info
Optionally, you can use 3rd party tools like :link: [**XCParse**](https://github.com/ChargePoint/xcparse) or :link: [**XCTestHTMLReport**](https://github.com/TitouanVanBelle/XCTestHTMLReport) to view your test results in a more user-friendly way.
:::
### Generating Test Report
If you add [Test Report Component](https://github.com/appcircleio/appcircle-test-report-component) to your workflow, Appcircle will show the result of your tests and code coverage with a clean UI.
You must add this component **after** the `Xcodebuild for Unit and UI Tests` so that it can parse test results. Your workflow should look like the below.
[Test Report Component](https://github.com/appcircleio/appcircle-test-report-component) shows both test and coverage results. To show coverage results, you must enable **Code Coverage** in Xcode's scheme settings.
### Showing Test Reports
Appcircle can show passing and failing tests in compact UI. If your tests generate artifacts, those artifacts are also displayed with your test cases.
## Automated Tests
Appcircle currently supports the following mobile automation testing tools:
- [Appium](/workflows/common-workflow-steps/#appium-server)
- [BrowserStack App Automate (XCUI)](/workflows/ios-specific-workflow-steps/browserstack-app-automation)
- [Maestro](/workflows/common-workflow-steps/maestro-cloud-upload)
- [Testinium](/workflows/common-workflow-steps/testinium-steps/testinium)
Each service allows you to run your tests on real devices, and test scenarios can be started with the artifacts created on Appcircle. Rich reports can be managed by visiting the web site of each service.
However, if your tool supports producing the following test report formats, you can also see the test results on Appcircle. Appcircle's Test Report currently supports the following test and coverage formats:
**Test Format**
- Xcode 13+ `.xctest`
- JUnit `.xml`
**Coverage Format**
- JaCoCo `.xml`
- Cobertura `.xml`
- Lcov `lcov.info`
For example, BrowserStack allows you to [export test results](https://www.browserstack.com/docs/app-automate/xcuitest/view-test-reports) as JUnit. You can get the results of your tests and code coverage results from BrowserStack by using a simple bash script.
```bash
curl -u "$AC_BROWSERSTACK_USERNAME:$AC_BROWSERSTACK_ACCESS_KEY" \
--output $AC_OUTPUT_DIR/myreport.xml \
-X GET "https://api-cloud.browserstack.com/app-automate/espresso/v2/builds/$BUILD_ID/sessions/$SESSION_ID/report"
```
:::info
Appcircle's [**BrowserStack App Automate(XCUI)**](https://docs.appcircle.io/workflows/ios-specific-workflow-steps/browserstack-app-automation) step already parses JUnit Test reports. The above code sample is only given as an example.
:::
---
## React Native Testing
It involves validating the functionality and user interface of React Native apps through unit, integration, and UI tests to ensure consistent performance across platforms.
## [UI Test with Detox](/continuous-testing/react-native-testing/react-native-ui-test-with-detox)
Learn how to run UI tests with Detox to validate your application's user interface, ensuring a smooth, bug-free user experience and rapid feedback during development.
These tests help maintain the reliability and performance of React Native apps by catching bugs early and ensuring a smooth user experience.
## [Unit Test with Jest](/continuous-testing/react-native-testing/react-native-unit-test-with-jest)
Explore how to seamlessly run unit tests with Jest to ensure the reliability and performance of your React Native application, enhancing test accuracy and boosting development efficiency.
---
## UI Test with Detox
# React Native UI Test on Appcircle
UI Testing with Detox for React Native ensures the reliability and performance of mobile apps by automating interactions and validating the user experience on real devices and simulators across platforms.
## Configuring Detox for Execution on Appcircle
When you configure Detox using the `detox init` command, it creates an **e2e** folder and a `jest.config.js` file. Since Detox runs on Jest, you’ll need to set up Jest properly to generate test reports.
Default Jest generates test results as JSON, but the **React Native UI Test** requires junit style for parsing the test results.
1. First add **jest-junit** to your project as a dev dependency by simply running the below command.
```bash
yarn add -D jest-junit
```
2. Open `e2e/jest.config.js` file and add the below report configuration to get reports junit style:
```
reporters: [
'detox/runners/jest/reporter',
[
'jest-junit',
{
outputDirectory: './test-reports',
outputName: 'e2e-report.xml',
},
],
],
```
3. Ensure that your `.detoxrc.js`, file contains a valid configuration, as the workflow step requires which configuration to build and run. An example configuration might look like this:
```js
configurations: {
'ios.sim.debug': {
device: 'simulator',
app: 'ios.debug',
},
'ios.sim.release': {
device: 'simulator',
app: 'ios.release',
},
'android.emu.debug': {
device: 'emulator',
app: 'android.debug',
},
'android.emu.release': {
device: 'emulator',
app: 'android.release',
},
},
```
:::caution Build in Release Mode
The React Native project must be build with Detox in release mode, as debug builds trigger [Metro](https://reactnative.dev/docs/metro) to start, which can interfere with testing. For more details, [**refer to the official Detox documentation**](https://wix.github.io/Detox/docs/introduction/preparing-for-ci).
:::
:::caution Output Directory
The **outputDirectory** must be set to **test-reports** at the root of the project, as the step will search for test results in that directory.
:::
:::caution Output Name
The **outputName** must be set to `\*-report.xml` at the end of the file name, as the step will search for test results for these files.
:::
## Performing React Native UI tests in Appcircle
To run your tests during the build process, you can simply add the **React Native UI Test** step in your workflows.
Make sure the step is placed after the following:
- [**Node Install**](/workflows/react-native-specific-workflow-steps/node-install)
- [**Npm/Yarn Commands**](/workflows/react-native-specific-workflow-steps/npm-yarn-commands)
- [**Cocoapods Install** ](/workflows/ios-specific-workflow-steps/cocoapods-install) (for only iOS)
- [**Wait for Android Emulator**](/workflows/android-specific-workflow-steps/wait-for-android-emulator) (for only Android)
and make sure the step is placed before the following:
- [**Test Reports for React Native**](/workflows/react-native-specific-workflow-steps/test-reports-react-native)
- [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts)
For detailed information on Workflow structure, please visit the [**Workflows documentation**](/workflows).
For more information, please visit the **React Native UI Test** workflow step [documentation](/workflows/react-native-specific-workflow-steps/react-native-ui-test#prerequisites).
## Generating Test Report
If you add [Test Report Component](https://github.com/appcircleio/appcircle-test-report-component) to your workflow, Appcircle will show the result of your tests and code coverage with a clean UI.
You must add this step **after** the `React Native UI Test` so that it can parse test results. Your workflow should look like the below.
## Showing Test Reports
Appcircle can show passing and failing tests in compact UI.
:::caution Test Suites
The name for Test Suites appears as undefined because the tests are not wrapped inside a describe block, which is required for the suite name to be properly displayed in the report.
:::
---
## Unit Test with Jest
# React Native Unit Test on Appcircle
Introduction to **React Native Unit Test** on Appcircle focuses on enhancing code quality and reliability by automating the testing of individual components and functionalities, ensuring seamless performance across different devices and environments.
## Configure Jest for Test Reports
Default Jest generates test result as JSON but the **React Native Unit Test** requires Junit style for parsing the test results.
Follow below steps to get Junit style test results:
1. First add **jest-junit** to your project as a dev dependency simply running below command:
```bash
yarn add -D jest-junit
```
2. Add custom reporter configuration to your jest configuration file like below:
```bash
reporters: [
'default',
[
'jest-junit',
{
outputDirectory: './test-reports',
outputName: 'junit-report.xml',
},
],
],
```
When **React Native Unit Test** step will run the tests with parameter below to get test results.
```bash
yarn run jest --reporters=jest-junit
```
:::caution Output Directory
The **outputDirectory** must be set to **test-reports** at the root of the project, as the step will search for test results in that directory.
:::
:::caution Output Name
The **outputName** must be set to `\*-report.xml` at the end of the file name, as the step will search for test results for these files.
:::
## Performing React Native Unit tests in Appcircle
To run your tests during the build process, you can simply add the **React Native Unit Test** step in your workflows.
Make sure the step is placed after the following:
- [**Node Install**](/workflows/react-native-specific-workflow-steps/node-install)
- [**Npm/Yarn Commands**](/workflows/react-native-specific-workflow-steps/npm-yarn-commands)
and make sure the step is placed before the following:
- [**Test Reports for React Native**](/workflows/react-native-specific-workflow-steps/test-reports-react-native)
- [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts)
For detailed information on Workflow structure, please visit the [**Workflows documentation**](/workflows).
For more information, please visit the **React Native Unit Test** workflow step [documentation](/workflows/react-native-specific-workflow-steps/react-native-unit-test#prerequisites).
## Generating Test Report
If you add [Test Report Component](/workflows/react-native-specific-workflow-steps/test-reports-react-native) to your workflow, Appcircle will show the result of your tests and code coverage with a clean UI.
You must add this step **after** the `React Native Unit Test` so that it can parse test results. Your workflow should look like the below.
## Showing Test Reports
Appcircle can show passing and failing tests in compact UI.
:::caution Test Suites
The name for Test Suites appears as **undefined** because the tests are not wrapped inside a describe block, which is required for the suite name to be properly displayed in the report.
:::
---
## Enterprise App Store Profile
The Enterprise App Store provides a centralized platform for managing an organization’s mobile applications. This guide will outline the essential steps involved in setting up the profile, uploading application binaries, configuring profile settings, and executing actions on the uploaded binaries.
## Creating a Profile
An Enterprise build profile can be created in several ways. IPA or APK files can either be manually uploaded or sent from Appcircle’s Distribution, Build, or Publish modules.
## Uploading Binary
Uploading binaries to the Enterprise App Store is an important step in managing an organization’s mobile applications. Several methods are offered by the platform to perform this action, each catering to different stages of the application lifecycle. The available options for uploading a binary are listed below:
### Manual Binary Upload
- If no profile has been created before, the following screen will be displayed. The **Add New App** button should be clicked to open the upload panel.
- Choose your APK or IPA file and click the **Upload** button.
- If a valid APK or IPA file has been uploaded, a brand new profile should be displayed.
:::caution
Ensure that the bundle ID matches the current profile and that the version or build number differs from the other files in the list.
:::
### Upload via Build Module
Binaries can also be uploaded via the Build module. For more information, please visit the [Build Configuration](/build/build-process-management/configurations#distribution-configuration) and [Build Actions](/build/build-process-management#binary-actions) documentations.
### Upload via Testing Distribution Module
Binaries can also be uploaded via the Testing Distribution module. For more information, please visit the [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile#send-your-application-to-enterprise-app-store) documentation.
### Upload via Publish Module
The Publish Flow steps can be customized to send the binary to the Enterprise App Store. For more information, please visit the [Publish Integrations](/publish-integrations/common-publish-integrations/send-to-enterprise-app-store) documentation.
### Upload via API & CLI
The above tasks can also be initiated using the Appcircle CLI. The Appcircle CLI documentation should be checked for the command line parameters.
Appcircle CLI
### Upload via Appcircle Marketplace
You can also upload binaries from other CI tools using ready-to-use plugins.
Appcircle Marketplace
## Profile Actions
Several key actions are available within the Enterprise App Store to manage and interact with profiles efficiently. The descriptions of the available profile actions are provided below:
#### 1. **Open**
The "Open" action allows entry into a specific profile, providing access to all details and settings associated with that profile. By selecting "Open" the apps, binaries, and configurations linked to the profile can be viewed and managed.
#### 2. **Pin**
The "Pin" action allows a profile to be prioritized by pinning it to the top of the profile list. When a profile is pinned, it remains easily accessible, especially when multiple profiles are managed. This action is particularly useful for frequently accessed profiles, ensuring they stay at the forefront of the workflow.
#### 3. **Delete**
The "Delete" action results in the permanent removal of a profile from the Enterprise App Store. Once a profile is deleted, all associated data, including uploaded binaries and settings, is also erased.
:::info
Unlike profiles from other modules within Appcircle, Enterprise App Store profiles cannot be manually named or renamed. Instead, the binary names will be displayed for these profiles.
:::
## Profile Settings
After the profile has been created, it should be configured and sent to different users and channels.
Profile information can be accessed, and users can be added to grant them access to the Live and Beta channels by clicking the **Settings** button.
### Config
The Profile ID can be copied from the Info tab by clicking the copy icon located on the right side of the displayed ID.
#### In-App Update Secret
In-app updates enable applications to deliver and install updates directly within the app, enhancing user experience by minimizing disruption.
For more information, please visit [In-App Updates](/enterprise-app-store/in-app-updates) documentation.
### Enterprise Portal
You can use the Enterprise Portal settings tab to manage Portal related configurations of your Enterprise App Store profile.
#### Show on Top
The **Show on Top** feature allows you to prioritize app versions by displaying them at the top of the list in their respective channels within the Enterprise Portal.
:::caution
Please note that due to the caching model in the service, updates may take up to 10 minutes to take effect.
:::
#### Hide Certificate Details
Enabling the Hide Certificate Details toggle in the Enterprise App Store profile settings will hide the certificate information associated with the iOS and Android app versions on the Enterprise Portal. This helps maintain confidentiality by preventing end users from viewing the certificate used to sign the application binaries.
This setting applies across all listed versions under the selected profile.
#### Binary Tags
The Binary Tags feature allows you to label your application binaries with meaningful metadata, which is displayed on the Enterprise Portal for easy identification by users.
These tags help testers understand each binary's origin, purpose, and how it was triggered. The available tags are:
- Commit ID
- Commit Hash
- Commit Message
- Commit Author
- Git Source Branch
- Trigger Reason
- Git Target Branch
- Git Tag
- Trigger User
- Build Profile ID
- Workflow Name
- Configuration Name
:::info Build Module Dependency
This section appears only if the binary is distributed to the Enterprise App Store profile from the Build Module.
Uploaded binaries without metadata from a build module won’t show the selected tags on the Enterprise Portal.
:::
Binary tags can be managed through the Enterprise App Store Profile Settings under the Info tab:
1. Navigate to **Enterprise App Store** module.
2. Select the relevant profile.
3. Click the **Settings** icon.
4. Under the **Info** tab, locate the **Binary Tags** section.
5. Use the “Add a new tag” field to enter or select tags.
6. Click **Save** to apply changes.
Once tags are saved in the profile settings:
- Tags will automatically appear next to the app version on the Enterprise Portal after being published to a channel.
### Manage Access
Multiple users can be added to the Beta and Live channels by pressing the Tab key.
Defined user groups from your provider can also be added after configuration.
:::info
Email entries are not case-sensitive; however, group names are case-sensitive.
:::
:::important
To configure the Manage Access tab, the authentication method for the Enterprise Portal must be set to either SSO or LDAP. For more information about authentication types, please refer to the [Portal Settings](/enterprise-app-store/portal-settings#store-authentication) documentation.
:::
:::caution
If a sub-organization is being worked for, visibility will be limited to the apps within that organization. However, if an app is published, it will also be displayed in the showcase of the parent organization on the Enterprise Portal.
User permissions within the Enterprise App Store can be managed using **Okta SAML**. By configuring authorization groups through **Okta** and subsequently applying these group names to **Alpha** or **Beta** channels via Appcircle, access will be restricted to only the relevant users.
For further details, please refer to the document: [Okta Managing User Groups](/account/my-organization/security/authorization/store-sso-authorization).
:::
:::info
If Beta Channel Access is not configured, versions marked for the Beta channel will not be visible to anyone by default.
If Live Channel Access is not configured, versions marked for the Live channel will be visible to everyone by default.
:::
### Distribution Links
The Enterprise App Store allows users to publish app versions to either the Beta or Live channels.
Once published, these versions can be accessed via direct links or QR codes, facilitating easy distribution and installation.
To retrieve the direct links or QR codes for published app versions, follow these steps:
- In the selected app profile, go to the Settings section.
- Click on the Links tab to view the available Beta and Live channel links.
- If the app version is published to either the Beta or Live channels, the corresponding direct link and QR code will be displayed.
- Click the Copy button next to the link to copy it for sharing. Alternatively, you can use the QR code image to access via mobile devices.
:::info
If no app versions are published to either channel, the links and QR codes will not be available.
:::
:::warning Link Usage
Always use the original share link from EAS → Profile → Settings, as sharing the redirected URL may prevent users from accessing the required app version if the published version is later changed or removed.
:::
## Binary Actions
### Binary Information
This window provides information about your binary, including the provisioning profile type, certificate name, and build details, such as the branch and logs.
#### Build Metadata Details
The following metadata is displayed in the Binary Details section of a Enterprise App Store Profile only when the binary is generated via the Build Module, either through automatic or manual triggers, and subsequently distributed using Auto Distribution to the Enterprise App Store module.
- **Trigger Type**: Indicates what initiated the build. Possible values include:
1. Pull Request: The build was triggered by the creation or update of a pull request.
2. User: A build was manually triggered by a user.
3. Commit: A new commit triggered the build automatically.
4. Tag: The build was initiated when a new Git tag was pushed to the repository.
- **Branch Name**: The source branch used during the build process.
- **Target Branch**: Typically used in pull request or merge-based triggers, this is the destination branch for the pull request or merge target.
- **Git Tag**: If the trigger type is Tag, this field shows the tag that initiated the build.
- **Triggered Internal User**: Displays the email address of the internal user who triggered the build or the user responsible for the action.
- **Workflow Name**: The name of the workflow profile name executed during the build process (e.g., Default Push Workflow).
- **Config Name**: Indicates the configuration profile name used within the selected workflow (e.g., Default Configuration).
#### Binary Comparison
In the top-right corner of the Binary Information screen, you can click the **Compare** button to compare the current binary with another of your choice. The comparison highlights differences between the two binaries using color-coded indicators for easy identification.
:::caution Build Details Comparison
Binaries generated through the Appcircle Build Module include associated build details. **However**, if the compared binary was **manually** uploaded to Appcircle, those details **will not be available** for comparison.
:::
### Publish
The Enterprise App Store module includes two channels: Beta and Live.
- **Beta Channel**: This channel can be used for testing new updates, features, or changes before they are rolled out to all users. The beta channel is ideal for trialing updates without affecting the broader user base, ensuring that everything works as expected before being moved to production.
- **Live Channel**: The live channel serves as the production environment where all end users interact with the Enterprise App Store. This channel may contain stable, fully tested binary versions.
Apps can be sent to the Beta or Live channels by hitting the `...` button and then selecting the **Publish** menu.
The channel can be selected, and a summary and release notes for the release can be written. Once the **Publish** button is clicked, the particular binary will be made available to all beta users.
A version can be sent to the Live Channel in two ways:
- Click the **Publish** button and select **Live** for the channel.
- Click the ... button for any beta build and select **Go Live** from the menu.
:::info
Only **one binary version** can be sent to the Live and Beta channels. When another Beta or Live binary version is sent, the previous app version in that channel will be replaced.
:::
:::tip
Any app versions published by sub-organizations to the **Live** or **Beta** channel will be available in the Enterprise Portal created by the root organization for users to view and download.
:::
When a binary is published to the Live or Beta channel, it will be displayed with the corresponding channel tag. This information will also be shown in the profile header within the profile and on the profile card in the Enterprise App Store profile list.
:::info
If two binaries are published to the Beta and Live channels, the profile header will display the binary from the Live channel.
:::
#### Publish as Unlisted
The **‘Publish as Unlisted’** feature allows users to provide direct access to an app version in the Enterprise Portal without listing it with the other published app versions. This ensures that the app version is accessible only via a direct link, without appearing in the general app list.
When publishing an app version to either Beta or Live channels, you can enable the ‘Publish as Unlisted’ toggle.
If enabled, the app version will not be displayed in the Enterprise Portal App List.
You can access the app version only through a direct link, which can be obtained from the Profile Settings > [Links](/enterprise-app-store/enterprise-app-store-profile#distribution-links) section.
Other applications published in the Enterprise Portal will not be visible to users accessing via this unlisted link. You can always use the main Enterprise Portal link which is located within the [Portal settings](/enterprise-app-store/portal-settings#store-domain), in order to access the rest of the app list.
:::info Authentication Method
• The authentication process for accessing an Unlisted app remains the same as the Enterprise Portal’s configured [authentication](/enterprise-app-store/portal-settings#store-authentication) settings.
:::
:::tip
App versions that were published to the Beta or Live channels as unlisted will display an **'Unlisted'** tag in the app version list within the Enterprise App Store profile.
:::
#### Unpublish
Any binary can be removed from the Live or Beta channels by selecting the **Unpublish** action from the actions menu.
### Re-sign Binary
Enterprise App Store Re-Sign & Auto-Resign enables re-signing and automatic re-signing of iOS and Android applications distributed via the Enterprise App Store.
This feature allows controlled updates to build and version numbers, signing identities, and store credentials, while providing a unified re-sign flow for both manual and automated scenarios.
Please refer to [Re-sign Binary](/enterprise-app-store/resign-binary) documentation for detailed information.
### Download
The binary artifact in the Enterprise App Store profile can be downloaded by selecting the Download button from the actions menu.
### Delete
Binaries in the Enterprise App Store profiles can be deleted by clicking the Delete button in the actions menu.
:::info
Please note that you **cannot** delete a binary that is published to the Beta or Live channels. You must unpublish it before you can delete it.
:::
## Apple Enterprise Program
The Apple Developer Enterprise Program allows large organizations to develop and deploy proprietary, internal-use apps directly to their employees. This program is designed for specific use cases that require private distribution through secure internal systems or a Mobile Device Management solution.
The Apple Developer Enterprise Program is intended solely for the internal use and distribution of proprietary apps in scenarios that are not adequately addressed by public apps on the App Store, custom apps through Apple Business Manager, Ad Hoc distribution, or beta testing via TestFlight.
https://developer.apple.com/programs/enterprise/
:::danger Apple Enterprise Program
**Please note that** if you have an **Apple Developer** account with an **Enterprise Organization** and you are using an app signed with an [**Enterprise Certificate**](/signing-identities/apple-certificates) for **internal distribution**, you must use [**authentication**](https://docs.appcircle.io/enterprise-app-store/store-customization#authentication) for user access.
Apple does not allow public distribution of internally distributed apps, and if Apple detects that you are distributing an app signed with an Enterprise certificate without using authentication, it will impose severe sanctions.
You can access the relevant terms and conditions from the links below and get detailed information.
- [**Apple Developer Enterprise Program License Agreement**](https://developer.apple.com/support/terms/)
- Please navigate the `Apple Developer Enterprise Program License Agreement` section and see Section 2.1 on page 8 for **usage and restrictions**, and Section 11.2 on page 34 for **terms and terminations**.
:::
## Enterprise App Store FAQ
#### What is Enterprise App Store?
Enterprise App Store is Appcircle's new feature that lets you create your own mobile app store for your in-house apps (apps that are not meant to be distributed through Apple's App Store and Google Play Store).
#### What is the difference between Enterprise App Store and Testing Distribution
[**Testing Distribution**](/testing-distribution) is a process designed to facilitate the manual testing of new builds by internal or third-party teams, ensuring that each iteration is thoroughly validated before final release.
[**Enterprise App Store**](/enterprise-app-store), on the other hand, serves as the final distribution method, offering a secure and branded experience for internal customers.
Understanding the difference between these two methods is essential for effective internal distribution, ensuring that the right version of your app reaches the right audience at the right time.
https://appcircle.io/blog/understanding-the-difference-between-testing-distribution-and-enterprise-app-store
#### Can non-Enterprise companies use this feature?
Yes. From small teams to large enteprises, anybody can create their own app store.
#### How can I get a binary from another organization to use in the Enterprise App Store ?
Let’s assume there are two organizations: Organization A and Organization B.
In Organization A, we have a build profile that generates an IPA, APK, or AAB.
In Organization B, we have a Enterprise App Store profile that we want to send the binary to.
In Organization A's build profile workflow, after the build step, we can add a [Custom Script](/workflows/common-workflow-steps/custom-script/) step that includes the code snippet below to transfer the binary generated in Organization A to the Enterprise App Store profile in Organization B. In order to do this, we need [Appcircle CLI](/appcircle-api-and-cli/cli-authentication), so this code snippet sets up the necessary information and sends binary with parameters.
#### Upload binary for an already existing Enterprise App Store profile
```bash
#Bash script
sudo npm install -g @appcircle/cli
appcircle login personal-access-key --secret $ORG_B_PERSONAL_ACCESS_KEY
# If an IPA or AAB is required, change *.apk to *.ipa or *.aab
appcircle enterprise-app-store version upload-for-profile \
--entProfileId "$ORG_B_ENT_APP_STORE_PROFILE_ID" \
--app "$AC_OUTPUT_DIR"/*.apk
```
#### Uploads a binary and creates the Enterprise App Store profile if it does not already exist
```bash
#Bash script
sudo npm install -g @appcircle/cli
appcircle login personal-access-key --secret $ORG_B_PERSONAL_ACCESS_KEY
# If an IPA or AAB is required, change *.apk to *.ipa or *.aab
appcircle enterprise-app-store version upload-without-profile \
--app "$AC_OUTPUT_DIR"/*.apk
```
This will also generate a new Enterprise App Store profile and application will be sent into this profile.
The key point here is that we need two essential parameters to make this work.
- `$ORG_B_PERSONAL_ACCESS_KEY` => Personal Access Key from Organization B.
- `ORG_B_ENT_APP_STORE_PROFILE_ID` => Enterprise App Store profile ID from Organization B.
- `$AC_OUTPUT_DIR` => Automatically defined by the system. See [Reserved Variables](/environment-variables/appcircle-specific-environment-variables/).
To generate Personal Access Key, follow this [documentation](/account/my-organization/security/personal-access-key#generatingmanaging-the-personal-access-keys)
To obtain the Enterprise App Store profile ID, follow the steps below:
1. Log in to organization B.
2. Go to Enterprise App Store module.
3. Select the desired Enterprise App Store profile
4. Copy it from the URL. `https://my.appcircle.io/enterprise-store/profiles/123456f-7d89-4545-5454-123456789abc`
5. Then the Enterprise App Store profile ID is => `123456f-7d89-4545-5454-123456789abc`
After collecting the required parameters, set the following values as [Environment Variables](/environment-variables/):
- `ORG_B_PERSONAL_ACCESS_KEY`
- `ORG_B_ENT_APP_STORE_PROFILE_ID`
#### What kind of apps can I put to my Enterprise Portal
As long as they are signed with an Ad Hoc or Enterprise Distribution Certificate, all apps with .ipa or .apk/.aab files can be uploaded.
#### Can we customize our Enterprise Portal and how?
Yes. You can customize your logo, primary and secondary color and the main text color.
#### How will users enter my Enterprise Portal?
Once you go to your portal's settings in Appcircle, you can define a prefix and Appcircle will give you a URL with the given prefix. Alternatively, you can use your own domain. (Not eligible on Starter plans. Please [contact us](https://appcircle.io/contact) to request custom domains).
#### Can I set an authentication method for accessing the Enterprise Portal?
Yes, you can choose one of the authentication methods provided by Appcircle to authenticate your users and control their access to the portal. For more information, please visit the Enterprise App Store [**Store Authentication**](/enterprise-app-store/portal-settings#store-authentication) documentations.
#### Can I send a binary from another CI tool?
Yes, you can use Appcircle API & CLI tools within your current CI tool to directly send the binary and utilize it within the Enterprise App Store. For more information, please visit the [**Appcircle API & CLI**](/appcircle-api-and-cli) documentations.
#### Is my app store accessible from desktop web?
Yes. Desktop users can access your app portal and view the available apps through your store's URL. To install and run an app, you need to open the store from a mobile device. Desktop website will display a QR code next to your portal to pen the page from mobile devices easily.
#### How can I create an Enterprise Distribution Certificate on iOS?
You have to be enrolled on [Apple Enterprise Developer Program](https://developer.apple.com/programs/enterprise/) ($299/year). You can alternatively use Ad Hoc certificates if you aren'a a member of the Enterprise Developer program (see question below).
#### Can I distribute apps signed with Ad Hoc / App Store Provisioning Profile from my Enterprise Portal?
You can distribute apps that are signed with an Ad Hoc certificate (iOS). Please note that your users' device identifiers must be added to Apple Developer Portal and should be included in the provisioning profile used in signing the build. Apps signed with App Store certificates can't be distributed.
#### What does downloads/month mean? How is the number calculated?
A download is calculated every time an app is downloaded from our servers. So a user downloading an app, updating to a new version and re-installing any version adds to the download count.
#### Do you offer plans specific to Enterprise App Store (without CI/CD features)?
Thanks to the modular structure of Appcircle, all modules can be used independently. Accordingly, you can also request a special plan only for Enterprise App Store. Please [contact us](https://appcircle.io/contact) for detailed information.
---
## Enterprise Portal
Appcircle features a separate distribution screen designed to facilitate easy downloading of shared applications.
For iOS and Android, users can log in via the shared link and view all the versions shared with them. Downloading iOS and Android binaries is managed through the specific flows for each operating system.
## Prerequisites
In order for your users to download IPA or APK files, those files must be signed with proper certificates or Keystore files.
Android apps can be signed with any Keystore if the user's device allows installing apps from other sources.
Although iOS apps can be signed with Ad-Hoc provisioning profiles for in-house distribution, this type of distribution is limited to 100 devices per year. Once you hit that limit, you need to wait a year to reset your device limit. You also need to add the UUID of your users' device to Apple's Developer website. Therefore, Ad-Hoc distribution is intended for internal developer team members.
If you have more than 100 users and don't want to deal with device enrollment, you need to use sign your apps with Enterprise Certificate. Please check the Apple's Enterprise program for more information.
:::caution Signing Binary
Appcircle's Enterprise App Store module allows you to distribute your application without the need for any external tools. However, the way your app is signed remains your responsibility and depends on your own workflows; therefore, if you are not enrolled in the Apple Enterprise Program, Appcircle will not provide an enterprise signing service.
:::
:::caution Supported Minimum iOS Versions
Appcircle's Enterprise App Store Module works as **expected** on Apple devices running **iOS 15 and later versions**. However, **unexpected errors may occur** in the Enterprise App Store Portal on **iOS 15 and earlier versions**. For this reason, we **recommend** running the Enterprise App Store Portal on a device with **at least iOS 15** installed.
:::
https://developer.apple.com/programs/enterprise/
## Login
When a binary is shared with users through the share action for Live and Beta channels, they will receive a link for access.
Upon clicking the link, users will be redirected to the Enterprise Portal.
:::info
Authentication method can be configured from the [store settings](/enterprise-app-store/portal-settings#store-authentication).
:::
:::warning
Please note that to login to the Enterprise Portal, you must enable cookies in your browser. Cookies help maintain your session and ensure secure access.
Refer to your browser's settings to enable cookies:
**Chrome**: Settings > Privacy and security > Cookies.
**Safari**: Preferences > Privacy.
:::
## Listing and Downloading App version
Once logged in, users will be able to see the app version shared from the Enterprise App Store profile. Files can be downloaded with a single click.
You can also navigate back to the app version list, where the shared binaries for the Live or Beta channels can be viewed. Each channel will display different app versions based on what was uploaded to the Enterprise App Store profile in Appcircle.
:::info
Beta channel users have access to both Live and Beta applications, while Live users can only view Beta versions.
:::
:::info
Please note that to download and install an .IPA file, you must log in from an iOS device.
Similarly, .APK files must be downloaded and installed from an Android device.
:::
#### Log Out
Users can logout by selecting the profile icon in the top right corner of the screen.
---
## Portal Reports
# Enterprise Portal Reports
You can get the reports of your Enterprise Portal from this screen. The reports screen allows you to see the following data with a clear and concise user interface.
- App name
- Users
- Version
- Type of app (Live or Beta)
- User's Device
- User's OS
- Download Date
You can filter your results by organization, users, date, app version or app name. It is also possible to hide some entries from the pie chart by clicking on the legends.
:::info
In the filter options, you can only view and select the organization and sub-organization you belong to.
:::
You can download the report as a .csv file by clicking the **Export** button.
:::caution
If you are working for a sub-organization, you can only see the reports of the applications belonging to that organization in the reports section.
:::
---
## In-app Updates
In-app updates enable applications to deliver and install updates directly within the app, enhancing user experience by minimizing disruption.
## What are In-app Updates for Streamlined Update Experience
In-app updates offer a seamless method for delivering and installing new versions of an application directly within the app. This eliminates the need for users to manually check for updates, ensuring they receive the latest features and fixes efficiently. This streamlined approach enhances the overall user experience and keeps the app up-to-date.
## Benefits and Examples of In-app Updates
In-app updates offer several benefits, including a smoother user experience by enabling seamless updates without requiring users to manually download or install new versions. For example, critical bug fixes and feature enhancements can be automatically applied while the app is running, ensuring users always have access to the latest improvements and functionalities.
## Prerequisites for Integration
### Authentication Requirements
To integrate an in-app update experience, you will need the **profile secret**, the **enterprise store prefix**, the **enterprise store url**, and the **enterprise store profile id**.
### How to Obtain Integrations Parameters
#### In-app Update Secret
Steps to Generate a Profile-Specific Secret:
1- Navigate to your enterprise app store profile.
2- In the top-right corner, click on the Settings icon.
3- Select Generate Secret to create a profile-specific secret.
#### Enterprise Portal Prefix
Navigate to the Enterprise App Store module and settings page to find the **STORE PREFIX** information. You can also modify it if needed.
#### Enterprise Portal URL
Navigate to the Enterprise Store module and settings page to find the **STORE URL** information.
#### Enterprise Store Profile Id
You can obtain your Enterprise Store Profile ID from the Profile Settings, the URL or by using the @appcircle/cli.
##### Retrieving Profile ID from the Enterprise Store Profile Settings
1. Navigate to your Enterprise App Store Profile.
2. Select the Settings from the top right corner.
3. Find and copy your Profile ID under the Info tab by clicking the copy button, next to your Profile ID.
##### How to Extract Your Enterprise Store Profile ID from the URL
1. Navigate to your Enterprise App Store Profile.
2. Check the URL, which should be in this format: **/enterprise-store/profiles/PROFILE_ID**. The PROFILE_ID refers to your specific profile ID.
##### Retrieving Profile ID Using @appcircle/cli
The upcoming command retrieves the complete list of Enterprise App Store Profiles.
```bash
appcircle enterprise-app-store profile list
```
### Authentication for Updates
#### Retrieving Access Token Using In-App Update Secret
To fetch app versions and download the binary, you first need to obtain an access token using your In-App Update Secret.
```java
package com.example.appcircle_sample_android;
class AuthModel {
@SerializedName("access_token")
private String accessToken;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}
public class AuthService {
private static final OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
public static AuthModel getAccessToken() throws IOException {
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host(Environment.STORE_URL)
.addPathSegment("api")
.addPathSegment("auth")
.addPathSegment("token")
.build();
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("ProfileId", Environment.PROFILE_ID);
jsonBody.put("Secret", Environment.SECRET);
} catch (JSONException e) {
throw new IOException("Error creating JSON body", e);
}
RequestBody body = RequestBody.create(
MediaType.parse("application/json; charset=utf-8"),
jsonBody.toString()
);
Request request = new Request.Builder()
.url(url)
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String responseBody = response.body().string();
System.out.println("Response: " + responseBody);
Gson gson = new Gson();
return gson.fromJson(responseBody, AuthModel.class);
}
}
}
```
```swift
extension API {
func getAccessToken(secret: String, profileId: String) async throws -> AuthModel {
var components = URLComponents()
components.scheme = apiConfig.scheme
components.host = apiConfig.host
components.path = "/api/auth/token"
guard let url = components.url else {
throw HTTPError.invalidUrl
}
var request = URLRequest(url: url)
request.httpMethod = HTTPMethod.POST.rawValue
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let parameters: [String: Any] = [
"ProfileId": profileId,
"Secret": secret
]
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)
return try await apiFetcher.request(request: request)
}
}
```
```bash
curl --X POST 'https://STORE_URL/api/auth/token' \
--H 'Content-Type: application/json' \
--D
'{
"ProfileId": "PROFILE_ID",
"Secret": "PROFILE_IN_APP_UPDATE_SECRET"
}'
```
```js
export const getACToken = async (profileId: string) => {
const endpointURL = `${Environment.STORE_URL}/api/auth/token`;
const response = await axios.post(
endpointURL,
{
ProfileId: profileId,
Secret:
Platform.OS === 'ios'
? Environment.IOS_STORE_SECRET
: Environment.ANDROID_STORE_SECRET,
},
{
headers: {
'Content-Type': 'application/json',
accept: 'application/json',
},
},
);
return response.data;
};
```
{`
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static MAUI_IN_APP.Models.InAppUpdateModel;
namespace MAUI_IN_APP.Helpers;
public static class InAppUpdateHelper {
private static async Task GetACToken(string profileId)
{
var httpClient = new HttpClient();
var endpointUrl = $"{Environment.GetEnvironmentVariable("STORE_URL")}/api/auth/token";
var secret = DeviceInfo.Platform == DevicePlatform.iOS
? Environment.GetEnvironmentVariable("IOS_STORE_SECRET")
: Environment.GetEnvironmentVariable("ANDROID_STORE_SECRET");
var requestBody = new
{
ProfileId = profileId,
Secret = secret
};
var json = JsonSerializer.Serialize(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(endpointUrl, content);
var responseData = await response.Content.ReadAsStringAsync();
var responseObject = JsonSerializer.Deserialize(responseData);
return responseObject.access_token;
}
}
`}
{`
namespace MAUI_IN_APP.Models;
public class InAppUpdateModel
{
public class UpdateResult
{
public string DownloadUrl { get; set; }
public string Version { get; set; }
}
public class TokenResponse
{
public string access_token { get; set; }
}
public class AppVersion
{
public string Id { get; set; }
public string ProfileId { get; set; }
public string AppResourceReferenceId { get; set; }
public string AppIconResourceReferenceId { get; set; }
public string Name { get; set; }
public string UniqueName { get; set; }
public string SignedCertName { get; set; }
public string Version { get; set; }
public string VersionCode { get; set; }
public int PublishType { get; set; }
public DateTime? PublishDate { get; set; }
public string PublishDateStr { get; set; }
public int PlatformType { get; set; }
public string FileName { get; set; }
public long FileSize { get; set; }
public int DownloadCount { get; set; }
public string Summary { get; set; }
public string ReleaseNotes { get; set; }
public DateTime? LatestNotificationDate { get; set; }
public DateTime CreateDate { get; set; }
public DateTime? UpdateDate { get; set; }
public string BuildId { get; set; }
public string AppIconUrl { get; set; }
public bool IsDownloadLimitExceeded { get; set; }
public int OrganizationDownloadCount { get; set; }
public int OrganizationDownloadLimit { get; set; }
}
public class AppVersionsResponse
{
public List data { get; set; }
}
public enum PublishType
{
NotPublished = 0,
Beta,
Live,
}
}
`}
:::caution
For Android, omit https and provide only your enterprise store domain, such as appcircle.store.appcircle.io.
:::
### Initiating Updates
#### Retrieving Available App Versions from Your Enterprise Portal
Fetch all available versions and compare them with the current version to determine if an update is required.
```java
package com.example.appcircle_sample_android;
class AppVersion {
private String id;
private String version;
private Integer publishType;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public Integer getPublishType() {
return publishType;
}
public void setPublishType(Integer publishType) {
this.publishType = publishType;
}
}
public class AppService {
private static final String BASE_URL = "https://api.appcircle.io";
private final OkHttpClient client = new OkHttpClient();
private final Gson gson = new Gson();
public List getAppVersions(String accessToken, String profileId) throws IOException {
HttpUrl url = HttpUrl.parse("https://" + Environment.STORE_URL + "/api/app-versions");
if (url == null) {
throw new IOException("Invalid URL");
}
Request request = new Request.Builder()
.url(url)
.get()
.addHeader("Accept", "*/*")
.addHeader("Authorization", "Bearer " + accessToken)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
String responseBody = response.body().string();
System.out.println("Response: " + responseBody); // For debugging
JsonObject jsonObject = JsonParser.parseString(responseBody).getAsJsonObject();
JsonArray dataArray = jsonObject.getAsJsonArray("data");
Type listType = new TypeToken>() {}.getType();
return gson.fromJson(dataArray, listType);
}
}
}
```
```swift
extension API {
func getAppVersions(accessToken: String) async throws -> [AppVersion] {
var components = URLComponents()
components.scheme = apiConfig.scheme
components.host = apiConfig.host
components.path = "/api/app-versions"
guard let url = components.url else {
throw HTTPError.invalidUrl
}
var request = URLRequest(url: url)
request.httpMethod = HTTPMethod.GET.rawValue
request.setValue("*/*", forHTTPHeaderField: "Accept")
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
return try await apiFetcher.request(request: request)
}
}
```
```bash
curl -X GET "https://STORE_URL/api/app-versions" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Accept: */*"
```
```js
export const getAppVersions = async (accessToken: string) => {
const url = `${Environment.STORE_URL}/api/app-versions`;
try {
const response = await axios.get(url, {
headers: {
Accept: '*/*',
Authorization: `Bearer ${accessToken}`,
},
});
return response.data.data;
} catch (error) {
console.error('Failed to get app versions:', error);
}
};
```
{`
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static MAUI_IN_APP.Models.InAppUpdateModel;
namespace MAUI_IN_APP.Helpers;
public static class InAppUpdateHelper {
private static async Task> GetAppVersions(string accessToken)
{
var url = $"{Environment.GetEnvironmentVariable("STORE_URL") }/api/app-versions";
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
};
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"));
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
var response = await httpClient.GetAsync(url);
var jsonResponse = await response.Content.ReadAsStringAsync();
var responseData = JsonSerializer.Deserialize(jsonResponse,options);
return responseData.data;
}
}
}
`}
{`
namespace MAUI_IN_APP.Models;
public class InAppUpdateModel
{
public class UpdateResult
{
public string DownloadUrl { get; set; }
public string Version { get; set; }
}
public class TokenResponse
{
public string access_token { get; set; }
}
public class AppVersion
{
public string Id { get; set; }
public string ProfileId { get; set; }
public string AppResourceReferenceId { get; set; }
public string AppIconResourceReferenceId { get; set; }
public string Name { get; set; }
public string UniqueName { get; set; }
public string SignedCertName { get; set; }
public string Version { get; set; }
public string VersionCode { get; set; }
public int PublishType { get; set; }
public DateTime? PublishDate { get; set; }
public string PublishDateStr { get; set; }
public int PlatformType { get; set; }
public string FileName { get; set; }
public long FileSize { get; set; }
public int DownloadCount { get; set; }
public string Summary { get; set; }
public string ReleaseNotes { get; set; }
public DateTime? LatestNotificationDate { get; set; }
public DateTime CreateDate { get; set; }
public DateTime? UpdateDate { get; set; }
public string BuildId { get; set; }
public string AppIconUrl { get; set; }
public bool IsDownloadLimitExceeded { get; set; }
public int OrganizationDownloadCount { get; set; }
public int OrganizationDownloadLimit { get; set; }
}
public class AppVersionsResponse
{
public List data { get; set; }
}
public enum PublishType
{
NotPublished = 0,
Beta,
Live,
}
}
`}
#### Compare Current Version with Fetched App Versions to Identify Updates
Compare the current version with the fetched versions to identify the latest release. Configuration options can be adjusted to determine which version is considered the latest.
```java
/*
You can implement your custom update check mechanism within this function.
Currently, we convert the version to an integer and compare it with the 'CFBundleShortVersionString'.
You may want to check other datas about the app version to write the update control mechanism please check
/v2/profiles/{profileId}/app-versions at https://api.appcircle.io/openapi/index.html?urls.primaryName=store
*/
public class VersionUtils {
private List versionComponents(String version) {
List components = new ArrayList<>();
String[] parts = version.split("\\.");
for (String part : parts) {
try {
components.add(Integer.parseInt(part));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
return components;
}
public @Nullable AppVersion getLatestVersion(String currentVersion, List appVersions) {
AppVersion latestAppVersion = null;
List currentComponents = versionComponents(currentVersion);
for (AppVersion app : appVersions) {
List latestComponents = versionComponents(app.getVersion());
boolean isNewerVersion = false;
for (int i = 0; i < Math.min(currentComponents.size(), latestComponents.size()); i++) {
int current = currentComponents.get(i);
int latest = latestComponents.get(i);
if (latest > current && app.getPublishType() != 0) {
isNewerVersion = true;
break;
} else if (latest < current) {
break;
}
}
if (isNewerVersion) {
latestAppVersion = app;
}
}
return latestAppVersion;
}
}
```
```swift
/*
You can implement your custom update check mechanism within this function.
Currently, we convert the version to an integer and compare it with the 'CFBundleShortVersionString'.
You may want to check other datas about the app version to write the update control mechanism please check
/v2/profiles/{profileId}/app-versions at https://api.appcircle.io/openapi/index.html?urls.primaryName=store
*/
private func getLatestVersion(currentVersion: String, appVersions: [AppVersion]) -> AppVersion? {
var latestAppVersion: AppVersion?
let currentComponents = versionComponents(from: currentVersion)
// Helper function to convert version string into an array of integers
func versionComponents(from version: String) -> [Int] {
return version.split(separator: ".").compactMap { Int($0) }
}
appVersions.forEach { app in
// Convert versions to arrays of integers
let latestComponents = versionComponents(from: app.version)
// Compare versions component by component
for (current, latest) in zip(currentComponents, latestComponents) {
// You can control to update None, Beta or Live publish types you have selected on Appcircle Enterprise Portal
if (latest > current && app.publishType != 0) {
latestAppVersion = app
}
}
}
return latestAppVersion
}
```
```js
interface AppVersion {
id: string;
version: string;
publishType: number;
}
/*
You can implement your custom update check mechanism within this function.
Currently, we convert the version to an integer and compare it with the 'CFBundleShortVersionString'.
You may want to check other datas about the app version to write the update control mechanism please check
/v2/profiles/{profileId}/app-versions at https://api.appcircle.io/openapi/index.html?urls.primaryName=store
*/
const getLatestVersion = (
currentVersion: string,
appVersions: AppVersion[],
): AppVersion | undefined => {
let latestAppVersion: AppVersion | undefined;
// Helper function to convert version string into an array of integers
const versionComponents = (version: string): number[] => {
return version
.split('.')
.map(Number)
.filter(num => !isNaN(num));
};
const currentComponents = versionComponents(currentVersion);
appVersions.forEach(app => {
// Convert versions to arrays of integers
const latestComponents = versionComponents(app.version);
// Compare versions component by component
for (
let i = 0;
i < Math.min(currentComponents.length, latestComponents.length);
i++
) {
const current = currentComponents[i];
const latest = latestComponents[i];
// You can control to update None, Beta or Live publish types you have selected on Appcircle Enterprise Portal
if (latest > current && app.publishType !== 0) {
latestAppVersion = app;
}
}
});
return latestAppVersion;
};
```
{`
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static MAUI_IN_APP.Models.InAppUpdateModel;
namespace MAUI_IN_APP.Helpers;
public static class InAppUpdateHelper {
/*
You can implement your custom update check mechanism within this function.
Currently, we convert the version to an integer and compare it with the 'CFBundleShortVersionString'.
You may want to check other datas about the app version to write the update control mechanism please check
/v2/profiles/{profileId}/app-versions at https://api.appcircle.io/openapi/index.html?urls.primaryName=store
*/
public static AppVersion GetLatestVersion(string currentVersion, List appVersions)
{
AppVersion latestAppVersion = null;
// Helper function to convert version string into an array of integers
int[] VersionComponents(string version)
{
return version
.Split('.')
.Select(part => int.TryParse(part, out int num) ? num : (int?)null)
.Where(num => num.HasValue)
.Select(num => num.Value)
.ToArray();
}
var currentComponents = VersionComponents(currentVersion);
foreach (var app in appVersions)
{
// Convert versions to arrays of integers
var latestComponents = VersionComponents(app.Version);
// Compare versions component by component
for (int i = 0; i < Math.Min(currentComponents.Length, latestComponents.Length); i++)
{
var current = currentComponents[i];
var latest = latestComponents[i];
// You can control to update None, Beta or Live publish types you have selected on Appcircle Enterprise Portal
if (latest > current && app.PublishType == (int)PublishType.Live)
{
latestAppVersion = app;
break; // Assuming once we find a valid version, we don't need to check further.
}
}
}
return latestAppVersion;
}
}
`}
{`
namespace MAUI_IN_APP.Models;
public class InAppUpdateModel
{
public class UpdateResult
{
public string DownloadUrl { get; set; }
public string Version { get; set; }
}
public class TokenResponse
{
public string access_token { get; set; }
}
public class AppVersion
{
public string Id { get; set; }
public string ProfileId { get; set; }
public string AppResourceReferenceId { get; set; }
public string AppIconResourceReferenceId { get; set; }
public string Name { get; set; }
public string UniqueName { get; set; }
public string SignedCertName { get; set; }
public string Version { get; set; }
public string VersionCode { get; set; }
public int PublishType { get; set; }
public DateTime? PublishDate { get; set; }
public string PublishDateStr { get; set; }
public int PlatformType { get; set; }
public string FileName { get; set; }
public long FileSize { get; set; }
public int DownloadCount { get; set; }
public string Summary { get; set; }
public string ReleaseNotes { get; set; }
public DateTime? LatestNotificationDate { get; set; }
public DateTime CreateDate { get; set; }
public DateTime? UpdateDate { get; set; }
public string BuildId { get; set; }
public string AppIconUrl { get; set; }
public bool IsDownloadLimitExceeded { get; set; }
public int OrganizationDownloadCount { get; set; }
public int OrganizationDownloadLimit { get; set; }
}
public class AppVersionsResponse
{
public List data { get; set; }
}
public enum PublishType
{
NotPublished = 0,
Beta,
Live,
}
}
`}
:::caution
The code above compares major versions. For instance, if the current app version is 1.0 and the latest available version is 1.1, it **won't** be considered an update. However, if the latest available version is 2.0, it will be treated as an update in your enterprise portal. You can configure this logic based on your business requirements.
:::
#### Updating / Downloading the App
If a newer version is available, generate the platform-specific download URL and return it for background opening later.
```java
public String getAppVersionName() {
try {
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
return pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return "NOT_FOUND";
}
private class GetAccessTokenTask extends AsyncTask {
@Override
protected AuthModel doInBackground(String... params) {
try {
AuthModel response = AuthService.getAccessToken();
fetchAppVersions(response.getAccessToken(), Environment.PROFILE_ID);
return response;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
private void fetchAppVersions(final String accessToken, final String profileId) {
new Thread(new Runnable() {
@Override
public void run() {
try {
final List appVersions = appService.getAppVersions(accessToken, profileId);
runOnUiThread(new Runnable() {
@Override
public void run() {
String versionName = getAppVersionName();
if (versionName != null) {
VersionUtils versionUtils = new VersionUtils();
@Nullable AppVersion latestVersion = versionUtils.getLatestVersion(versionName, appVersions);
if (latestVersion != null) {
showUpdateDialog(Environment.STORE_PREFIX, profileId, latestVersion, accessToken, "USER_EMAIL");
}
} else {
Log.d("MainActivity", "Current Version Not Found");
}
}
});
} catch (final IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("APIError", "Error fetching app versions", e);
}
});
}
}
}).start();
}
```
```swift
func checkForUpdate(secret: String, profileId: String, storeURL: String, userEmail: String) async throws -> URL? {
do {
let authResponse = try await self.authApi.getAccessToken(secret: secret, profileId: profileId)
let appVersions = try await self.api.getAppVersions(accessToken: authResponse.accessToken)
let bundle = Bundle.main
let currentVersion = bundle.infoDictionary?["CFBundleShortVersionString"] as? String
guard let currentVersion = currentVersion else {
print("'CFBundleShortVersionString' Version Could Not found")
return nil
}
guard let availableVersion = getLatestVersion(currentVersion: currentVersion, appVersions: appVersions) else {
print("App is up to date!")
return nil
}
guard let downloadURL = URL(string: "itms-services://?action=download-manifest&url=https://\(storeURL)/api/app-versions/\(availableVersion.id)/download-version/\(authResponse.accessToken)/user/\(userEmail)") else {
print("Latest Version URL could not created")
return nil
}
return downloadURL
} catch {
print(error)
return nil
}
}
```
```bash
curl -X GET "https://STORE_URL/api/app-versions/{AppVersionId}/download-version"
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "user-id: USER_EMAIL" \
-H "Accept: */*"
```
```js
export const checkForUpdate = async (params: {
iOSProfileId: string;
androidProfileId: string;
currentVersion: string;
userEmail: string;
}): Promise<{updateURL: string; version: string} | undefined> => {
try {
const {access_token} = await getACToken(
Platform.OS === 'ios' ? params.iOSProfileId : params.androidProfileId,
);
const appVersions = await getAppVersions(access_token);
const latestVersion = getLatestVersion(params.currentVersion, appVersions);
if (latestVersion) {
const downloadUrl = createDownloadUrl(
latestVersion.id,
access_token,
params.userEmail,
);
if (!downloadUrl) {
console.error('Failed to create download URL');
return undefined;
}
return {
updateURL: downloadUrl,
version: latestVersion.version,
};
}
} catch (error) {
console.log(error.response);
console.error('Failed to determine if an update is available', error);
}
};
const createDownloadUrl = (
availableVersionId: string,
accessToken: string,
email: string,
): string | null => {
const baseUrl = `${Environments.STORE_URL}/api/app-versions/${availableVersionId}/download-version/${accessToken}/user/${email}`;
const downloadUrl = `itms-services://?action=download-manifest&url=${baseUrl}`;
try {
return Platform.OS === 'ios' ? downloadUrl : baseUrl;
} catch {
console.error('Latest Version URL could not be created');
return null;
}
};
```
{`
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static MAUI_IN_APP.Models.InAppUpdateModel;
namespace MAUI_IN_APP.Helpers;
public static class InAppUpdateHelper {
public static async Task CheckForUpdate(string currentVersion, string userEmail)
{
var profileId = DeviceInfo.Platform == DevicePlatform.iOS ?
Environment.GetEnvironmentVariable("IOS_PROFILE_ID") :
Environment.GetEnvironmentVariable("ANDROID_PROFILE_ID");
if (profileId != null)
{
var accessToken = await GetACToken(profileId);
var appVersions = await GetAppVersions(accessToken);
var latestVersion = GetLatestVersion(currentVersion, appVersions);
if (latestVersion != null)
{
var downloadUrl = CreateDownloadUrl(latestVersion.Id,accessToken,userEmail);
if (downloadUrl == null)
{
return null;
}
return new UpdateResult
{
DownloadUrl = downloadUrl,
Version = latestVersion.Version
};
}
}
return null;
}
public static string CreateDownloadUrl(string availableVersionId, string accessToken, string email)
{
var baseUrl = $"{Environment.GetEnvironmentVariable("STORE_URL")}/api/app-versions/{availableVersionId}/download-version/{accessToken}/user/{email}";
var downloadUrl = $"itms-services://?action=download-manifest&url={Uri.EscapeDataString(baseUrl)}";
try
{
// Assuming you have a way to determine the platform
var isIos = DeviceInfo.Platform == DevicePlatform.iOS;
return isIos ? downloadUrl : baseUrl;
}
catch (Exception)
{
Console.WriteLine("Latest Version URL could not be created");
return null;
}
}
}
`}
{`
namespace MAUI_IN_APP.Models;
public class InAppUpdateModel
{
public class UpdateResult
{
public string DownloadUrl { get; set; }
public string Version { get; set; }
}
public class TokenResponse
{
public string access_token { get; set; }
}
public class AppVersion
{
public string Id { get; set; }
public string ProfileId { get; set; }
public string AppResourceReferenceId { get; set; }
public string AppIconResourceReferenceId { get; set; }
public string Name { get; set; }
public string UniqueName { get; set; }
public string SignedCertName { get; set; }
public string Version { get; set; }
public string VersionCode { get; set; }
public int PublishType { get; set; }
public DateTime? PublishDate { get; set; }
public string PublishDateStr { get; set; }
public int PlatformType { get; set; }
public string FileName { get; set; }
public long FileSize { get; set; }
public int DownloadCount { get; set; }
public string Summary { get; set; }
public string ReleaseNotes { get; set; }
public DateTime? LatestNotificationDate { get; set; }
public DateTime CreateDate { get; set; }
public DateTime? UpdateDate { get; set; }
public string BuildId { get; set; }
public string AppIconUrl { get; set; }
public bool IsDownloadLimitExceeded { get; set; }
public int OrganizationDownloadCount { get; set; }
public int OrganizationDownloadLimit { get; set; }
}
public class AppVersionsResponse
{
public List data { get; set; }
}
public enum PublishType
{
NotPublished = 0,
Beta,
Live,
}
}
`}
:::caution Created Download URL
The scripts provided above for each platform generate a **Download URL** required to upload a new version. This URL also includes a `userEmail` parameter. While this parameter is optional, if the `userEmail` information will not be used, the `/user/{userEmail}` section at the end of the URL should be removed, and the URL should be generated using only the token.
For example;
- **iOS-Swift**: **`itms-services://?action=download-manifest&url=https://\(storeURL)/api/app-versions/\(availableVersion.id)/download-version/\(authResponse.accessToken)`**
- **Android-Java/Kotlin**: **`https://%s/api/app-versions/%s/download-version/%s`**
- **React Native Android**: **`${Environments.STORE_URL}/api/app-versions/${availableVersionId}/download-version/${accessToken}`**
- **React Native iOS**: **`itms-services://?action=download-manifest&url=https://\(storeURL)/api/app-versions/\(availableVersion.id)/download-version/\(authResponse.accessToken)`**
- **MAUI**: **`${Environment.GetEnvironmentVariable("STORE_URL")}/api/app-versions/{availableVersionId}/download-version/{accessToken}`**
Adding the token and email as parameters is supported, but it is **recommended** to include them in the headers, as shown in the cURL example.
:::
:::caution User Email and Enterprise App Store Report
Please note that the user email parameter is used for the reporting feature of the Enterprise App Store module. If the user email parameter is not provided, the **User** field in the report will appear as **`In-App Update User`**.
For more detailed information about Enterprise App Store Reporting, please visit [**Enterprise Portal Reports documentation**](/enterprise-app-store/enterprise-reports).
:::
### How to Prompt an Alert and Install the Latest Release
After obtaining the download URL for a newer version, display an alert with options to update or cancel. Customize the alert based on your requirements, such as omitting the cancel button for mandatory updates.
:::danger Simulators
Apple and Android simulators do not support installing applications from any app store. One of the main reasons for this limitation is the architectural differences between simulators and physical devices. Therefore, to use Appcircle’s in-app update feature, please use a physical device.
Please note that this feature **will not work** even if a simulator is used for testing during the development phase. **This functionality is exclusively supported on physical devices**.
:::
```java
private AppService appService = new AppService();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new GetAccessTokenTask().execute(Environment.PAT);
}
private void showUpdateDialog(final String storeURL, final String profileId, final AppVersion appVersion, final String accessToken, final String userEmail) {
new AlertDialog.Builder(this)
.setTitle("Update Available")
.setMessage(appVersion.getVersion() + " version is available. Do you want to update?")
.setPositiveButton("Update", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String baseDownloadURL = "https://%s/api/app-versions/%s/download-version/%s/user/%s";
Uri downloadURL = Uri.parse(String.format(baseDownloadURL, storeURL, appVersion.getId(), accessToken, userEmail));
Intent intent = new Intent(Intent.ACTION_VIEW, downloadURL);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Code to run when "Cancel" is pressed
dialog.dismiss();
}
})
.show();
}
```
```swift
@main
struct AppcircleApp: App {
@State private var updateURL: URL?
@State private var showAlert: Bool = false
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
let updateChecker = UpdateChecker()
Task {
if let updateURL = try await updateChecker.checkForUpdate(secret: Environments.secret, profileId: Environments.profileId, storeURL: Environments.storeURL, userEmail: "USER_EMAIL") {
self.updateURL = updateURL
self.showAlert.toggle()
}
}
}
.alert(isPresented: $showAlert) {
Alert(
title: Text("Update Available"),
message: Text("A new version is available Would you like to update?"),
primaryButton: .default(Text("Update"), action: {
UIApplication.shared.open(self.updateURL!) { isOpened in
print("Application Opened")
}
}),
secondaryButton: .cancel(Text("Cancel"), action: {
// Handle the cancel action
print("User canceled the update")
})
)
}
}
}
}
```
```js
useEffect(() => {
const updateControl = async (currentVersion: string) => {
const updateInfo = await checkForUpdate({
iOSProfileId: Environment.IOS_PROFILE_ID,
androidProfileId: Environment.ANDROID_PROFILE_ID,
currentVersion,
userEmail: 'USER_EMAIL',
});
if (updateInfo && updateInfo.updateURL && updateInfo.version) {
Alert.alert(
'Update Available',
`${updateInfo.version} version is available.`,
[
{
text: 'Update',
onPress: () => {
console.log('updateInfo.updateURL', updateInfo.updateURL);
Linking.openURL(updateInfo.updateURL);
},
},
{
text: 'Cancel',
},
],
);
}
};
const getCurrentAppVersion = async () => {
try {
const currentVersion = await DeviceInfo.getVersion();
const buildNumber = await DeviceInfo.getBuildNumber();
updateControl(currentVersion);
} catch (error) {
console.error('Failed to get app version:', error);
}
};
getCurrentAppVersion();
}, []);
```
{`
using MAUI_IN_APP.Helpers;
namespace MAUI_IN_APP;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await UpdateControl();
}
public async Task UpdateControl()
{
var currentVersion = AppInfo.VersionString;
var updateInfo = await InAppUpdateHelper.CheckForUpdate(currentVersion, "USER_EMAIL");
if (updateInfo?.DownloadUrl != null && await Launcher.CanOpenAsync(updateInfo.DownloadUrl))
{
bool result = await DisplayAlert("Update Available",$"{updateInfo.Version} version is available.", "Update","Cancel");
if (result)
{
await Launcher.OpenAsync(updateInfo.DownloadUrl);
}
}
}
}
`}
:::caution
With API Level 29 and above, the in-app update experience must be managed by allowing users to download and manually install the update due to increased security restrictions.
:::
### Mandatory Update
The Appcircle Enterprise App Store module does not provide a direct mandatory update feature. To enforce users to update the application, you can customize the scripts provided in the [**How to Prompt an Alert and Install the Latest Release**](/enterprise-app-store/in-app-updates#how-to-prompt-an-alert-and-install-the-latest-release) section according to your requirements, allowing you to implement a force update mechanism.
For instance, if the new release includes a major update and you want to make it mandatory, you can modify the update alert shown in the application by removing the cancel button or closing the application if the update is not performed. This approach ensures that the update becomes mandatory for users.
---
## Enterprise App Store
If you want to distribute your in-house applications to your users, you can use the **Enterprise App Store**.
Appcircle's Enterprise App Store helps you to set up your own store and have full control over deployment and access management.
:::tip Learn More
For a complete overview of the Appcircle Enterprise App Store module capabilities, check out the [Appcircle's Enteprise App Store Section](https://appcircle.io/enterprise-app-store).
:::
## [Enterprise App Store Profile](/enterprise-app-store/enterprise-app-store-profile)
There are several ways to create an Enterprise App Store Profile. You can either manually upload your IPA or APK files or send them through Appcircle's Distribution, Build, or Publish modules.
Enterprise App Store Profile
## [Re-sign Binary](/enterprise-app-store/resign-binary)
Enterprise App Store Re-Sign & Auto-Resign enables re-signing and automatic re-signing of iOS and Android applications distributed via the Enterprise App Store.
Re-sign Binary
## [Portal Customization](/enterprise-app-store/portal-customization)
The Enterprise App Store module allows for tailoring the login page to reflect your organization's branding. You can customize the colors, update the title, and replace the logo to create a seamless and professional experience for your users.
Portal Customization
## [Portal Settings](/enterprise-app-store/portal-settings)
The Enterprise Portal Settings allows you to configure your store's authentication, along with captcha and domain settings.
Portal Settings
## [Enterprise Portal](/enterprise-app-store/enterprise-portal)
Enterprise Portal allows you to share your applications via Beta and Live channels.
Enterprise Portal
## [Portal Reports](/enterprise-app-store/enterprise-reports)
You can access reports for your Enterprise App Store from this screen. The reports screen provides the following data through a clear and concise user interface.
Portal Reports
## [In-app Updates](/enterprise-app-store/in-app-updates)
In-app updates enable applications to deliver and install updates directly within the app, enhancing user experience by minimizing disruption.
In-app Updates
---
## Portal Customization
You can customize the appearance of your portal by navigating to the Customize section.
The Customization feature allows you to tailor the login page of your Enterprise Portal to align with your organization's branding. This feature enables you to modify key elements to create a consistent and professional appearance that reflects your corporate identity.
- **Logo**: Replace the default logo with your company’s logo to reinforce brand recognition.
- **App Store Header**: Choose from three options to customize the positions of your store title and logo on your App Store header: Default, Title Left, or Title Center.
- **App Store Title**: Personalize the title displayed on the login page. You can update it to include your company name or any other relevant text that suits your brand.
- **Colors**: Customize the color scheme of your login page, including the background, text, and button, to reflect your brand’s unique palette.
The preview screen allows you to view changes in real time before saving them. The preview screen displays the Login screen, App Details screen, and App List screen as you customize your Enterprise Portal.
:::caution
If you are working on a sub organization, you will not have access to Customize and Settings sections on Enterprise App Store module.
Only the root organization has the privilege to Set up, Configure and Customize the Enterprise Portal.
:::
---
## Portal Settings
Portal settings allow you to configure your authentication and domain settings.
## Store Authentication
Appcircle supports Static, SSO, and LDAP login. Users can also set the authentication to 'none' for direct logins.
:::info
SSO and LDAP login is only available for Enterprise accounts. Only the Organization owner or users with **Manage Enterprise Settings & Apps** rights can change the login settings.
:::
### No Authentication Login
Enterprise Portal authentication can be set to 'none,' allowing users to log in automatically without entering credentials.
Please note that this authentication method will also affect the shared links and QR codes for app versions across all Enterprise Store profiles.
### Static Login
You can set a different username and password for live and beta apps. The usernames of the live and beta section must be different.
### SSO Login
You may also use SSO for your Enterprise Portal. Appcircle supports both OpenID and SAML SSO providers. In order to enable SSO integration, please follow [Store Authentications](/account/my-organization/security/authentications/store-sso-authentication) documentation.
:::info
If you're configuring SAML Provider, you must set `https://auth.appcircle.io/auth/realms/store` as Audience URI (SP Entity ID).
:::
**Identity Providers**
You can follow the below documents to connect your identity providers. If your Identity Provider is not on the list, you can follow any OpenID or SAML integration guide from the below list to find out the parameters.
- [Auth0 OpenID](/account/my-organization/security/authentications/store-sso-authentication#4-specific-provider-configuration)
- [Auth0 SAML](/account/my-organization/security/authentications/store-sso-authentication#4-specific-provider-configuration)
- [Azure AD SAML](/account/my-organization/security/authentications/store-sso-authentication#4-specific-provider-configuration)
- [Okta OpenID](/account/my-organization/security/authentications/store-sso-authentication#4-specific-provider-configuration)
- [Okta SAML](/account/my-organization/security/authentications/store-sso-authentication#4-specific-provider-configuration)
- [OneLogin SAML](/account/my-organization/security/authentications/store-sso-authentication#4-specific-provider-configuration)
Please check the below document to learn more about SSO integration.
Single Sign-On
### LDAP Login
In order to create an LDAP login, first click the **Activate** link next to the LDAP login. If you select **Enable LDAP Login**, your previous login options will be disabled and LDAP login will be enabled. Click the **Details** link and then click the **Create** link. Appcircle supports multiple LDAP providers. You can add multiple LDAP servers with different settings.
**Configuration**
Each setting has a tooltip that shows a detailed explanation.
**Name**
Display the name of the LDAP provider. You can write any name for this area.
**Vendor**
Appcircle supports multiple LDAP providers such as Active Directory, Red Hat Directory Server, Tivoli, and Novell Directory out of the box. If your provider is not on the above list, you can select the Other option to configure your LDAP login manually.
**Username LDAP attribute**
Name of LDAP attribute, which is mapped as username. For many LDAP server vendors, it can be 'uid'. For Active directory, it can be 'sAMAccountName' or 'cn'
**RDN LDAP attribute**
Name of LDAP attribute, which is used as RDN (top attribute) of typical user DN. Usually, it's the same as the Username LDAP attribute, however, it is not required. For example for the Active directory, it is common to use 'cn' as the RDN attribute when the username attribute might be 'sAMAccountName'.
**UUID LDAP attribute**
Name of LDAP attribute, which is used as a unique object identifier (UUID) for objects in LDAP. For many LDAP server vendors, it is 'entryUUID'; however, some are different. For example, for the Active directory, it should be 'objectGUID'. If your LDAP server does not support the notion of UUID, you can use any other attribute that is supposed to be unique among LDAP users in the tree. For example 'uid' or 'entryDN'
**User Object Classes**
All values of the LDAP objectClass attribute for users in LDAP divided by comma. For example: 'inetOrgPerson, organizationalPerson'.
**Connection Url**
Connection URL to your LDAP server
**Users DN**
Full DN of LDAP tree where your users are. This DN is the parent of LDAP users. It could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have DN like 'uid=john,ou=users,dc=example,dc=com'
**Custom User LDAP Filter**
Additional LDAP Filter for filtering searched users. Leave this empty if you don't need additional filter. Make sure that it starts with '(' and ends with ')'
**Phone Number LDAP Attribute**
This attribute will be used to get email address for Two Factor Authentication(2FA).
**Search Scope**
For one level, the search applies only for users in the DNs specified by User DNs. For subtree, the search applies to the whole subtree. See LDAP documentation for more details
**Bind Type**
Type of the Authentication method used during LDAP Bind operation. It is used in most of the requests sent to the LDAP server. Options: 'none' (anonymous LDAP authentication) and 'simple' (Bind credential + Bind password authentication)
**Bind DN**
DN of LDAP admin, which will be used to access LDAP server
**Enable StartTLS**
Encrypts the connection to LDAP using STARTTLS
**Connection Timeout**
LDAP Connection Timeout in milliseconds
**Read Timeout**
LDAP Read Timeout in milliseconds. This timeout applies for LDAP read operations
**Pagination**
Does the LDAP server support pagination
### User Federation
After you have configured the main LDAP settings, you need to configure the **User Federation Mapper** section to set group DN settings. These settings will be used to query groups.
### Testing LDAP Connection
After you have configured LDAP, you can use **Test Connection** and **Test Authentication** to check the connection and credentials.
### Two-factor Authentication
To further protect your logins, you may add Two-factor Authentication(2FA) to your LDAP integration.
:::note
**Cloud** Appcircle supports **only email** 2FA method, while the self-hosted Appcircle installation using **Docker/Podman** supports both **email** and **SMS** 2FA methods.
Similar to the cloud, the self-hosted Appcircle installation using the **Helm chart** also **does not support SMS** 2FA method for now.
:::
:::info
The SMS 2FA method on Docker/Podman-based self-hosted Appcircle requires a custom integration with your SMS service. Please [contact us](https://appcircle.io/contact) for further details.
:::
## Store Domain
You can customize your store prefix which will be reflected in your Enterprise Portal access URL.
The URL can be copied by clicking the copy icon next to it.
### Custom Domain
**Custom Domain**
It's possible to use a custom domain for the Enterprise Portal. You need to have the following to create a custom domain:
- A custom domain that you can create a CNAME record.
- SSL Certificate that is exported as a p12 or pfx file.
**Creating CNAME Record**
Open your DNS provider's website and add a CNAME with the below details
**Name:** Your subdomain name. Ex. **store**
**Destination:** _**store-domain.appcircle.io**_
:::info
For self-hosted users with a Kubernetes deployment, it is essential to configure DNS records appropriately for your environment.
- Retrieve the ingress objects:
```bash
kubectl get ingress -n appcircle
```
- Examine the `ADDRESS` column:
- If internal IP addresses are listed for the ingress objects:
- For internal-only access to Appcircle, use these IP addresses as the destination for `A` records.
- For internet access to Appcircle, use the public IP addresses of these nodes as the destination for `A` records.
- If `CNAME` records are listed for the ingress objects:
- Use the `CNAME` as the destination for `CNAME` records.
:::
The below screenshot shows an example configuration screen from Cloudflare.
**Updating Settings**
After creating the DNS settings, type your custom domain name, select your certificate, and update the configuration. DNS changes can take time to propagate. You may have to wait a few minutes or hours to see the redirect.
:::caution
If you are working on a sub organization, you will not have access to Customize and Settings sections on Enterprise App Store module.
Only the main organization has the privilege to Set up, Configure and Customize the Enterprise Portal.
:::
## Enable Captcha
The captcha configuration in the Enterprise App Store module is designed to enhance login security for the Enterprise Portal. It provides flexibility for administrators to control how and when captcha is enforced, as well as to set restrictions on failed login attempts.
#### Captcha Enable/Disable Toggle
- **Disabled**: The captcha system remains inactive regardless of the number of failed login attempts.
- **Enabled**: The captcha system enforces additional security based on two specific settings available in the user interface.
#### When Captcha Will Be Shown
Defines the threshold of failed login attempts after which captcha is displayed to users.
The default setting is 3. However, it can be set to 0 to always enable captcha, requiring users to solve it on every login attempt.
#### Restrict Failed Attempts
Limits the number of login attempts a user can make after which the system blocks further attempts.
The maximum number of failed attempts is determined by the value set in this configuration. This value must be greater than 1.
If a user gets restriction due to failed attempts, the recovery time is 1 hour.
:::info
Please note that Enable Captcha feature is only available for organizations with an Enterprise license.
:::
## Session Management
The Session Management feature allows administrators to control how user sessions behave in the Enterprise Portal across devices and browsers.
#### Single Active Session
When the **Single Active Session** toggle is enabled, each user can have only one active session at a time across all browsers and devices within the Enterprise Portal.
- If the same user signs in from another browser or device, the previous active session is automatically terminated.
- This helps prevent simultaneous logins with the same account and improves overall account security.
If the toggle is disabled, users can sign in from multiple browsers or devices at the same time without terminating existing sessions.
:::info
The Session Management feature is available for organizations with an Enterprise license.
:::
:::warning Single Active Session Compatibility
The **Single Active Session** feature supports all valid authentication types: **SSO**, **Static**, and **LDAP**.
This feature is **not** applicable when the authentication type is set to **None (No Authentication)**.
:::
:::tip Channel Independence
**Live** and **Beta** channels operate independently and do not affect each other’s sessions.
If a user is logged in to the **Beta** channel, it will **not** terminate or impact the user’s active session in the **Live** channel, and vice versa.
:::
---
## Re-sign Binary
Enterprise App Store Re-Sign & Auto-Resign enables re-signing and automatic re-signing of iOS and Android applications distributed via the Enterprise App Store.
This feature allows controlled updates to build and version numbers, signing identities, and store credentials, while providing a unified re-sign flow for both manual and automated scenarios.
## iOS Re-sign
Manual iOS re-sign allows you to re-sign an existing IPA using a different signing configuration without rebuilding the application.
You can use manual re-sign to:
- Change the signing certificate or provisioning profile
- Update the bundle identifier to match the profile
- Modify the app display name
- Adjust version and build numbers before distribution
Manual re-sign operations are performed per app version and the resulting output is stored as a new re-signed artifact.
:::info iOS Re-sign Configurations
For detailed information about Manual iOS Re-sign configurations, please refer to the [configuration](/enterprise-app-store/resign-binary#ios-auto-re-sign) section. The configuration structure for Manual and Auto Re-sign is the same. However, unlike Auto Re-sign, Manual Re-sign configurations must be reconfigured for each re-sign action.
:::
## Android Re-sign
Manual Android re-sign enables re-signing APK or AAB files using a different keystore configuration.
You can use manual re-sign to:
- Replace the signing keystore
- Update the package name to match the profile
- Modify version code and version name values
- Convert AAB files to APK if required for distribution
:::info Android Re-sign Configurations
For detailed information about Manual Android Re-sign configurations, please refer to the [configuration](/enterprise-app-store/resign-binary#android-auto-re-sign) section. The configuration structure for Manual and Auto Re-sign is the same. However, unlike Auto Re-sign, Manual Re-sign configurations must be reconfigured for each re-sign action.
:::
## Auto Re-sign Configurations
Auto Re-sign enables Appcircle to automatically re-sign newly uploaded binaries based on predefined signing and versioning rules.
Before using this feature, you must first configure the Auto Re-sign settings for the relevant platform (iOS or Android), including identifier management, versioning strategy, and signing credentials.
After completing the configuration, make sure to enable the Auto Re-sign option from the Enterprise App Store profile settings. Otherwise, newly uploaded binaries will not be re-signed automatically.
### iOS Auto Re-sign
The functionality and configuration steps of **Appcircle’s Auto Re-sign** feature for the iOS platform are explained step-by-step below.
#### Information
From the **Information** tab under Auto Re-sign configuration, you can manage the application's bundle identifier and display name values.
_**Bundle Identifier**_
Appcircle Publish profiles can accept binaries with different bundle identifiers. The binary defined for the profile serves as the reference for Auto Re-sign. When a binary with a different bundle identifier is uploaded, it is re-signed according to the bundle identifier of the profile. The bundle identifier of the resulting re-signed binary is updated to match the one associated with the profile.
> ⚠️ Note: Release flows cannot be initiated with a binary whose bundle identifier differs from that of the profile. For more information, please visit the Binary Management [documentation](/publish-to-stores-module/binary-management).
:::caution Multiple Target Binary
If the binary to be re-signed has multiple targets, each target bundle identifiers **must be registered** in your **Apple Developer** portal. Otherwise, you **may encounter errors** during the re-signing process.
:::
_**Select a Pool**_
The Pool Selection field defines which organization pool will be used to execute the Auto Re-sign process.
:::caution Pool Selection Is Mandatory
Auto Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Auto Re-sign process will not start.
- Uploaded binaries will remain unsigned.
- No re-signed output will be generated for Publish profile.
Always ensure that a valid macOS pool is selected before saving the Auto Re-sign configuration.
:::
_**Display Name**_
With the **Display Name** parameter, you can change the visible name of the binary that will be re-signed. The re-signing process starts with the specified display name, and once completed, the `CFBundleDisplayName` value inside the binary is updated accordingly.
#### Versioning
By utilizing the versioning capability of the Auto Re-sign feature, you can modify the version and build number of the incoming binary according to the defined strategy during the re-signing process.
_**Update Build Number**_
With the **Update Build Number** feature, you can automatically increment the build number of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new build number will be generated based on the given offset before the re-signing begins, and the binary will be signed with this updated build number.
- **Build Number Source**: The defined base build number will be used for versioning during the re-signing process. **App Store**, **TestFlight**, and **Uploaded Binary** are available options.
- **App Store**: The build number will be calculated based on the latest live version available on the **Apple App Store**.
- **TestFlight**: The build number will be determined by referencing the latest version available on **TestFlight**.
- **Uploaded Binary**: The build number or version code will be calculated from the **most recent binary** uploaded to Appcircle.
- **Build Number**: The offset value is a number to be added or subtracted from the **build number source**.
_**Update Version Number**_
With the **Update Version Number** feature, you can automatically increment the version number of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new version number will be generated before the re-signing begins, based on the selected increment strategy and offset, and the binary will be signed with this updated version number.
- **Version Number**: The defined base version number will be used for versioning during the re-signing process. **App Store**, **TestFlight**, and **Uploaded Binary** are available options
- **App Store**: The version number will be calculated by referencing the latest live version available on the **Apple App Store**.
- **TestFlight**: The version number will be determined based on the latest version available on **TestFlight**.
- **Uploaded Binary**: The version number or version name will be calculated based on the most recently **uploaded binary** to Appcircle.
- **Version Number**: The offset value is a number to be added or subtracted from the **version number source**.
- **Increment Strategy**: You can increase the `major`, `minor`, or `patch` value of the version number.
:::caution Update Versioning
Within the Auto Re-sign feature configuration, if any store-based option is selected for versioning, it is mandatory to select an appropriate API key to retrieve the version information. If you do not want to perform versioning using the store, please select the **Uploaded Binary** option instead.
For more information, please visit the **Credentials** [documentation.](/account/my-organization/security/credentials)
:::
#### Signing
Appcircle requires valid certificate and provisioning profile to successfully perform the auto re-sign process. The re-signing begins using the associated certificates and provisioning profile..
_**App Store Credential**_
Appcircle’s Auto Re-sign feature requires an **App Store Connect** credential. Therefore, selecting a credential is mandatory for both versioning and signing processes. This credential is used to download the necessary signing assets and retrieve version-related information when versioning is configured to use App Store data.
For more information, please visit the **App Store Connect API Key** [documentation](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key).
_**Signing Method**_
The **Signing Method** defines how Appcircle selects the provisioning profile during the re-signing process. This strategy determines whether Appcircle should use an existing provisioning profile. Selecting the appropriate signing strategy ensures compatibility with your target distribution method and proper signing of your binary.
For more information about these signing strategies, please visit the Apple Profiles [documentation](/signing-identities/apple-profiles).
:::caution Enterprise API Key and In-house Signing
The Auto Re-sign feature also supports **In-house** signing. You can perform this by selecting an **Enterprise API Key**. However, please note that only In-house signing is allowed with an Enterprise Key—attempting to use it with any other signing method will result in an error.
:::
_**Create a New Provision Profile**_
If the **Create a New Provision Profile** option is enabled, Appcircle generates a valid provisioning profile for signing using the Apple API Key selected in the profile settings and your Apple Developer account. If this option is disabled, Appcircle matches an existing valid provisioning profile from your Apple Developer portal for the signing process.
:::caution Create a New Provision Profile
If you **do not** want to create the provisioning profile for signing, Appcircle will attempt to match a valid provisioning profile and use it for the signing process. When this option is disabled and a matching provisioning profile cannot be found, a new provisioning profile will be automatically created.
:::
_**Using Existing Provisioning Profile**_
When using the Auto Re-sign feature, Appcircle also provides the option to select an existing provisioning profile. If the **Create a New Provision Profile** option is not enabled, the user can manually select a provisioning profile. To be selectable, the relevant profile must already be uploaded under **Apple Profiles** in the **Signing Identity** module.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Apple Profiles](/signing-identities/apple-profiles) documentations.
:::caution Existing Provision Profile
If no provisioning profile is selected, Appcircle will still **attempt to match** a provisioning profile using the selected **App Store Credential**. If the provisioning profile **cannot be found** in the **Apple Developer portal**, a new one **will be generated**.
For example, if the binary being signed has multiple targets and only one provisioning profile has been selected, Appcircle **will try to find** the related provisioning profiles for the other targets in the **Apple Developer portal**, and if they are not found, **it will generate them**.
:::
_**Certificates**_
In addition to the selected signing strategy, Appcircle requires a corresponding certificate to perform the auto re-sign process. Therefore, make sure that your certificates are uploaded under the **Apple Certificate** section in the **Appcircle Signing Identity module**. The re-signing process will begin using the certificate you have selected.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Apple Certificates](/signing-identities/apple-certificates) documentations.
:::caution Enterprise API Key and In-house signing
If you want to perform **In-house** signing using an **Enterprise API** Key, make sure that a compatible signing certificate is selected. Otherwise, Appcircle will not be able to verify the certificate and the signing process will fail.
:::
:::info Enabling Auto Re-sign
Once you configure the Auto Re-sign settings, you must enable the Auto Re-sign feature from the Enterprise App Store profile settings. Otherwise, newly uploaded binaries will not be re-signed automatically.
:::
### Android Auto Re-sign
The functionality and configuration steps of **Appcircle’s Auto Re-sign** feature for the Android platform are explained step-by-step below.
#### Information
From the Information tab under Auto Re-sign configuration, you can manage the application's package identifier value.
_**Package Identifier**_
Appcircle Publish profiles can accept binaries with different package name. The binary defined for the profile serves as the reference for Auto Re-sign. When a binary with a different package name is uploaded, it is re-signed according to the package name of the profile. The package name of the resulting re-signed binary is updated to match the one associated with the profile.
> ⚠️ Note: Release flows cannot be initiated with a binary whose package name differs from that of the profile. For more information, please visit the Binary Management [documentation](/publish-to-stores-module/binary-management).
_**Select a Pool**_
The Pool Selection field defines which organization pool will be used to execute the Auto Re-sign process.
:::caution Pool Selection Is Mandatory
Auto Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Auto Re-sign process will not start.
- Uploaded binaries will remain unsigned.
- No re-signed output will be generated for Publish profile.
Always ensure that a valid macOS pool is selected before saving the Auto Re-sign configuration.
:::
#### Versioning
By utilizing the versioning capability of the Auto Re-sign feature, you can modify the version code and version name of the incoming binary according to the defined strategy during the re-signing process.
_**Update Version Code**_
With the **Update Version Code** feature, you can automatically increment the version code of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new version code will be generated based on the given offset before the re-signing begins, and the binary will be signed with this updated version code.
- **Version Code Source**: The defined base version code will be used for versioning during the re-signing process. **Google Play**, and **Uploaded Binary** are available options.
- **Google Play**: The version code will be set by referencing the latest live version on **Google Play Console**.
- **Uploaded Binary**: The version code will be calculated from the **most recent binary** uploaded to Appcircle.
- **Version Code Offset**: The offset value is a number to be added or subtracted from the **version code source**.
_**Update Version Name**_
With the **Update Version Name** features, you can automatically increment the version name of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new version name will be generated before the re-signing begins, based on the selected increment strategy and offset, and the binary will be signed with this updated version name.
- **Version Number/Version Name Source**: The defined base version name will be used for versioning during the re-signing process. **Google Play** and **Uploaded Binary** are available options
- **Google Play(Android)**: The version name will be set by referencing the latest live version on **Google Play Console**.
- **Uploaded Binary**: The version name will be calculated based on the most recently **uploaded binary** to Appcircle.
- **Version Name Offset**: The offset value is a number to be added or subtracted from the **version name source**.
- **Increment Strategy**: You can increase the `major`, `minor`, or `patch` value of the version name.
:::caution Update Versioning
Within the Auto Re-sign feature configuration, if any store-based option is selected for versioning, it is mandatory to select an appropriate API key to retrieve the version information. If you do not want to perform versioning using the store, please select the **Uploaded Binary** option instead.
For more information, please visit the **Credentials** [documentation.](/account/my-organization/security/credentials)
:::
#### Signing
Appcircle requires a necessary Keystore to successfully perform the auto re-sign process. The re-signing begins using the associated keystore.
_**Google Play Console Credential**_
A **Google Play Console** credential is only required if versioning is configured to use store-based data. When versioning is set to retrieve version information from the Google Play Console, an API key must be provided to access live version details during the re-signing process.
_**Keystores**_
The **Keystores** section is where you manage the signing credentials required for Android re-signing. To successfully perform the auto re-sign process, Appcircle needs access to a valid keystore. You must upload the keystore file, provide the necessary alias, and enter the key and store passwords within the **Android Keystores** section of the **Signing Identity** module. The re-signing will be executed using the selected keystore credentials.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Android Keystores](/signing-identities/android-keystores) documentations.
_**Convert AAB To APK**_
The **Convert AAB to APK** option allows you to automatically convert an Android App Bundle (AAB) file into an APK during the re-signing process. This is especially useful when your distribution channel requires an `APK` instead of an `AAB`. When enabled, Appcircle will handle the conversion and signing of the resulting APK seamlessly.
:::info Enabling Auto Re-sign
Once you configure the Auto Re-sign settings, you must enable the Auto Re-sign feature from the Enterprise App Store profile settings. Otherwise, newly uploaded binaries will not be re-signed automatically.
:::
---
## Reserved Variables
# Reserved Variables in Appcircle
Here is a list of pre-defined environment variables in Appcircle.
These reserved environment variables are either predetermined by Appcircle or are set in the build configuration.
You can check how these environment variables are utilized within the related workflow step. For instance, you can set the Xcode version of a build profile through the [build configuration](../build/platform-build-guides/building-ios-applications#selecting-the-xcode-version-and-switching-to-the-xcode-beta), which will then set this value as the `AC_XCODE_VERSION` environment variable.
You can then use this variable in any workflow step and this variable will be assigned as the default input value of the [Xcode Select workflow step](https://github.com/appcircleio/appcircle-xcode-select-component). This assignment is editable, meaning that you can either choose to keep it in the same way it is configured or you can change it by specifying a value directly in the step settings or assigning a different environment variable.
For more information on the inputs of the steps and how the variables in the following steps are used, please refer to the documentation of the specific step that is available at [https://github.com/appcircleio](https://github.com/appcircleio)
:::tip Additional Environment Variables Reference
This documentation also includes additional output environment variables from workflow steps that may be useful to users.
For any input or output variables not listed here, please refer to the "Input Variables" or "Output Variables" sections on each workflow step’s [documentation](/workflows).
If there is an environment variable you believe should be included here, please [contact us here](https://appcircle.io/support/).
:::
### iOS & Android Common Environment Variables
| Variable | Description |
| ------------------------ |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AC_OUTPUT_DIR | Output folder path to upload artifacts. |
| AC_TEMP_DIR | Path to temp directory. |
| AC_ENV_FILE_PATH | Path to the environment file. |
| AC_REPOSITORY_DIR | Clone repository destination. |
| AC_PROJECT_PATH | Project path (For Android `gradlew` file path. For iOS `.xcodeproj` or `.xcworkspace` file path). |
| AC_APPCIRCLE | Set to `true` when Appcircle starts a build. |
| AC_METADATA_OUTPUT_PATH | Metadata output file path. |
| AC_GIT_URL | Git URL of the repository. |
| AC_GIT_COMMIT | The Git commit hash that is built. |
| AC_COMMIT_ID | The commit ID that is generated from Appcircle. |
| AC_COMMIT_MESSAGE | Commit message. |
| AC_COMMIT_AUTHOR_NAME | The name of the author of the commit. |
| AC_COMMIT_AUTHOR_EMAIL | Email address of the commit author. |
| AC_COMMIT_SUBJECT | Subject or title of the commit message. |
| AC_TAG_AUTHOR_EMAIL | The email of the author of the tag. |
| AC_TAG_ANNOTATED_MESSAGE | The annotated message of the tag. |
| AC_COMMIT_TAGS | Commit tags. |
| AC_BUILD_NUMBER | Build number (`Fetch Details` is counted as Build). |
| AC_BUILD_TIMESTAMP | Build timestamp (Unix timestamp format). |
| AC_BUILD_BRANCH_ID | Unique identifier for the build branch. |
| AC_BUILD_PROFILE_ID | Unique identifier for the build profile.
| AC_GIT_BRANCH | The Git branch that is built (eg: master). |
| AC_GIT_TARGET_COMMIT | Target commit for a Pull or Merge Request. |
| AC_GIT_TARGET_BRANCH | Target branch for a Pull or Merge Request. |
| AC_GIT_PR | Set to `true` if the workflow started for a Pull or Merge Request. |
| GIT_VERSION | Version of the Git installed. |
| AC_PULL_NUMBER | Pull or merge request number. |
| AC_INTERNAL_TRIGGER_USER | The user who initiated the build, either [manually](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers#manual-build) or [automatically](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers#automatic-build). |
| AC_INTERNAL_CONFIGURATION_NAME | Name of the configuration that used the build. |
| AC_INTERNAL_CONFIGURATION_ID | Unique identifier for the [configuration](https://docs.appcircle.io/build/build-process-management/build-profile-configuration) that started the build. |
| AC_PROVIDER_NAME | **Git Provider**. Options include: GitHub, GitHub App, GitLab, GitLab Self-Hosted, Bitbucket, Bitbucket Server, Azure DevOps Services. |
| AC_IS_SUCCESS | Set to `true` if the previous step was successful. This environment variable is **deprecated** and might be removed in the future. You can use `AC_BUILD_STATUS` instead. |
| AC_BUILD_STATUS | Specify the status of the build that has run so far. Options: `Success`, `Warning`, and `Failed`. |
| AC_BUILD_STEPS_STATUS | Provides detailed information about the status of the build steps executed so far. Steps that are disabled will not appear in this environment variable. The JSON output for executed steps includes the following fields: - **StepName**: The name of the executed step. - **BuildStatus**: The status of the step. Possible values: `Success`, `Warning`, or `Failed`. - **Duration**: The time taken to complete the step, represented in seconds (e.g., `0.0000000`). - **StartDate**: The start time of the step, formatted as an ISO 8601 timestamp (e.g., `2024-12-13T15:45:59.6426984Z`). - **FinishDate**: The completion time of the step, also formatted as an ISO 8601 timestamp (e.g., `2024-12-13T15:45:59.6426984Z`). For additional details and instructions on how to format this output for readability, refer to the [**How can I print the status of workflow steps with detailed information?**](/workflows/common-workflow-steps/custom-script#how-can-i-print-the-status-of-workflow-steps-with-detailed-information) documentation. |
| AC_LOGFILE | Build log path. |
| AC_TEST_RESULT_PATH | Test result path. |
| AC_WORKFLOW_ID | Workflow UUID. |
| AC_WORKFLOW_NAME | Workflow name. |
| AC_PLATFORM_TYPE | **Platform Type**: ObjectiveCSwift, JavaKotlin, ReactNative, Flutter. |
| AC_PURPOSE | **Purpose of the Workflow** _Metadata_ = 0 _Build_ = 1 _StoreSubmit_ = 2_Merge_ = 3_TagBuild_ = 4. |
| AC_TRIGGER_REASON | The trigger reason that causes the building to start. Values it can take: `User`, `Commit`, `Tag`, `PullRequest`. |
| AC_USER_ORG_ROLES | The permission list of the user who started the build. |
| AC_OMIT_ZERO_PATCH_VERSION | Controls whether zero is omitted in the patch version. Options are true or false. |
| LC_CTYPE | Defines the character encoding and character classification properties. |
| AC_VERSION_STRATEGY | Strategy used for versioning (e.g., major, minor, patch). |
| AC_ORGANIZATION_ID | Unique identifier for the organization. |
### Reserved Android Variables
| Variable | Description |
| ---------------------------- |-------------------------------------------------------------------------------------------------------------------------------------|
| ANDROID_HOME | Android SDK installation directory. |
| AC_MODULE | Selected Android module. |
| AC_VARIANTS | Selected Android variant. |
| AC_OUTPUT_TYPE | Selected output type of Android artifact. |
| AC_APK_PATH | Generated APK file path. |
| AC_AAB_PATH | Generated AAB file path. |
| AC_SIGNED_APK_PATH | Generated signed APK file path. |
| AC_SIGNED_AAB_PATH | Generated signed AAB file path. |
| AC_ANDROID_KEYSTORE_PATH | Selected Android keystore path. |
| AC_ANDROID_KEYSTORE_PASSWORD | Password for the selected keystore. |
| AC_ANDROID_ALIAS | Selected alias name. |
| AC_ANDROID_ALIAS_PASSWORD | Selected alias password. |
| AC_V2_SIGN | Specifies if signing will use V2. |
| AC_ANDROID_POST_PROCESS_OUTPUT_PATH | Path to the output file generated by the [Android Post-Processing](/workflows/android-specific-workflow-steps/app-post-processor) step. |
| JAVA_HOME | Directory path of the Java JDK installation. |
| JAVA_OPTS | Options for Java arguments. For example: `-Xms1536M -Xmx9216M` |
| JAVA_VERSION | Version of the Java JDK installed. |
| JAVA_HOME_8_X64 | OpenJDK 8 location. |
| JAVA_HOME_11_X64 | OpenJDK 11 location. |
| JAVA_HOME_17_X64 | OpenJDK 17 location. |
| JAVA_HOME_21_X64 | OpenJDK 21 location. |
| GRADLE_OPTS | Configuration options for [Gradle build](https://docs.gradle.org/current/userguide/command_line_interface.html). |
| AC_BUILD_NUMBER_SOURCE | Build number source for versioning. |
| AC_ANDROID_BUILD_NUMBER | Build number for versioning. |
| AC_BUILD_OFFSET | Build number offset for versioning. |
| AC_VERSION_NUMBER_SOURCE | Version number source for versioning. |
| AC_ANDROID_VERSION_NUMBER | Version number for versioning. |
| AC_VERSION_OFFSET | Version number offset for versioning. |
| AC_VERSION_FLAVOR | Flavor for versioning. |
### Reserved iOS Variables
| Variable | Description |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AC_XCODE_LIST_DIR | Specifies the Xcode folder list path |
| AC_SCHEME | Specifies the project scheme for build |
| AC_ARCHIVE_FLAGS | Specifies the extra Xcodebuild flag. For example: `-configuration DEBUG` |
| AC_XCODE_VERSION | Specifies the Xcode version |
| AC_ARCHIVE_PATH | Archive path |
| AC_ARCHIVE_METADATA_PATH | Archive metadata path |
| AC_SIMULATOR_ARCHIVE_PATH | Simulator archive path description |
| AC_METADATA_OUTPUT_PATH | Metadata output file description |
| AC_CERTIFICATES | Concatenated strings of 'cert_pass\|cert_path' combined with a pipe ('\|') character that have the paths of the certificates and their passwords if they exist. For instance, when we have two certificates A and B that require passwords, then it should be like 'a_cert_pass\|a_cert_path\|b_cert_pass\|b_cert_path'. If there is no password, its field will be empty, like '\|a_cert_path'. |
| AC_PROVISIONING_PROFILES | Paths of the provisioning profiles |
| AC_EXPORT_DIR | Specifies the path that contains `ipa`, `exportOptions.plist`and other exported files |
| AC_BUNDLE_IDENTIFIERS | Specifies the project bundle identifiers |
| AC_BUILD_NUMBER_SOURCE | Build Number Source for Versioning |
| AC_IOS_BUILD_NUMBER | Build Number for Versioning |
| AC_BUILD_OFFSET | Build Number Offset for Versioning |
| AC_VERSION_NUMBER_SOURCE | Version Number Source for Versioning |
| AC_IOS_VERSION_NUMBER | Version Number for Versioning |
| AC_VERSION_OFFSET | Version Number Offset for Versioning |
| AC_BUNDLE_ID | Bundle Id for Versioning |
| AC_TARGETS | iOS Targets for Versioning |
| AC_IOS_CONFIGURATION_NAME | Configuration name for Versioning |
| AC_AUTOSIGN_CRED_PATH | App Store Connect API Key Path. **Only active if automatic signing is turned on.** |
| AC_AUTOSIGN_METHOD_FOR_EXPORT | Specifies the signing method when [automatic signing](https://docs.appcircle.io/signing-identities/apple-profiles#automatic-signing) is enabled. Options include `App Store`, `Ad-Hoc`, `Development`, `Enterprise`". Default value is `App Store`. |
| AC_AUTOSIGN_KEY | App Store Connect API Key Id. **Only active if automatic signing is turned on.** |
| AC_AUTOSIGN_ISSUER_ID | App Store Connect API Issuer Id. **Only active if automatic signing is turned on.** |
---
## Introduction to Environment Variables
Environment variables let you extend your build configuration. There are several read-only Appcircle variables and you can add your own variables to export during the build process and use in custom build scripts.
Environment variables have a key and a secret value that can be defined manually to be used in your project builds globally.
You can create groups of environment variables and import these groups to your builds to customize your builds with additional parameters.
---
## Platform-Specific Usage
Tailor your build environment with platform-specific environment variables to manage different aspects of iOS and Android builds.
### [iOS Builds](/environment-variables/platform-specific-usage/using-environment-variables-in-ios-projects)
Configure environment variables specific to iOS builds to control various settings and behaviors in Xcode, managing aspects like provisioning profiles, code signing, and more.
### [Android Builds](/environment-variables/platform-specific-usage/using-environment-variables-in-android-projects)
Set up environment variables for Android builds to fine-tune the Gradle build process, SDK versions, and other Android-specific parameters.
These platform-specific variables offer the flexibility needed to customize the build processes according to the unique requirements of each platform.
---
## Android Builds
# Using Environment Variables in Android Projects
Android developers can use environment variables using Gradle’s module-level build configuration. This module-level Gradle configuration file lets you specify build settings for that module of your application.
In the `android` block of your `build.gradle` file, specify a new `buildConfigField` method as shown below:
```groovy title="build.gradle"
android {
defaultConfig {
// Create a new variable here to be used in your code
buildConfigField "String", "APPCIRCLE_API_URL", "\"${System.env.AC_API_URL}\""
}
}
```
During the build process, Gradle will generate the `buildConfig` class and these variables will be accessible from your application in runtime.
You can now use this variable in your application. Here is an example showing how to use the variable in a view:
```java
public class SampleFragmentDetail extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Use your BuildConfig variable in your view
appVersionTextView.setText("Api URL: " + BuildConfig.APPCIRCLE_API_URL);
return view;
}
}
```
### Creating Environment Variables in Appcircle and using them in Android builds
Appcircle allows you to create groups of environment variables to be used during your builds. You can create environment variable groups for different branches of your project like development, staging, and production.
Managing Variables
Going forward on our sample above, you may want to use different API endpoints for development, staging, and production.
To create different values of the same variable, simply create an environment variable group for each branch:
Create an environment variable with the same name in each group and set the proper values for each branch.
Don’t forget to tell your build configuration to use the proper environment variable group during the build process:
Appcircle will use the values from the environment variables from the designated group for the branch you are building your application from.;
During the build process, `build.gradle` file in your module will use the values from the environment variables and your application will use these values during the runtime:
---
## iOS Builds
# Using Environment Variables in iOS Projects
We strongly recommend using environment variables if you need to use sensitive or variable data in your projects. Using sensitive data such as API keys and passwords may cause security flaws or keeping frequently changing variables may increase your development time.
### Xcode configuration files
Xcode allows you to create build configuration files commonly known as `xcconfig` files. These files can hold key/value pairs for your project-wide variables. Once you create these configuration variables, you can then use Appcircle's custom script workflow steps to replace them with the environment variables you create in Appcircle.
### Creating Xcode build configuration files
Simply create a new file by selecting **File > New** from Xcode menu and choose **Configuration Settings File** under **Other** section in the Xcode window.
Once you create your `.xcconfig` file, you can now assign it to your targets in Configurations window:
### Adding variables into build configuration file
You can now add your project-wide variables into the `.xcconfig` file:
```swift
// Application name
APPLICATION_NAME = Appcircle
// API endpoint
API_URL = api.appcircle.io
```
:::info
Please note that Xcode will treat double slashes // as comment delimiters even if it’s a URL. That’s why you may exclude the `https://` portion of your URLs or use different symbols to be replaced later in your code.
:::
### Using different values for different stages
You may want to use different values of the same environment variables for different stages of your application. For example, an API endpoint may need to be different for the development and production stages.
Xcode allows you to include and inherit build configuration files and use different configuration files for different targets of your project.;
Here's a sample code showing importing the main `config.xcconfig` file into a `development.xcconfig` file and alter the value of a variable:
```swift
// include the main xcconfig file
#include "path/to/Config.xcconfig"
// Development.xcconfig
APPLICATION_NAME = $(inherited) DEV
```
### Accessing build configuration values from your project
Now that we have our build configuration files ready, we need to tell our project to use the values from these files for certain variables.;
Xcode’s Info tab in the configuration window refers to the target’s `info.plist` file, which is compiled during the build process into the application bundle. Here, by simply adding a reference to the `$(API_URL)` variable, you can access its value from your bundle.
Final step in Xcode will be calling the variables from your code's view controller:
```swift
- (void)viewDidLoad {
[super viewDidLoad];
self.lblVersion.text = [NSString stringWithFormat:@"v%@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]];
self.lblApi.text = [NSString stringWithFormat:@"Api URL: %@\nApi KEY: %@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"API_URL"],[[NSBundle mainBundle] objectForInfoDictionaryKey:@"API_KEY"]];
}
```
### Replacing configuration settings values with environment variables
You can create environment variable groups and key/value pairs in these groups. To learn more about creating environment variables in Appcircle please see the following page:
Managing Variables
Once you update your project with `.xcconfig` files, you can create environment variable groups and include different values of the same environment variable to be used in different stages of your application like development or production.
To be able to use these variables in your project, we need to replace the values in our `.xcconfig` file using a custom script workflow step. To get more information about creating and using custom scripts, please check the following page:
Working with Custom Scripts
In our example here, we will use a Bash script to replace the values in our .xcconfig file.;
```bash
echo "API_URL : ${API_URL}"
echo "API_KEY : ${API_KEY}"
bash $AC_REPOSITORY_DIR/Appcircle/environment.sh $AC_REPOSITORY_DIR/Appcircle/development.xcconfig
```
During the build process, this Bash script will replace the values in the .xcconfig file with the environment variables created earlier.
---
## Getting Started With Appcircle
Appcircle is a mobile CI/CD platform which makes it easy for you to manage the lifecycle of your mobile applications.
:::tip
Appcircle supports mobile applications developed in Swift/Objective-C, Java/Kotlin, React Native and Flutter for both iOS and Android.
:::
Before going through with the documentation, you can also view the following introductory video about Appcircle:
A basic lifecycle of a mobile application can be broken down into 4 steps:
### Create or Add Signing Identities
Your mobile applications must be digitally signed to be able to distributed, tested and, submitted to app stores.
For iOS applications, you must have a signing certificate and provisioning profiles to be able to run your application on real devices and submit them to Apple Appstore.
Apple Certificates & Provisioning Profiles
For Android applications, you need to create a keystore file to sign your applications digitally.
Android Keystores
###
### Create Building Profiles
Building your mobile applications is very easy with Appcircle no matter what platform and language you are using. You can connect your repositories from GitHub, Bitbucket, or GitLab to Appcircle.
You can also connect to public repositories directly or use SSH for custom repository connections. If you want to try out Appcircle, you can find sample apps for different frameworks in [Appcircle GitHub](https://github.com/appcircleio?q=sample).
Appcircle will fetch all your branches and commits in your repository and lets you build any commit you want to test your application.
Connection Guides
Configure your build profile and select project parameters, signing options, distribution profiles and environment variables. Your project will be built using these settings and options.
Build Profile Configuration Overview
You can customize your build flow using our workflow editor. Workflow editor allows you to be in control of the build process. You can add or remove build steps, add your custom scripts for advanced build processes.
What are Workflows and How to Use Them?
You can also automate your build process by telling Appcircle to automatically build your code with every push to your repository. There are also options including tagged pushes for more advanced cases.
Build Manually or Automatically with Webhooks and Triggers
###
### Distribute Your Applications
Distribution is a very major and important step for testing and deploying a mobile application.
Create testing groups, add testers to testing groups and assign these groups to distribution profiles to distribute your build to testers so that they can download and install applications on their devices.
Testing Groups
If you have a team of testers, you can create testing groups and distribute builds to your testers manually or automatically after each build and let them run the application on their mobile devices.
Create a Distribution Profile and Sharing with Testers
### Submit to the Public App Stores
You can manually or automatically send your binaries to respective app stores.
Send a binary to Apple Testflight or App Store.
Send Apps to App Store Connect and TestFlight
Send a binary to Google Play.
Send Apps to Google Play Console
Send a binary to Huawei AppGallery.
Send Apps to Huawei AppGallery
### Dashboard Overview
The Appcircle Dashboard provides a centralized view of your organization’s activity, usage, and resources. It is designed to give you a quick snapshot of your builds, distribution progress, store publishing status, and Enterprise App Store assets, along with fast access to your most frequently used modules.
:::info Organization Display
Please note that the displayed data belongs to the currently logged-in root organization. It does not include usage information or binary names from sub-organizations.
:::
#### Usage Summary
At the top of the Dashboard, you will find usage indicators summarizing the current limits and consumption of your plan:
- **Builds** – Total number of builds used within the current billing period.
- **Testing Distribution** – Number of downloaded distributed builds for testing.
- **Publishes** – Number of binaries published to external app stores.
- **Members** – The number of users currently active in the organization.
- **Concurrency** – The total number of concurrent build slots available to your plan.
#### Build Profiles
The Build Profiles section lists all configured profiles in the organization. Each profile displays:
- Platform badge (iOS or Android)
- Profile name
- Connected repository
- Quick navigation arrow to open the corresponding build profile
#### Last Builds
This section shows the most recent build activities across all profiles. Each row includes:
- Repository source (GitHub, GitLab, Bitbucket, SSH, Public, etc.)
- Build status (Running, Success, Failed, Canceled)
- The email of the user who triggered the build
- Quick access to build logs and details
#### Testing Distributions
All distributions created for internal testing are listed here. Each item displays:
- The distribution binary name
- The associated build artifact (IPA/APK file)
- A quick navigation link to open distribution details, testers, and installation access
#### Publish to Stores
The Publish to Stores section displays binaries that are prepared or sent to app distribution services, such as:
- App Store Connect / TestFlight (iOS)
- Google Play Console (Android)
- Huawei AppGallery
- Microsoft Intune
:::tip
Only RC (Release Candidate) marked binaries will be listed here.
:::
#### Enterprise App Store
If you use the Enterprise App Store module, this section lists your enterprise-distributed apps. Each enterprise app entry shows:
- The application name
- The binary version
- A link to the Enterprise App Store detail page
---
## Android Build Stacks
For each Android build, Appcircle creates a brand new virtual machine;
- If you select "Appcircle Linux Pool (x86_64)", the virtual machine will be the below
- Debian 11 Bullseye
- If you select "Appcircle macOS Pool (arm64)", the virtual machine will be one of the options below
- macOS Tahoe `26.3.2`
- macOS Sequoia `15.6.1`
- macOS Sequoia `15.4.1`
- macOS Sonoma `14.5`
:::info
If you select Appcircle macOS Pool (arm64), you can not choose macOS version. It will be automatically selected by Appcircle.
The chance is equal for all runners for your Android build because it does not affect your build.
:::
Virtual machines are created and they become ready for build within seconds.
During the build process, you can install any dependencies and run commands using [custom script](/workflows/common-workflow-steps/custom-script) steps in the build workflow. This gives you complete control over your build and the virtual machine.
:::info
Please note that virtual machines are wiped off after a build is executed (no matter success or fail) and anything you installed in the virtual machine will be gone.
:::
## Java Version
Appcircle runners have Java 8, 11, 17, and 21 installed. Java 17 is set as the default version.
If you want to use a different Java version, please add the [Select Java Version](/workflows/common-workflow-steps/select-java-version) component to your workflow.
When you select "Appcircle Linux Pool (x86_64)" for Android builds, the following JDK locations are available within the environment variables:
- **JAVA_HOME_8_X64**: `/root/.sdkman/candidates/java/8.0.392-zulu`
- **JAVA_HOME_11_X64**: `/root/.sdkman/candidates/java/11.0.21-zulu`
- **JAVA_HOME_17_X64**: `/root/.sdkman/candidates/java/17.0.9-zulu`
- **JAVA_HOME_21_X64**: `/root/.sdkman/candidates/java/21.0.2-zulu`
:::tip
We're deprecating Intel-based runners and transitioning our customers to Apple silicon-based (M-series) build machines.
Although Intel-based runners are actively maintained, if your app does not specifically require an Intel-based build machine, we suggest using the "Appcircle macOS Pool (arm64)", since it has much more build capacity and the latest updates as well.
:::
When you select "Appcircle macOS Pool (arm64)" for Android builds, the following JDK locations are available within the environment variables:
- **JAVA_HOME_8_X64**: `/Users/appcircle/.sdkman/candidates/java/8.0.392-zulu`
- **JAVA_HOME_11_X64**: `/Users/appcircle/.sdkman/candidates/java/11.0.21-zulu`
- **JAVA_HOME_17_X64**: `/Users/appcircle/.sdkman/candidates/java/17.0.9-zulu`
- **JAVA_HOME_21_X64**: `/Users/appcircle/.sdkman/candidates/java/21.0.2-zulu`
## Emulator
Appcircle runners have Pixel_3a Android 9.0 emulator pre-installed. You may add or remove other emulators by using `sdkmanager`.
For example, in order to install Android 11 (API 30) emulator to x86_64 Linux, you can take the below steps:
**1.** Install emulator system image if not exists. (If it exists, the command will return quickly with success.)
```bash
sdkmanager "system-images;android-30;google_apis;x86_64"
```
You can see a list of available system images with the below command:
```bash
sdkmanager --list | grep "system-images;android"
```
**2.** Create new pixel_3a device with "Pixel_Custom" emulator name.
```bash
avdmanager create avd -n Pixel_Custom -k "system-images;android-30;google_apis;x86_64" -c 512M -d pixel_3a
```
When completed with success, you should see below the device with `avdmanager list avd`:
```txt
Name: Pixel_Custom
Device: pixel_3a (Google)
Path: /users/appcircle/.android/avd/Pixel_Custom.avd
Target: Google APIs (Google Inc.)
Based on: Android 11.0 (R)
Tag/ABI: google_apis/x86_64
Sdcard: 512 MB
```
:::caution
If you're using UI tests with emulators, you must select an Intel device (**Appcircle Linux Pool (x86_64)**) since M-series virtual machines (**Appcircle macOS Pool (arm64)**) don't support nested virtualization.
:::
## Android Build Environment
There are many pre-installed packages in virtual machines. You can get a full list of pre-installed packages by running Bash commands in custom script steps.
Here are some most important packages installed in our Linux and macOS images used for Android builds:
| Package | Debian Bullseye | macOS Sonoma | macOS Sequoia `15.4.1` | macOS Sequoia `15.6.1` | macOS Tahoe `26.3.2` |
| ------------------- | --------------- | -------------- | ----------------- | ----------------- | ----------------- |
| Apt | 2.2.4 | n/A | n/A | n/A | n/A |
| Homebrew | n/A | 4.3.5 | 4.5.1 | 4.6.16 | 5.1.0 |
| Bash | 5.1.4 | 3.2.57 | 3.2.57 | 3.2.57 | 5.3.9 |
| GNU Binutils | 2.35.2 | n/A | n/A | n/A | n/A |
| Bzip2 | 1.0.8 | n/A | n/A | n/A | n/A |
| Curl | 7.74.0 | 8.6.0 | 8.7.1 | 8.7.1 | 8.7.1 |
| GCC | 10.2.1 | 16.0.0 | 17.0.0 | 17.0.0 | 21.0.0 |
| Git | 2.35.1 | 2.45.2 | 2.49.0 | 2.51.0 | 2.53.0 |
| Git LFS | 2.13.2 | 3.5.1 | 3.6.1 | 3.7.0 | 3.7.1 |
| Gradle | 4.4.1 | 8.8 | 8.14 | 9.1.0 | 9.4.0 |
| Gzip | 1.10 | 430.100.5 | 457.100.3 | 457.140.3 | 475 |
| Java | 17.0.9 | 17.0.9 | 17.0.9 | 17.0.9 | 17.0.12 |
| Maven | 3.9.9 | 3.9.7 | 3.9.9 | 3.9.11 | 3.9.14 |
| Node JS | 18.20.5 | 18.20.3 | 18.20.8 | 18.20.8 | 22.22.1 |
| OpenSSL | 1.1.1 | 3.3.6 | 3.3.6 | 3.3.6 | 3.3.6 |
| Perl | 5.32.1 | 5.34.1 | 5.34.1 | 5.34.1 | 5.34.1 |
| Python | 3.9.2 | 3.12.3 | 3.13.3 | 3.14.0 | 3.14.3 |
| Rake | 13.2.1 | 13.0.6 | 13.0.6 | 13.3.0 | 13.0.6 |
| Rbenv | 1.3.0 | 1.2.0 | 1.3.2 | 1.3.2 | 1.3.2 |
| Ruby | 3.2.3 | 3.2.3 | 3.2.3 | 3.2.3 | 3.2.3 |
| Unzip | 6.00 | 6.00 | 6.00 | 6.00 | 6.00 |
| Wget | 1.21 | 1.24.5 | 1.25.0 | 1.25.0 | 1.25.0 |
| Yarn | 1.22.22 | 1.22.22 | 1.22.22 | 1.22.22 | 1.22.22 |
| Zip | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 |
### Using your own computer for build
Appcircle supports using a third-party computer to perform builds. You can create your own build environment by installing the operating system and other tools and dependencies you need to tell Appcircle to use that environment to perform builds.
Appcircle Self-hosted Runner
---
## Build Infrastructure
Select the optimal build stack for your iOS or Android applications to ensure compatibility and performance.
## [iOS Build Stacks](/infrastructure/ios-build-infrastructure)
Choose from a variety of iOS build stacks compatible with different versions of Xcode, Swift, and the iOS SDK to match your project's requirements.
## [Android Build Stacks](/infrastructure/android-build-infrastructure)
For Android projects, select a build stack that aligns with your needs for specific versions of the Android SDK, Gradle, and other build tools.
Properly setting up your build infrastructure is key to a smooth, efficient, and successful build process for your mobile applications.
---
## iOS Build Stacks
Depending on which Xcode version you select, Appcircle creates a brand new virtual machine running.
If your selected pool from config is "Appcircle macOS Pool (arm64)", there are several options for the virtual machine as listed below:
| Xcode Selection | macOS Version |
| ------- | ----- |
| 26.3.x or later | Tahoe `26.3.2` |
| 16.3.x - 26.3.x | Sequoia `15.6.1` / Sequoia `15.4.1` |
| 16.0.x - 16.2.x | Sequoia `15.6.1` / Sequoia `15.4.1` / Sonoma `14.5` |
| 14.3.x - 15.4.x | Sonoma `14.5` |
MacOS images run on fresh virtual machines for stability and performance. They are created just for your build and become ready within seconds.
During the build process, you can install any dependencies and run commands using [custom script](/workflows/common-workflow-steps/custom-script) steps in the build workflow. This gives you complete control over your build and the virtual machine.
:::info
Please note that virtual machines are wiped off after a build is executed (no matter success or fail) and anything you installed in the virtual machine will be gone.
:::
## Available Xcode Versions
Our macOS runners have Xcode versions 26.5.x, 26.4.x, 26.3.x, 26.2.x, 26.1.x, 26.0.x, 16.4.x, 16.3.x, 16.2.x, 16.1.x, 16.0.x, 15.4.x, 15.3.x, 15.2.x, 15.1.x, 15.0.x, 14.3.x available.
The "Appcircle macOS Pool (arm64)" macOS **Tahoe** (`26.3.2`) stack has the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 26.5 | `17F42` |
| 26.4.1 | `17E202` |
| 26.3 | `17C529` |
The "Appcircle macOS Pool (arm64)" macOS **Sequoia** (`15.6.1`) stack has the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 26.3 | `17C529` |
| 26.2 | `17C52` |
| 26.1.1 | `17B100` |
| 26.0.1 | `17A400` |
| 16.4 | `16F6` |
| 16.3 | `16E140` |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
The "Appcircle macOS Pool (arm64)" macOS **Sequoia** (`15.4.1`) stack has the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 16.4 | `16F6` |
| 16.3 | `16E140` |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
The "Appcircle macOS Pool (arm64)" macOS **Sonoma** (`14.5`) stack has the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
| 15.4 | `15F31d` |
| 15.3 | `15E204a` |
| 15.2 | `15C500b` |
| 15.1 | `15C65` |
| 15.0.1 | `15A507` |
| 14.3.1 | `14E300c` |
## iOS Build Environment
There are many pre-installed packages on virtual machines. You can get a full list of pre-installed packages by running Bash commands in the [custom script](/workflows/common-workflow-steps/custom-script) steps.
Here are some of the most important packages installed in our iOS build runners used for iOS builds:
| Package | macOS Sonoma | macOS Sequoia `15.4.1` | macOS Sequoia `15.6.1` | macOS Tahoe `26.3.2` |
| ------------------ | -------------- | -------------- | -------------- | -------------- |
| Bash | 3.2.57 | 3.2.57 | 3.2.57 | 5.3.9 |
| Bundle | 2.4.19 | 2.4.19 | 2.7.2 | 2.4.19 |
| Carthage | 0.39.1 | 0.40.0 | 0.40.0 | 0.40.0 |
| Curl | 8.6.0 | 8.7.1 | 8.7.1 | 8.7.1 |
| Homebrew | 4.3.5 | 4.5.1 | 4.6.16 | 5.1.0 |
| Java (OpenJDK) | 17.0.9 | 17.0.9 | 17.0.9 | 17.0.12 |
| Gem | 3.4.19 | 3.4.19 | 3.4.19 | 3.4.19 |
| Fastlane | 2.220.0 | 2.227.2 | 2.228.0 | 2.232.2 |
| Git | 2.45.2 | 2.49.0 | 2.51.0 | 2.53.0 |
| Git LFS | 3.5.1 | 3.6.1 | 3.7.0 | 3.7.1 |
| Gzip (Apple) | 430.100.5 | 457.100.3 | 457.140.3 | 475 |
| LibreSSL (OpenSSL) | 3.3.6 | 3.3.6 | 3.3.6 | 3.3.6 |
| ImageMagick | 7.1.1-33 | 7.1.1-47 | 7.1.2-5 | 7.1.2-17 |
| Maven | 3.9.7 | 3.9.9 | 3.9.11 | 3.9.14 |
| N | 9.2.3 | 10.1.0 | 10.2.0 | 10.2.0 |
| Node | 18.20.3 | 18.20.8 | 18.20.8 | 22.22.1 |
| Npm | 10.7.0 | 10.8.2 | 10.8.2 | 10.9.4 |
| Perl | 5.34.1 | 5.34.1 | 5.34.1 | 5.34.1 |
| Pod | 1.15.2 | 1.16.2 | 1.16.2 | 1.16.2 |
| Pip | 24.0 | 25.0.1 | 25.2 | 26.0 |
| Python | 3.12.3 | 3.13.3 | 3.14.0 | 3.14.3 |
| Rake | 13.0.6 | 13.0.6 | 13.3.0 | 13.0.6 |
| Ruby | 3.2.3 | 3.2.3 | 3.2.3 | 3.2.3 |
| Rbenv | 1.2.0 | 1.3.2 | 1.3.2 | 1.3.2 |
| Sdkman | 5.18.2 | 5.19.0 | 5.20.0 | 5.21.0 |
| Slather | 2.8.0 | 2.8.5 | 2.8.5 | 2.8.5 |
| Unzip | 6.00 | 6.00 | 6.00 | 6.00 |
| Xcodeproj | 1.27.0 | 1.27.0 | 1.27.0 | 1.27.0 |
| Yarn | 1.22.22 | 1.22.22 | 1.22.22 | 1.22.22 |
| Zip | 3.0 | 3.0 | 3.0 | 3.0 |
### Using your own computer for build
Appcircle supports using a third-party computer to perform builds. You can create your own build environment by installing the operating system and other tools and dependencies you need to tell Appcircle to use that environment to perform builds.
Appcircle Self-hosted Runner
---
## Machine Plans
Appcircle provides different **Machine Plans** to give you flexibility and scalability depending on your build requirements.
By default, all users are on the **Standard** plan, which is suitable for regular build workloads. For faster build times or more demanding workloads, you can upgrade to **Velocity** or **Ultra** machine plans, which offer higher CPU and memory resources.
Users can view their current machine plan from:
- **Build Configurations**
- **Build Logs**
- **Build History**
- **Billing Page**
:::tip Upgrade Your Machine Plan
To upgrade your machine plan, please [contact our team](https://appcircle.io/contact).
:::
## Standard Plan
| Operating System | Machine Type | Architecture | CPU | RAM |
|------------------|-----------------|-------------|---------|------|
| macOS | M1 | `arm64` | 6 vCPU | 7 GB |
| Linux | AMD EPYC™ 7313 | `x86_64` | 8 vCPU | 15 GB |
---
## Velocity Plan
| Operating System | Machine Type | Architecture | CPU | RAM |
|------------------|-----------------|-------------|---------|------|
| macOS | M2 Pro | `arm64` | 10 vCPU | 15 GB |
| macOS | M2 Pro | `arm64` | 8 vCPU | 7 GB |
| macOS | M2 Max | `arm64` | 10 vCPU | 31 GB |
| Linux | AMD EPYC™ 7313 | `x86_64` | 8 vCPU | 15 GB |
---
## Ultra Plan
| Operating System | Machine Type | Architecture | CPU | RAM |
|------------------|-----------------|-------------|---------|------|
| macOS | M4 Pro | `arm64` | 10 vCPU | 23 GB |
| macOS | M4 Pro | `arm64` | 10 vCPU | 31 GB |
| Linux | AMD EPYC™ 7313 | `x86_64` | 8 vCPU | 15 GB |
---
## Appcircle Documentation
Build.Test.Distribute.
Make better, safer mobile app releases with Appcircle.
Platform Build Guides
New to Appcircle? Get started by adding your Obj-C/Swift, Java/Kotlin, React Native, Flutter app first.
Building Your Apps
Learn about setting up your repository, creating workflows and how to automatically trigger a build.
Send to Testers & Stores
Add testers, set up your builds to be auto distributed to them and Apple App Store, Testflight, Google Play, Huawei AppGallery and Firebase.
Running Unit & UI Tests
Learn how to run Unit and UI tests and see detailed reports on which ones have failed and why.
Build
Supports major mobile stacks including native and cross-platform frameworks. Seamless integration with popular Git providers like GitHub, BitBucket, and GitLab.
Customizable workflows with automated processes and secure environment management.
Advanced caching, versioning, and real-time build insights with detailed dashboards.
Learn how
Signing Identities
Manage iOS certificates and Android keystores centrally & securely, accessible across multiple projects.
Automate certificate and provisioning profile management with App Store Connect integration.
Receive notifications for expiring certificates and track signing activities with detailed audits.
Learn how
Testing Distribution
Distribute app builds via email, QR codes, and webhooks. Share .IPA, APK, and other file formats directly.
Create test groups, automate distribution, and integrate with DevOps pipelines.
Securely manage test groups with LDAP/SSO (OpenID & SAML) and track engagement with detailed reports.
Learn how
Publish
Publish apps to App Store, Google Play, and Huawei AppGallery from a single module. Automate the process with customizable workflows.
Track release performance with audit logs and reports, and update metadata like descriptions, keywords, and screenshots.
Deploy to multiple platforms like App Store, TestFlight, Google Play, and more, with phased rollouts and version management support.
Learn how
Create your own app store.
Some apps are not meant to be on App Stores. That’s why we’re introducing Enterprise App Store. A way for you to distribute your internal apps.
Learn how
Self-Hosted Appcircle
Want to use your own build machines? Just install our runner scripts to the machines you want to use for your iOS / Android builds.
Learn how
## Dive Deeper into Appcircle
Slack Community
How-To Videos
Follow us on Twitter
Contact Us
### See something that's not documented here?
Send us a request and we will get it in: [Appcircle Support](https://appcircle.io/support/)
---
## Setting Up Appcircle Enterprise App Store Plugin
The Appcircle Enterprise App Store plugin allows users to publish their apps and start distribution to test groups or individuals.
### Discover Action
You can discover more about this action and install it from:
https://rubygems.org/gems/fastlane-plugin-appcircle_enterprise_store
## System Requirements
**Compatible Agents:**
- macOS 14 (arm64)
- RHEL 9 (x86_64)
- Ubuntu 22.04 (x86_64)
**Supported Version:**
- Fastlane 2.222.0
- Ruby 3.2.2
:::caution
Currently, plugins are only compatible to use with Appcircle Cloud. Self-hosted support will be available in future releases.
:::
### Getting Started
This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `appcircle_enterprise_app_store`, add it to your project by running:
```bash
fastlane add_plugin appcircle_enterprise_app_store
```
After adding the plugin to your project, configure your Fastfile as follows:
```ruby
lane :distribute_app_store do
appcircle_enterprise_app_store(
personalAPIToken: "$(AC_PERSONAL_API_TOKEN)",
appPath: "$(APP_PATH)",
summary: "$(SUMMARY)",
releaseNotes: "$(RELEASE_NOTE)",
publishType: "$(PUBLISH_TYPE)" # Assign the appropriate number based on the status: None (0), Beta (1), Live (2)
)
end
```
- `personalAPIToken`: The Appcircle Personal API token is utilized to authenticate and secure access to Appcircle services, ensuring that only authorized users can perform actions within the platform.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Testing Distribution Profile.
- `releaseNotes`: Contains the details of changes, updates, and improvements made in the current version of the app being published.
- `summary`: Used to provide a brief overview of the version of the app that is about to be published.
- `publishType`: Specifies the publishing status as either none, beta, or live, and must be assigned the values "0", "1", or "2" accordingly.
### Leveraging Environment Variables
Utilize environment variables seamlessly by substituting the parameters with `$(VARIABLE_NAME)` in your task inputs. The extension automatically retrieves values from the specified environment variables within your pipeline.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If two workflows start simultaneously, the last workflow to reach the publish step will be the up-to-date version on the Enterprise App Store. If these workflows building the same package version, the first publish will be successful, while later deployments with the same version will fail.
:::
## References
- For more detailed instructions and support, visit the [Appcircle Enterprise App Store documentation](/enterprise-app-store).
---
## Fastlane Marketplace
Enhance the power of distributing builds to test groups or releasing beta versions of your apps by using the **Appcircle Testing Distribution** and **Appcircle Enterprise App Store** plugins.
### [Testing Distribution](/marketplace/fastlane/testing-distribution)
It is a process of distributing test builds to designated test groups or individuals.
### [Enterprise App Store](/marketplace/fastlane/enterprise-app-store)
Your own mobile app store to provide access to in-house apps with a customizable mobile storefront.
---
## Setting Up Appcircle Testing Distribution Plugin For Fastlane
# Setting Up Appcircle Testing Distribution Plugin
The Appcircle Testing Distribution plugin allows users to upload their apps and start distribution to test groups or individuals.
### Discover Action
You can discover more about this action and install it from:
https://rubygems.org/gems/fastlane-plugin-appcircle_testing_distribution
### System Requirements
**Compatible Agents:**
- macOS 14 (arm64)
- RHEL 9 (x86_64)
- Ubuntu 22.04 (x86_64)
**Supported Version:**
- Fastlane 2.222.0
- Ruby 3.2.2
:::caution
Currently, plugins are only compatible to use with **Appcircle Cloud**. **Self-hosted** support will be available in future releases.
:::
### User Permission Requirements
To perform operations such as generating a Personal API Token, creating a testing distribution profile, and managing testing groups, your user role must have the necessary permissions in the target organization. For more information about user roles and permissions, please refer to the relevant sections of the Role Management documentation below.
- Access to organization or sub-organization and generating PAT: [Organization Management Permissions](/account/my-organization/profile-and-team/role-management#organization-management-permissions).
- Testing distribution operations and profile management: [Testing Distribution Permissions](/account/my-organization/profile-and-team/role-management#testing-distribution-permissions).
- Testing group management: [Testing Group Permissions](/account/my-organization/profile-and-team/role-management#testing-group-permissions).
### How to Add the Appcircle Distribute Action to Your Pipeline
To use the Appcircle Testing Distribution action, install the plugin and add the following step to your pipeline at the end:
```bash
fastlane add_plugin appcircle_testing_distribution
```
```ruby
appcircle_testing_distribution(
personalAPIToken: ENV["AC_PERSONAL_API_TOKEN"],
subOrganizationName: ENV["AC_SUB_ORGANIZATION_NAME"],
profileName: ENV["AC_PROFILE_NAME"],
createProfileIfNotExists: ENV["AC_CREATE_PROFILE_IF_NOT_EXISTS"],
profileCreationSettings: {
authType: ENV["AC_PROFILE_AUTH_TYPE"],
username: ENV["AC_PROFILE_USERNAME"],
password: ENV["AC_PROFILE_PASSWORD"],
testingGroupNames: ENV["AC_PROFILE_TESTING_GROUP_NAMES"]
},
appPath: ENV["AC_APP_PATH"],
message: ENV["AC_MESSAGE"]
)
```
- `personalAPIToken`: The Appcircle Personal API token used to authenticate and authorize access to Appcircle services within this plugin.
- `subOrganizationName` (optional): Required when the Root Organization's `personalAPIToken` is used, and you want to create the profile under a sub-organization. In this case, provide the name of the sub-organization in this field. If you directly used the sub-organization's `personalAPIToken`, this parameter is not needed.
- `profileName`: Specifies the profile that will be used for uploading the app.
- `createProfileIfNotExists` (optional): Ensures that a testing distribution profile is automatically created if it does not already exist; if the profile name already exists, the app will be uploaded to that existing profile instead.
- `profileCreationSettings` (optional): If `createProfileIfNotExists` is `true` and a new profile being created, the profile will be configured with these settings.
- `authType`: Authentication type of the profile. `none`: None, `static`: Static Username and Password, `ldap`: LDAP Login, `sso`: SSO Login.
- `username`: The username for the profile if authentication type set to `static` (Static Username and Password).
- `password`: The password for the profile if authentication type set to `static` (Static Username and Password).
- `testingGroupNames`: Uploaded versions will be automatically shared with these testing groups. Example format: `group1, group2, group3`.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Testing Distribution Profile.
- `message`: Your message to testers, ensuring they receive important updates and information regarding the application.
:::tip
Profile creation settings are only used when a new profile is created. If you need to update these settings, please go to the [profile settings](https://docs.appcircle.io/testing-distribution/create-or-select-a-distribution-profile#settings) in the Appcircle dashboard.
:::
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If multiple workflows start simultaneously, the order in which versions are shared in the Testing Distribution is determined by the execution order of the publish step. The version that completes its build and triggers the publish plugin first will be shared first, followed by the others in sequence.
:::
### Distributing to Sub-Organizations
To distribute your app to a sub-organization, you can use one of the following methods:
#### 1. Using the Root Organization's Personal API Token
- Obtain the `personalAPIToken` for the Root Organization. This token is used to authenticate and authorize actions within Appcircle.
- Specify the `subOrganizationName` parameter in your configuration. This parameter indicates the target sub-organization where the profile will be created and the app will be distributed.
#### 2. Using the Sub-Organization's Personal API Token
- Invite your user to the sub-organization and obtain the `personalAPIToken` for the sub-organization. This token directly authenticates and authorizes actions within the specific sub-organization.
- Use the sub-organization's `personalAPIToken` in your configuration.
With this configuration, the profile will be created and the app will be distributed within the sub-organization.
### CLI Usage
Recommended method of using the action is adding it to the `Fastfile` as described [above](#how-to-add-the-appcircle-distribute-action-to-your-pipeline).
If you prefer to use it from the terminal, you can execute the following command and enter the inputs interactively:
```bash
fastlane run appcircle_testing_distribution
```
To pass parameters with the command, you can use the `:symbol` format. For example:
```bash
fastlane run appcircle_testing_distribution parameter1:"value1" parameter2:"value2"
```
:::caution IMPORTANT NOTE
The CLI only supports primitive types such as integers, floats, booleans, and strings. Arrays can be passed as a comma-separated string (e.g., `parameter:"value1,value2,value3"`). Hashes are not currently supported, so to use parameters like `profileCreationSettings`, it is recommended to add the action to the `Fastfile` as described.
:::
### Leveraging Environment Variables
Utilize environment variables seamlessly by substituting the parameters with `ENV["VARIABLE_NAME"]` in your task inputs. The extension automatically retrieves values from the specified environment variables within your pipeline.
## References
- To create or learn more about Appcircle testing and distribution profiles, please refer to [Creating or Selecting a Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile).
---
## Setting Up Appcircle Enterprise App Store Action
The Appcircle Enterprise App Store action allows users to publish their apps to appcircle app store.
## System Requirements
**Compatible Agents:**
- macOS 14 (arm64)
- Ubuntu 22.04 (x86_64)
:::caution
Currently, plugins are only compatible to use with **Appcircle Cloud**. **Self-hosted** support will be available in future releases.
:::
### Discover Action
You can discover more about this action and install it from:
https://github.com/marketplace/actions/appcircle-enterprise-app-store
### How to Add the Appcircle Enterprise App Store Action to Your Pipeline
To use the Appcircle Enterprise App Store action, add the following step to your pipeline at the end:
```yml
- name: Publish App to Appcircle Enterprise App Store
id: store-publish-to-appcircle
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
```
- `personalAPIToken`: The Appcircle Personal API token is utilized to authenticate and secure access to Appcircle services, ensuring that only authorized users can perform actions within the platform.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Testing Distribution Profile.
- `releaseNotes`: Contains the details of changes, updates, and improvements made in the current version of the app being published.
- `summary`: Used to provide a brief overview of the version of the app that is about to be published.
- `publishType`: Specifies the publishing status as either none, beta, or live, and must be assigned the values "0", "1", or "2" accordingly.
## Leveraging Environment Variables
Utilize environment variables seamlessly by substituting the parameters with **secrets.NAME** in your task inputs. The action automatically retrieves values from the specified environment variables within your pipeline.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If two workflows start simultaneously, the last workflow to reach the publish step will be the up-to-date version on the Enterprise App Store. If these workflows building the same package version, the first publish will be successful, while later deployments with the same version will fail.
:::
## References
- For more detailed instructions and support, visit the [Appcircle Enterprise App Store documentation](/enterprise-app-store).
---
## GitHub Marketplace
Enhance the power of distributing builds to test groups or releasing beta versions of your apps by using the **Appcircle Testing Distribution** and **Appcircle Enterprise App Store** actions.
### [Testing Distribution](/marketplace/github-marketplace/testing-distribution)
It is a process of distributing test builds to designated test groups or individuals.
### [Enterprise App Store](/marketplace/github-marketplace/enterprise-app-store)
Your own mobile app store to provide access to in-house apps with a customizable mobile storefront.
---
## Setting Up Appcircle Testing Distribution Action
The Appcircle Testing Distribution action allows users to upload their apps and start distribution to test groups or individuals.
### Discover Action
You can discover more about this action and install it from:
https://github.com/marketplace/actions/appcircle-testing-distribution
## System Requirements
**Compatible Agents:**
- macOS 14 (arm64)
- Ubuntu 22.04 (x86_64)
:::caution
Currently, plugins are only compatible to use with **Appcircle Cloud**. **Self-hosted** support will be available in future releases.
:::
### How to Add the Appcircle Testing Distribution Action to Your Pipeline
To install the Appcircle Testing Distribution action, add the following step to your pipeline at the end:
```yaml
- name: Publish App to Appcircle
id: testing-distribution-appcircle
uses: appcircleio/appcircle-testing-distribution-githubaction
with:
personalAPIToken: ${{ secrets.AC_PROFLE_API_TOKEN }}
profileName: ${{ secrets.AC_PROFILE_NAME }}
createProfileIfNotExists: ${{ secrets.CREATE_PROFILE_IF_NOT_EXISTS }}
appPath: ${{ secrets.APP_PATH }}
message: ${{ secrets.MESSAGE }}
```
- `personalAPIToken`: The Appcircle Personal API token is used to authenticate and secure access to Appcircle services. Add this token to your credentials to enable its use in your pipeline and ensure authorized actions within the platform.
- `profileName`: Specifies the profile that will be used for uploading the app.
- `createProfileIfNotExists`: Ensures that a user profile is automatically created if it does not already exist; if the profile name already exists, the app will be uploaded to that existing profile instead.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Testing Distribution Profile.
- `message`: Your message to testers, ensuring they receive important updates and information regarding the application.
## Leveraging Environment Variables
Utilize environment variables seamlessly by substituting the parameters with **secrets.NAME** in your task inputs. The action automatically retrieves values from the specified environment variables within your pipeline.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If multiple workflows start simultaneously, the order in which versions are shared in the Testing Distribution is determined by the execution order of the publish step. The version that completes its build and triggers the publish plugin first will be shared first, followed by the others in sequence.
:::
## References
- To create or learn more about Appcircle testing and distribution profiles, please refer to [Creating or Selecting a Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile)
---
## Marketplace Overview
Appcircle offers a variety of extensions to facilitate integrations with other platforms.
## [Fastlane Marketplace](/marketplace/fastlane)
Appcircle enhances the power of distributing builds to test groups or releasing beta versions of your apps with the Appcircle Testing Distribution and Appcircle Enterprise App Store plugins.
The Testing Distribution process allows you to distribute test builds to designated test groups or individuals. The Enterprise App Store serves as your own mobile app store, providing access to in-house apps with a customizable mobile storefront.
## [GitHub Marketplace](/marketplace/github-marketplace)
Maximize the efficiency of your app distribution by leveraging Appcircle's Testing Distribution and Enterprise App Store actions on GitHub Marketplace.
Testing Distribution simplifies the process of sending test builds to specific test groups or individuals. The Enterprise App Store enables you to create a private mobile app store, offering access to internal apps with a customizable storefront tailored to your needs.
## [Jenkins Marketplace](/marketplace/jenkins)
In the Jenkins Marketplace, Appcircle offers robust solutions for automating build distribution and app management.
Leverage Testing Distribution to efficiently distribute test builds to specific test groups or individuals. The Enterprise App Store enables organizations to create a branded app portal for internal applications, enhancing accessibility and control.
## [Visual Studio Marketplace](/marketplace/visual-studio-marketplace)
Appcircle offers two extensions: "Testing Distribution" and "Enterprise App Store". These help users distribute builds to test groups, individuals, or for beta testing.
## [OpenAI Marketplace](/marketplace/open-ai)
Appcircle offers a custom Assistant GPT that provides users with quick, clear answers about Appcircle, including step-by-step instructions and troubleshooting support.
---
## Setting Up Appcircle Enterprise App Store Plugin For Jenkins
### Discover Plugin
You can discover more about this action and install it from:
https://plugins.jenkins.io/appcircle-enterprise-store/
# Setting Up Appcircle Enterprise App Store Plugin
The Appcircle Enterprise App Store plugin enables users to publish their apps to the Appcircle App Store.
## System Requirements
**Compatible Agents:**
- macOS 14 (arm64)
**Supported Version:**
- Jenkins 2.440.3
:::caution
Currently, plugins are only compatible to use with **Appcircle Cloud**. **Self-hosted** support will be available in future releases.
:::
### Install Appcircle Enterprise App Store Plugin
Go to your Jenkins dashboard and navigate to Manage Jenkins > Manage Plugins. Then, search for "Appcircle Enterprise App Store" in the available plugins section.
### Add Plugin in Build Steps
Go to your configuration page of the project and add a build step.
### Configure Plugin
After adding the plugin to your build steps, ensure that you provide all required inputs.
Additionally, remember to place the plugin after your build steps as you will need to specify the build path later on.
### Using Plugin into Your Script
```Groovy
stage('Publish') {
environment {
AC_PAT = credentials('AC_PAT')
}
steps {
appcircleEnterpriseAppStore personalAPIToken: AC_PAT,
appPath: '$APP_PATH',
releaseNotes: '$RELEASE_NOTE',
summary: '$SUMMARY',
publishType: '$PUBLISH_TYPE' // "0": None, "1": Beta, "2": Live
}
}
```
- `personalAPIToken`: The Appcircle Personal API token is utilized to authenticate and secure access to Appcircle services, ensuring that only authorized users can perform actions within the platform.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Enterprise App Store Profile.
- `releaseNotes`: Contains the details of changes, updates, and improvements made in the current version of the app being published.
- `summary`: Used to provide a brief overview of the version of the app that is about to be published.
- `publishType`: Specifies the publishing status as either none, beta, or live, and must be assigned the values "0", "1", or "2" accordingly.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If two workflows start simultaneously, the last workflow to reach the publish step will be the up-to-date version on the Enterprise App Store. If these workflows building the same package version, the first publish will be successful, while later deployments with the same version will fail.
:::
## References
- For more detailed instructions and support, visit the [Appcircle Enterprise App Store documentation](/enterprise-app-store).
---
## Jenkins Marketplace
Enhance the power of distributing builds to test groups or releasing beta versions of your apps by using **Appcircle Testing Distribution** and **Appcircle Enterprise App Store** actions.
### [Testing Distribution](/marketplace/jenkins/testing-distribution)
It is a process distributing test builds to designated test groups or individuals.
### [Enterprise App Store](/marketplace/jenkins/enterprise-app-store)
Your own mobile app store to provide access to in-house apps with a customizable mobile storefront.
---
## Setting Up Appcircle Testing Distribution Plugin
The Appcircle Testing Distribution plugin allows users to upload their apps and start distribution to test groups or individuals.
### Discover Plugin
You can discover more about this action and install it from:
https://plugins.jenkins.io/appcircle-testing-distribution/
## System Requirements
**Compatible Agents:**
- macOS 14 (arm64)
**Supported Version:**
- Jenkins 2.440.3
:::caution
Currently, plugins are only compatible to use with **Appcircle Cloud**. **Self-hosted** support will be available in future releases.
:::
### Install Appcircle Testing Distribution Plugin
Go to your Jenkins dashboard and navigate to Manage Jenkins > Manage Plugins. Then, search for "Appcircle Testing Distribution" in the available plugins section.
### Add Plugin in Build Steps
Go to your configuration page of the project add a build step.
### Configure Plugin
After adding the plugin to your build steps, ensure that you provide all required inputs.
Additionally, remember to place the plugin after your build steps as you will need to specify the build path later on.
### Adding the Plugin to Your Pipeline
```Groovy
stage('Publish') {
environment {
AC_PAT = credentials('AC_PAT')
}
steps {
appcircleTestingDistribution personalAPIToken: AC_PAT,
profileName: 'PROFILE_NAME',
createProfileIfNotExists: false,
appPath: 'APP_PATH',
message: 'MESSAGE'
}
}
```
- `personalAPIToken`: The Appcircle Personal API token is used to authenticate and secure access to Appcircle services. Add this token to your credentials to enable its use in your pipeline and ensure authorized actions within the platform.
- `profileName`: Specifies the profile that will be used for uploading the app.
- `createProfileIfNotExists`: Ensures that a user profile is automatically created if it does not already exist; if the profile name already exists, the app will be uploaded to that existing profile instead.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Testing Distribution Profile.
- `message`: Your message to testers, ensuring they receive important updates and information regarding the application.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If multiple workflows start simultaneously, the order in which versions are shared in the Testing Distribution is determined by the execution order of the publish step. The version that completes its build and triggers the publish plugin first will be shared first, followed by the others in sequence.
:::
## References
- For more detailed instructions and support, visit the [Testing Distribution documentation](/testing-distribution).
---
## OpenAI Marketplace
Appcircle provides a custom **Appcircle Assistant** GPT designed to deliver quick and clear answers, offering step-by-step guidance and troubleshooting support for users.
https://chatgpt.com/g/g-686e31aa891481919ef3603325b15ae0-appcircle-assistant
### How to Use Appcircle Assistant
Getting started with the Appcircle Assistant is simple. Just follow these steps:
1. Log in to your [ChatGPT account](https://chatgpt.com/).
2. In the left-hand menu, click **GPTs**.
3. Use the search bar to type **Appcircle Assistant**.
4. Click on it to open and start your conversation with the **Appcircle Assistant**.
---
## Setting Up Appcircle Enterprise App Store in Azure DevOps Pipeline
Appcircle Enterprise App Store serves as your private mobile app store, allowing access to in-house apps through a customizable mobile storefront. The Appcircle Enterprise App Store extension enables you to upload your app to your personalized app store within Appcircle.
### System Requirements
**Compatible Azure DevOps Versions:**
- Azure DevOps Services (cloud)
- Azure DevOps Server 2020 (on-premises)
- Azure DevOps Server 2022 (on-premises)
**Compatible Agents:**
Both cloud and self-hosted agents are supported.
- macOS 14 (arm64)
- Ubuntu 22.04 (x86_64)
### Setup Appcircle Enterprise App Store
Refer to our comprehensive [Enterprise App Store Docs](/enterprise-app-store) for detailed information about: Enterprise App Store profiles, portal customization, portal settings, enterprise portal, portal reports, in-app updates and more.
### How to Get the Appcircle Enterprise App Store Extension
#### Permissions
Before installing the extension, ensure you have the necessary permissions in your Azure DevOps organization. If you don't have permission to add extensions, you'll need to [request approval](https://learn.microsoft.com/en-us/azure/devops/marketplace/request-extensions) from your organization administrator.
#### Installation
You can discover more about this extension and install it from here:
https://marketplace.visualstudio.com/items?itemName=Appcircle.enterprise-app-store
For details on how to install the extension, visit the Azure [extension installation](https://learn.microsoft.com/en-us/azure/devops/marketplace/install-extension) guide.
:::tip
When visiting the installation guide, ensure you select the correct version of Azure DevOps from the dropdown menu at the top of the page. The available options include "Azure DevOps Services" and "Azure DevOps Server 2022" etc.
:::
### How to Add the Appcircle Enterprise App Store Task into Your Pipeline
#### 1. Get a Personal API Token
For this extension to authenticate to your Appcircle, you need to create a Personal API Token, and use it in your task configuration.
You can follow the [Generating and Managing Personal Access Keys](/account/my-organization/security/personal-access-key) page to create a Personal Access Key for a PAT.
#### 2. Add Task to Your Pipeline
In order to install Appcircle Enterprise App Store Extension, follow these steps;
1. Go to your pipeline, click "Edit" button on the top right corner.
2. Inside your YAML file, search for "Appcircle Enterprise App Store" task.
3. Complete the necessary input fields and then click the "Add" button.
#### 3. Configure the Task
After filling out the required fields, the `AppcircleEnterpriseStore@0` task will appear in your pipeline steps as shown below:
```yaml
- task: AppcircleEnterpriseStore@0
inputs:
personalAPIToken: $(AC_PERSONAL_API_TOKEN)
authEndpoint: $(AC_AUTH_ENDPOINT)
apiEndpoint: $(AC_API_ENDPOINT)
appPath: $(AC_APP_PATH)
summary: $(AC_SUMMARY)
releaseNotes: $(AC_RELEASE_NOTES)
publishType: $(AC_PUBLISH_TYPE)
```
- `personalAPIToken`: The Appcircle Personal API token used to authenticate and authorize access to Appcircle services within this extension.
- `authEndpoint` (optional): Authentication endpoint URL for self-hosted Appcircle installations. If not specified, uses Appcircle Cloud by default (`auth.appcircle.io`).
- `apiEndpoint` (optional): API endpoint URL for self-hosted Appcircle installations. If not specified, uses Appcircle Cloud by default (`api.appcircle.io`).
- `appPath`: Indicates the file path to the application that will be uploaded to Appcircle Enterprise App Store. The path can be specified in two ways:
**When Build and Enterprise App Store tasks are in the same pipeline:**
Assuming you are using Enterprise App Store task after a build step, you can use the output directory of the build step. For example:
- iOS:
- `$(Build.SourcesDirectory)/output/app.ipa` or
- `./output/app.ipa`
- Android:
- `$(Build.SourcesDirectory)/app/build/outputs/apk/release/app-release.apk` or
- `./app/build/outputs/apk/release/app-release.apk`
**When Enterprise App Store task is a separate pipeline:**
Assuming you have published a build artifact in your build pipeline using `PublishBuildArtifacts` task, you can get the artifact using `DownloadBuildArtifacts` task into a specified directory and use it in the Enterprise App Store pipeline. For example:
- `$(Build.ArtifactStagingDirectory)/app.ipa`
- `$(Build.ArtifactStagingDirectory)/app.apk`
Make sure the path points to a valid application package file.
- `releaseNotes`: Contains the details of changes, updates, and improvements made in the current version of the app being published.
- `summary`: Used to provide a brief overview of the version of the app that is about to be published.
- `publishType`: Specifies the publishing status as either none, beta, or live, and must be assigned the values "None", "Beta", or "Live" accordingly.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If two workflows start simultaneously, the last workflow to reach the publish step will be the up-to-date version on the Enterprise App Store. If these workflows building the same package version, the first publish will be successful, while later deployments with the same version will fail.
:::
### Using with Appcircle Self-Hosted
#### Self-signed Certificates
Adding custom certificates is **not** currently supported in this extension.
:::caution
If your self-hosted Appcircle server has self-signed certificates, the Azure DevOps agent that runs the pipeline must trust your Appcircle server's certificates.
:::
### Leveraging Environment Variables
Utilize environment variables seamlessly by substituting the parameters with `$(VARIABLE_NAME)` in your task inputs. The extension automatically retrieves values from the specified environment variables within your pipeline.
## References
- For more detailed instructions and support, visit the [Appcircle Enterprise App Store documentation](/enterprise-app-store).
---
## Visual Studio Marketplace
Enhance the power of distributing builds to test groups or releasing beta versions of your apps by using **Appcircle Testing Distribution** and **Appcircle Enterprise App Store** actions.
### [Testing Distribution](/marketplace/visual-studio-marketplace/testing-distribution)
It is a process distributing test builds to designated test groups or individuals.
### [Enterprise App Store](/marketplace/visual-studio-marketplace/enterprise-app-store)
Your own mobile app store to provide access to in-house apps with a customizable mobile storefront.
---
## Setting Up Appcircle Testing Distribution Task in Azure DevOps Pipeline
The Appcircle distribute extension allows users to upload their apps and start distribution to test groups or individuals.
### System Requirements
**Compatible Azure DevOps Versions:**
- Azure DevOps Services (cloud)
- Azure DevOps Server 2020 (on-premises)
- Azure DevOps Server 2022 (on-premises)
**Compatible Agents:**
Both cloud and self-hosted agents are supported.
- macOS 14 (arm64)
- Ubuntu 22.04 (x86_64)
### Setup Appcircle Testing Distribution
Refer to our comprehensive [Testing Distribution Docs](/testing-distribution) for detailed information about: Distribution profiles, Testing groups, Binary re-signing, Testing portal, Reporting and more.
### How to Get the Appcircle Testing Distribution Extension
#### Permissions
Before installing the extension, ensure you have the necessary permissions in your Azure DevOps organization. If you don't have permission to add extensions, you'll need to [request approval](https://learn.microsoft.com/en-us/azure/devops/marketplace/request-extensions) from your organization administrator.
#### Installation
You can discover more about this extension and install it from here:
https://marketplace.visualstudio.com/items?itemName=Appcircle.build-release-task
For details on how to install the extension, visit the Azure [extension installation](https://learn.microsoft.com/en-us/azure/devops/marketplace/install-extension) guide.
:::tip
When visiting the installation guide, ensure you select the correct version of Azure DevOps from the dropdown menu at the top of the page. The available options include "Azure DevOps Services" and "Azure DevOps Server 2022" etc.
:::
### How to Add the Appcircle Testing Distribution Task into Your Pipeline
#### 1. Get a Personal API Token
For this extension to authenticate to your Appcircle, you need to create a Personal API Token, and use it in your task configuration.
You can follow the [Generating and Managing Personal Access Keys](/account/my-organization/security/personal-access-key) page to create an Access Key for a PAT.
#### 2. Add Task to Your Pipeline
To install the Appcircle Testing Distribution Extension, follow these steps:
1. Go to your pipeline, click "Edit" button on the top right corner.
2. Search for the “Appcircle Testing Distribution" task within your `YAML` file.
3. Fill out the necessary input fields and click the **Add** button.
#### 3. Configure the Task
After filling out the required fields, the `AppcircleTestingDistribution@0` task will appear in your pipeline steps as shown below:
```yaml
- task: AppcircleTestingDistribution@0
inputs:
personalAPIToken: $(AC_PROFILE_API_TOKEN)
authEndpoint: $(AC_AUTH_ENDPOINT)
apiEndpoint: $(AC_API_ENDPOINT)
profileName: $(AC_PROFILE_NAME)
createProfileIfNotExists: $(AC_CREATE_PROFILE_IF_NOT_EXISTS)
appPath: $(AC_APP_PATH)
message: $(AC_MESSAGE)
```
- `personalAPIToken`: The Appcircle Personal API token used to authenticate and authorize access to Appcircle services within this extension.
- `authEndpoint` (optional): Authentication endpoint URL for self-hosted Appcircle installations. If not specified, uses Appcircle Cloud by default (`auth.appcircle.io`).
- `apiEndpoint` (optional): API endpoint URL for self-hosted Appcircle installations. If not specified, uses Appcircle Cloud by default (`api.appcircle.io`).
- `profileName`: Specifies the profile that will be used for uploading the app.
- `createProfileIfNotExists` (optional): Ensures that a testing distribution profile is automatically created if it does not already exist; if the profile name already exists, the app will be uploaded to that existing profile instead.
- `appPath`: Indicates the file path to the application package that will be uploaded to Appcircle Testing Distribution Profile. The path can be specified in two ways:
**When Build and Testing Distribution tasks are in the same pipeline:**
Assuming you are using Testing Distribution task after a build step, you can use the output directory of the build step. For example:
- iOS
- `$(Build.SourcesDirectory)/output/app.ipa` or
- `./output/app.ipa`
- Android
- `$(Build.SourcesDirectory)/app/build/outputs/apk/release/app-release.apk` or
- `./app/build/outputs/apk/release/app-release.apk`
**When Testing Distribution task is a separate pipeline:**
Assuming you have published a build artifact in your build pipeline using `PublishBuildArtifacts` task, you can get the artifact using `DownloadBuildArtifacts` task into a specified directory and use it in the distribution pipeline. For example:
- `$(Build.ArtifactStagingDirectory)/app.ipa`
- `$(Build.ArtifactStagingDirectory)/app.apk`
Make sure the path points to a valid application package file.
- `message` (optional): Your message to testers, ensuring they receive important updates and information regarding the application.
:::caution Build Steps Order
Ensure that this action is added after build steps have been completed.
:::
:::caution
If multiple workflows start simultaneously, the order in which versions are shared in the Testing Distribution is determined by the execution order of the publish step. The version that completes its build and triggers the publish plugin first will be shared first, followed by the others in sequence.
:::
### Using with Appcircle Self-Hosted
#### Self-signed Certificates
Adding custom certificates is **not** currently supported in this extension.
:::caution
If your self-hosted Appcircle server has self-signed certificates, the Azure DevOps agent that runs the pipeline must trust your Appcircle server's certificates.
:::
### Leveraging Environment Variables
Utilize environment variables seamlessly by substituting the parameters with `$(VARIABLE_NAME)` in your task inputs. The extension automatically retrieves values from the specified environment variables within your pipeline.
## References
- To create or learn more about Appcircle testing and distribution profiles, please refer to [Creating or Selecting a Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile)
---
## App Information from Google Play
The **App Information from Google Play** step checks the status of the app releases in the [Google Play Console](https://play.google.com/console). This allows you to monitor the progress of your app.
:::tip
The **App Information from Google Play** step monitors the general status information of the app on Google Play. It is not limited to the specific version you sent.
:::
## Prerequisites
To run the **App Information from Google Play** step, you need to have previously uploaded at least one version of the app to the Google Play Console. However, if you want to monitor the app information after publishing it to Google Play, you can add the [**Publish to Google Play**](/publish-integrations/android-publish-integrations/publish-to-google-play) step before this step in the publish flow.
You also need to have a Google Service Account and its key as a JSON file. Please refer to the following document for more information about service accounts:
Adding Google Play Service Accounts
After completing the integration with Google Play Services, go to [Publishing Settings](/publish-to-stores-module/publish-settings). In the [Store Credential](/publish-to-stores-module/publish-settings#store-credentials) section, select the Google Play Store API Key you uploaded, from the drop-down list.
:::info
If you are using [Publish Variables](/publish-to-stores-module/publish-settings#publish-variables), you should select them in the [Publishing Settings](/publish-to-stores-module/publish-settings) window.
:::
## Input Variables
No input variables are required for the **App Information from Google Play** step. It will retrieve information from Google Play, based on the app you are running and the [Store Credential](/publish-to-stores-module/publish-settings#store-credentials) you select in [Publishing Settings](/publish-to-stores-module/publish-settings).
## Output Variables
**App Information from Google Play** step does not produce any output variables. However, you can check the logs to see detailed release statuses for your app.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-playstore-app-information.git
---
## Distribute to Track
The **Distribute to Track** step in Appcircle enables automated deployment of Android applications to specific tracks within the Google Play Console. This functionality allows developers to manage releases efficiently, targeting different user groups such as internal testers, beta users, or the general public.
## Prerequisites
The Publish flow steps that need to be executed before running the **Distribute to Track** step, along with their respective reasons, are listed in the table below:
| Prerequisite Workflow Step | Description |
|------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
| [**Publish to Google Play**](/publish-integrations/android-publish-integrations/publish-to-google-play) | The app must be published to Google Play before checking the status of the app version in the Google Play Console. |
:::warning
If you have previously submitted this app version to the Google Play Console, you do not need to add the **Publish to Google Play** step.
:::
## Input Variables
Following input configurations are required for the **Distribute to Track** step.
| Variable Name | Description | Status |
| -------------------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --------- |
| `$AC_STACK_TYPE` | The `Track type for submit` specifies the [distribution channel](https://developers.google.com/android-publisher/tracks) for submitting your app for testing or production. Options are dynamic and retrieved from the Google Play Console. They may vary for each app. Options: `Internal`, `Alpha`, `Beta`, `TEST-TRACK`, `Production`. Default: `Alpha`. | Optional |
| `$AC_RELEASE_STATUS` | The `Play Store App Status` refers to the stage of the app's [publication process](https://support.google.com/googleplay/android-developer/answer/9859751?hl=en#zippy=%2Capp-status) on the Play Store. Options: `completed`, `partial`, `draft`. | Optional |
| `$AC_AUTO_SEND_PLAYSTORE_REVIEW` | The `Auto Send for Review` where you select whether your changes should automatically go for review on the Google Play Console. Options: `Send for Review Automatically but Rescue Errors`, `Don't Send for Review Automatically but Rescue Errors`, `Always Send for Review Automatically`, `Never Send for Review Automatically`. | Optional |
| `$AC_RELEASE_NOTES` | Provides release notes for the submission to Google Play. Use the `$AC_RELEASE_NOTES` variable to include the current release notes for the app version. Check or edit your app version's release notes in Binary Information. | Optional |
For detailed information about **Auto Send for Review** setting, please refer to the [Auto Send for Review](/publish-to-stores-module/publish-information/google-play-information#auto-send-for-review) documentation.
## Output Variables
The **Distribute to Track** publish step in Appcircle provides a custom UI that allows users to:
- Observe Google Play Information and edit Release Notes on default language or localized.
- See the Track Name and status which defines the Google Play track where the app is being deployed (e.g., `alpha` status: `in progress` ).
- Control the percentage of users receiving the update initially. A slider is available to adjust the rollout percentage (e.g., 10%).
:::info
Rollout Percentage slider is only available for `partial` Play Store app Status.
:::
:::tip
You can see the Play Store App Status for your tracks on Google Play Console by checking the **Publishing overview** section.
:::
---
## Get Approval From Google Play
The **Get Approval From Google Play** step ensures that your app release is approved by checking its status on the [Google Play Console](https://play.google.com/console). This allows you to monitor the progress of your submission and take any necessary actions to address any issues or concerns that may arise during the review process.
## Prerequisites
The Publish flow steps that need to be executed before running the **Get Approval via Email** step, along with their respective reasons, are listed in the table below:
| Prerequisite Workflow Step | Description |
|------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
| [**Publish to Google Play**](/publish-integrations/android-publish-integrations/publish-to-google-play) | The app must be published to Google Play before checking the status of the app version in the Google Play Console. |
:::warning
If you have previously submitted this app version to the Google Play Console, you do not need to add the **Publish to Google Play** step.
:::
You also need to have a Google Service Account and its key as a JSON file. Please refer to the following document for more information about service accounts:
Adding Google Play Service Accounts
After completing the integration with Google Play Services, go to [Publishing Settings](/publish-to-stores-module/publish-settings). In the [`Store Credential`](/publish-to-stores-module/publish-settings#store-credentials) section, select the Google Play Store API Key you uploaded, from the drop-down list.
:::info
If you are using [Publish Variables](/publish-to-stores-module/publish-settings#publish-variables), you should select them in the [Publishing Settings](/publish-to-stores-module/publish-settings) window.
:::
## Input Variables
The parameters required for this step to work as expected are listed below:
| Variable Name | Description | Status |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------- |
| `$AC_TRACK_TO_CHECK` | Select a release track to check the app's status. It is recommended to choose the track to which you have sent the app in the previous steps. Options: `alpha`, `beta`, `production`, and `internal`. | Optional |
| `$AC_ACCEPTED_STATUSES` | Customize the statuses to be accepted as passed by using commas. You can use statuses such as `completed`, `inProgress`, `draft`, `halted`. | Optional |
:::tip
Please follow the document to get information about the [Release Lifecycle](https://developers.google.com/assistant/console/releases#lifecycle) on Google Play.
:::
## Output Variables
The **Get Approval from Google Play** step does not produce any output variables. However, the step will succeed or fail, based on whether your application is in the correct status according to the [inputs](#input-variables) you provide.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-googleplay-status-check.git
---
## Android Integrations Overview
Appcircle's Android Integrations facilitate the distribution of your Android applications to major app stores with minimal effort.
To use the Android Integration, click on the **Android Publish** button on the left in the Publish module.
Click on **Add New** to create a new publish profile, **Open** details, and click on **Publish Flow**.
In **Publish Flow**, the default steps will appear. You can add or delete steps from your flow using the **Manage Flow** button.
Click on the **Save** button if you make any changes to your flow steps, or use the **Back** button without any change.
You can find Android specific steps in the Publish Flow under the headings below. For common steps, please refer to [this document](/publish-integrations/common-publish-integrations/).
## [Publish to Google Play](/publish-integrations/android-publish-integrations/publish-to-google-play)
- Quickly send APK and AAB binaries to Google Play.
- Initial setup requires an app listing and uploaded binary with a keystore.
- Effortlessly manage and deploy app profiles.
## [Publish to Huawei AppGallery](/publish-integrations/android-publish-integrations/publish-to-huawei-appgallery)
- Quickly send APK and AAB binaries to the AppGallery.
- Ensure your app is listed in Huawei AppGallery Connect with the correct keystore.
- Handle your app's keystore files and profile details in one place.
## [App Information from Google Play](/publish-integrations/android-publish-integrations/app-information-from-google-play)
- Enables you to monitor the current status of your app releases directly from the Google Play Console.
- Keeps you informed about any updates or issues with your app.
- Automates publish flow integration.
## [Get Approval From Google Play](/publish-integrations/android-publish-integrations/get-approval-from-google-play)
- Identifies potential issues early in the release process, allowing for timely resolution.
- Ensures your app release meets all necessary requirements and obtains approval from Google Play.
- Automatically verifies the status of your app, reducing the need for manual monitoring.
## [Distribute to Track](/publish-integrations/android-publish-integrations/distribute-to-track)
- Allows you to seamlessly release your apps to different testing or production tracks.
- This functionality ensures that new versions are rolled out in a controlled manner, enabling better testing, feedback collection, and staged releases.
- By leveraging different tracks, developers can ensure better app stability, collect valuable user feedback, and optimize the rollout process before reaching a wider audience.
## [Update Metadata on Google Play Console](/publish-integrations/android-publish-integrations/update-metadata-on-google-play)
- Automatically updates your app’s metadata and screenshots on the Google Play Console as part of your release pipeline.
- Ensures consistency across app listings by syncing the latest metadata and visual assets.
- Saves time and minimizes human error by eliminating the need for manual metadata updates.
Appcircle's integration tools are designed to simplify and automate the publishing process, allowing you to focus on developing great apps while we handle the distribution.
---
## Publish to Google Play
Appcircle supports sending APK and AAB binaries to [Google Play](https://play.google.com) through the Publish module.
Google Play no longer supports APK submission; however, Appcircle retains the APK submission feature for exceptional cases. For more details about APK submission, please refer to this document:
> [Google Play requires new apps to be published with the Android App Bundle starting August 2021.](https://android-developers.googleblog.com/2021/06/the-future-of-android-app-bundles-is.html)
## Prerequisites
Before uploading a binary to the store, please make sure that an application listing is created in Google Play and the initial binary is manually uploaded with the same keystore and the application ID (package name). Otherwise, the store upload process will fail. This is a known limitation of Google Play that is in place for security purposes.
You also need to have a Google Service Account and its key as a JSON file. Please refer to the following document for more information about service accounts:
Adding Google Play Service Accounts
After completing the integration with Google Play Services, go to [Publishing Settings](/publish-to-stores-module/publish-settings). In the [`Store Credential`](/publish-to-stores-module/publish-settings#store-credentials) section, select the Google Play Store API Key you uploaded, from the drop-down list.
If you are using [Publish Variables](/publish-to-stores-module/publish-settings#publish-variables), you should select them in the [Publishing Settings](/publish-to-stores-module/publish-settings) window.
## Input Variables
The parameters required for this step to work as expected are listed below:
| Variable Name | Description | Status |
| -------------------- | ---------------------------------------------------------------------------------------------------------------- | --------- |
| `$AC_STACK_TYPE` | The `Track type for submit` specifies the [distribution channel](https://developers.google.com/android-publisher/tracks) for submitting your app for testing or production. Options: `Internal`, `Alpha`, `Beta`, `Production`. Default: `Alpha`. | Optional |
| `$AC_RELEASE_STATUS` | The `Play Store App Status` refers to the stage of the app's [publication process](https://support.google.com/googleplay/android-developer/answer/9859751?hl=en#zippy=%2Capp-status) on the Play Store. Options: `completed`, `draft`. | Optional |
| `$AC_AUTO_SEND_PLAYSTORE_REVIEW` | The `Auto Send for Review` where you select whether your changes should automatically go for review on the Google Play Console. Options: `Send for Review Automatically but Rescue Errors`, `Don't Send for Review Automatically but Rescue Errors`, `Always Send for Review Automatically`, `Never Send for Review Automatically`.
| `$AC_RELEASE_NOTES` | Provides release notes for the submission to Google Play. Use the `$AC_RELEASE_NOTES` variable to include the current release notes for the app version. Check or edit your app version's release notes in Binary Information. | Optional |
For detailed information about **Auto Send for Review** setting, please refer to the [Auto Send for Review](/publish-to-stores-module/publish-information/google-play-information#auto-send-for-review) documentation.
:::tip
You can find the release notes in the [Google Play Console](https://play.google.com/console) by following these steps:
1. Select the app from the app list on the `Home` page.
2. From the menu on the left, select the track under `Release` (for example, `Closed testing`).
3. Click on `Manage track` next to your track under `Active tracks`.
4. Find your version under `Releases` and click `Manage release`.
5. The release notes you submitted will appear under the `Release notes`.
For track type differences and best practices, please refer to the following official Google documentation:
- [Understanding different testing tracks and their requirements](https://support.google.com/googleplay/android-developer/answer/14151465)
- [Differences between internal, closed, and open testing](https://support.google.com/googleplay/android-developer/answer/9845334)
:::
:::info App Status usage
**Draft**
Use when the app setup is incomplete or when you want to upload binaries and update metadata **without submitting the app for review**.
**Completed**
Use when all required information is finalized and the app is **ready to be submitted for review or release**.
:::
## Output Variables
**Publish to Google Play** step does not produce any output. However, you can check the logs to see whether your app has successfully accessed Google Play.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-send-to-playstore
## FAQ
### `changesNotSentForReview` Errors
**Sample Error:**
```
Changes are sent for review automatically. The query parameter changesNotSentForReview must not be set.
```
**Q: What does `changesNotSentForReview` mean?**
- According to Google Play API docs, it indicates that changes in this edit **will not be reviewed** until they are explicitly sent for review from the Google Play Console UI.
- These changes are **queued** with any other pending changes not yet sent for review.
**Q: When should I use `changesNotSentForReview: true`?**
* Only use `true` if your app/track is in a **rejected** state.
* Otherwise, leave it **unset or false**, so the changes can be sent for review automatically.
**Q: What if I get a 400 error related to draft status?**
* Enable publishing to `draft`
* Or promote the `draft` build to a testing track (Alpha/Beta/Internal)
* Follow Play Console steps: fill questionnaires, upload screenshots, get approval, then retry publishing.
---
## Publish to Huawei AppGallery
Appcircle supports sending [APK](https://developer.huawei.com/consumer/en/doc/app/agc-help-releaseapkrpk-0000001106463276) and [AAB](https://developer.huawei.com/consumer/en/doc/app/agc-help-releasebundle-0000001100316672) binaries to [Huawei AppGallery](https://appgallery.huawei.com/) through the Publish module.
### Prerequisites
Before uploading a binary to the store, please make sure that an application listing is created in Huawei AppGallery Connect and the initial binary is manually uploaded with the same keystore and the application ID. Otherwise, the store upload process will fail.
You also need to have an AppGallery Connect API and its key as a JSON file. Please refer to the following document for more information on creating your API key.
Adding Huawei AppGallery API Key
After completing the integration with Huawei AppGallery API Key, go to [Publishing Settings](/publish-to-stores-module/publish-settings). In the [`Store Credential`](/publish-to-stores-module/publish-settings#store-credentials) section, select the Huawei AppGallery API Key you uploaded, from the drop-down list.
If you are using [Publish Variables](/publish-to-stores-module/publish-settings#publish-variables), you should select them in the [Publishing Settings](/publish-to-stores-module/publish-settings) window.
## Input Variables
The parameters required for this step to work as expected are listed below:
| Variable Name | Description | Status |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| `$AC_HUAWEI_APP_ID` | It is required to publish the app to Huawei AppGallery. You can find the App ID on the [Huawei Developer Console](https://developer.huawei.com/consumer/en/console) by navigating to `App Services` > `AppGallery Connect` > `My Apps` > `your app` > `App Information`. | Required |
| `$AC_RELEASE_NOTES` | Provides release notes for the submission to Huawei AppGallery. | Optional |
## Output Variables
**Publish to Huawei AppGallery** step does not produce any output. However, you can check the logs to see whether your app has successfully accessed Huawei AppGallery.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-send-to-appgallery.git
## FAQ
### App is not visible on Huawei AppGallery after a successful publish
**Question**:
Publishing to Huawei AppGallery completes successfully on Appcircle, but the app does not appear on the Huawei Store. The same build is visible on Google Play without any issues. Why does this happen?
**Answer**:
This issue can occur if there is a previous rollout on Huawei AppGallery that has not been completed or canceled.
We observed that when an incomplete or ongoing rollout exists, Huawei AppGallery may block the new upload even though Appcircle reports the publish step as successful.
**Solution**:
- Cancel the previous incomplete rollout on Huawei AppGallery.
- After canceling the old rollout, you will see that the app you previously submitted has been successfully installed.
### Cannot obtain upload URL (403)
**Error**
```
Cannot obtain upload URL, please check API Token / Permissions (status code: 403)
```
**Possible Causes & Solutions**
If you encounter this error during the **Send to Huawei AppGallery** step in **Appcircle**, please verify the following points:
#### 1. Check API Client Permissions
Ensure that the **AppGallery API Client** has **at least the following permissions enabled**:
- **Development**
- **Operations**
Missing or insufficient permissions will result in a `403 Forbidden` response when requesting the upload URL.
#### 2. Verify the API Key Used in Appcircle
Make sure that the **correct AppGallery API Key** is configured in Appcircle.
**Recommendation:**
Delete the existing AppGallery API Key in Appcircle and re-add the intended one to eliminate any misconfiguration.
:::info
Unlike Google Play Console, **Huawei AppGallery** allows downloading the same API Client JSON file multiple times. Re-downloading the JSON does not invalidate previous downloads.
:::
#### 3. Confirm Huawei App ID Configuration
Ensure that the **Huawei App ID** is correctly entered in the **Send to Huawei AppGallery** step configuration in Appcircle.
An incorrect or missing App ID will prevent Appcircle from obtaining the upload URL.
#### 4. Restart the Workflow
After making any changes (API Key, permissions, App ID):
* Use the **Restart Flow** button in Appcircle.
* Then rerun the **Send to Huawei AppGallery** step.
This ensures that all recent configuration updates are properly applied.
---
If the problem persists after completing all steps, please contact support with your pipeline details and error logs.
---
## Update Metadata on Google Play Console
This step uploads all edited metadata information from the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information) page to the corresponding sections on Google Play Console.
### Prerequisites
This step operates independently; it does not require any specific prior steps. You can incorporate it anywhere in the Publish Flow according to your workflow.
### Input Variables
Below are the parameters necessary for this step's operation, along with their descriptions.
| Input Variables | Description |
|------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Uploads screenshots while sending METADATA** | This value is `true` by default and includes screen shots uploaded in [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#ios-metadata-information) during the upload process. If `false`, screen shots will not be uploaded. |
| **Update Metadata fields** | This value is `true` by default and ensures that the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#ios-metadata-information) to be updated is uploaded. If `false`, the entered metadata information will not be uploaded. |
| **Synchronize Image Uploads with the Google Play Console** | If enabled, only new images will be uploaded. Previously uploaded and unchanged images will be skipped. |
| **Auto Send for Review** | Automatically submits the updated metadata and app version for review on the Google Play Console. |
:::warning Mandatory Google Play Metadata Fields
On **Google Play Console**, certain metadata fields are **mandatory** and must be completed before you can **save** the metadata details in Appcircle.
The following fields are required by Google Play:
- **App Name**
- **Short Description**
- **Full Description**
- **App Icon**
- **Feature Graphic**
- **Phone Screenshots**
If any of these required fields are missing, Google Play Console will not allow the metadata to be saved or updated. Make sure all mandatory fields are properly filled and uploaded before running the **Update Metadata on Google Play Console** publish step.
:::
---
## Custom Script from Git
You can use the **Custom Script from Git** steps to execute scripts stored in a Git repository within your [Publish flow](/publish-to-stores-module/publish-flow). Instead of writing scripts directly in Appcircle, this step clones your repository and runs the specified script file, enabling centralized script management and version control. These scripts will run on the runner, giving you access to all the capabilities of the publish environment.
The guidelines detailed in the **Custom Script from Git** documentation for [Build Workflow](/workflows) also apply to the Custom Script in [Publish](/publish-to-stores-module). Therefore, this document will not repeat those details. For comprehensive information about the **Custom Script from Git** step, please visit the link below:
Custom Script from Git Step in Build Workflow
---
## Custom Script (Publish Flow)
# Custom Script
You can use the **Custom Script** steps to add extra functionalities in your [Publish flow](/publish-to-stores-module/publish-flow). Appcircle will execute the commands specified in your custom scripts, allowing you to perform custom actions. These scripts will run on the runner, giving you access to all the capabilities of the publish environment.
The guidelines detailed in the **Custom Script** documentation for [Build Workflow](/workflows) also apply to the Custom Script in [Publish](/publish-to-stores-module). Therefore, this document will not repeat those details. For comprehensive information about the Custom Script step, please visit the link below:
Custom Script Step in Build Workflow
## FAQ
### How can I print the status of publish steps with detailed information?
If you want to track or share the status of your publish steps during a publish flow, you can use the following environment variable:
- **`$AC_PUBLISH_STEPS_STATUS`**: Displays detailed information about each executed publish step.
:::caution
Please ensure that when writing scripts, you only include conditions for existing statuses, considering the possibility of new statuses being added in the future. For example, while supporting a condition like `if step_status == 'Success'`, avoid using a generic negation such as `if step_status != 'Success'` for handling other statuses.
:::
However, the output of `$AC_PUBLISH_STEPS_STATUS` is in raw JSON format, which may not be easy to read directly. To make it more readable, you can use the following Ruby script to format and print the information in a user-friendly way:
```ruby
require 'json'
# Read the environment variable
json_data = ENV['AC_PUBLISH_STEPS_STATUS']
begin
# Parse and beautify the JSON
parsed_data = JSON.parse(json_data)
pretty_json = JSON.pretty_generate(parsed_data)
# Output the formatted JSON
puts "AC_PUBLISH_STEPS_STATUS:"
puts pretty_json
rescue JSON::ParserError => e
puts "Failed to parse JSON: #{e.message}"
end
```
:::info
The script above is written in Ruby. To execute it, select `Ruby` as the `Execute with` option in the **Custom Script** step.
:::
If you add a **Custom Script** step in your publish flow, the script will generate an output similar to this:
```json
AC_PUBLISH_STEPS_STATUS:
[
{
"StepName": "Get Approvel via Email",
"StepId": "qwertyu-iopa-sdfg-hjkl-zxcvbnm",
"StepStatus": "NotStarted",
"Duration": 0.133102,
"StartDate": "2024-12-30T16:48:47.919386Z",
"FinishDate": "2024-12-30T16:48:48.052488Z"
},
{
"StepName": "Distribute to Track",
"StepId": "qwertyu-iopa-sdfg-hjkl-zxcvbnn",
"StepStatus": "Success",
"Duration": 1.90708,
"StartDate": "2024-12-30T16:48:48.186532Z",
"FinishDate": "2024-12-30T16:48:50.093612Z"
}
]
```
:::info
Steps that are disabled in the publish flow will not appear in the above output. The `NotStarted` status is assigned to enabled steps that were not executed when running only specific steps instead of the entire publish flow.
:::
Simply include this script in your publish flow to better understand and monitor the status of your publish steps.
---
## Get Approval via Email
The **Get Approval via Email** step allows you to get approval from the email addresses entered as input in the step before moving on to the next steps in Publish.
Based on your business requirements, you can designate certain email addresses to require approval, specify others as optional approvers, or set a minimum number of approvals needed from the provided email addresses.
If some optional users reject the request but there is still a chance to achieve the minimum approval count, the step will remain in `Waiting` status, awaiting responses from other users. For instance, if you set the minimum approval count to 3, and out of 10 users, only one is required, the step can still succeed. Even if 7 optional users reject, approval can still be obtained from the remaining 3 users. However, if 8 optional users reject, the step will fail, as it will no longer be possible to meet the minimum requirement of 3 approvals.
:::info
Once a user makes a decision, it cannot be changed unless the step is restarted, even if the user sees the "Thank you" page. The step must be restarted to allow the user to make a new decision.
Upon restarting or initiating the step, it resets all answers to `Waiting`. Users must then provide their answers again and will receive new approval emails.
:::
:::tip Get Approval via Email
The Get Approval via Email step can be used for different purposes. Since this step takes two different parameters, one Required and one Optional, the usage varies.
For example, imagine you need approval from at least two people to keep the flow going in your company or team. Additionally, let's assume that two more people can act as backups for the necessary approvers. We have four people in total: two necessary and two optional. If you set the minimum approval count to three, one of the optional approvers must approve alongside the two necessary approvers. Once the necessary approvers have given their approval, it will be sufficient for one of the optional approvers to approve. The publish flow will continue as the majority is provided.
:::
### Email Template
With the Email Approval step provided by the Appcircle Publish module, release processes are managed in a structured and controlled way. The email includes all key information, such as binary details, release notes, and other relevant data, so users can review the release context without needing to search within the Appcircle interface.
To proceed with the approval, users can click the link in the email, which opens the binary details window in Appcircle. From this view, they can examine version information, build details, and commit history before making a decision by selecting **Approve** or **Reject**.
:::info Rejection
Users who decide to reject the binary, must provide an explanation. This explanation message will be displayed on the Publish Flow window under the desicion of that user.
:::
### Prerequisites
There are no required steps that must precede the **Get Approval via Email** step. However, please note that any steps executed before the **Get Approval via Email** step in the [Publish flow](/publish-to-stores-module/publish-flow) will not be impacted by the approval process. The approval logic will only affect the steps that follow the **Get Approval via Email** step.
### Input Variables
The parameters required for this step to work as expected are listed below:
| Variable Name | Description | Status |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_APPROVAL_EMAILS` | The **All Required Approval Emails** specify the required email addresses, separated by commas, to which special approve and reject links will be sent. All email addresses in this field must be approved for this step to be successful. If one of the required users rejects it, the step will fail. The count of emails cannot be less than the **Minimum Required Approval Count**. | Optional |
| `$AC_OPTIONAL_APPROVAL_EMAILS` | The **Optional Required Approval Emails** specify optional email addresses, separated by commas, to which special approve and reject links will be sent. Optional approval emails may need to be approved if the **Minimum Required Approval Count** is lower than the count of **All Required Approval Emails**. | Optional |
| `$AC_MINIMUM_APPROVAL_COUNT` | The **Minimum Required Approval Count** specify the minimum number of required email approvals. The total of required and optional email approvals must be equal to or greater than this number. The step will not succeed unless the minimum number of approvals is fulfilled. | Required |
:::warning
If the **Minimum Required Approval Count** cannot be achieved, the step will fail. For example, if the **Minimum Required Approval Count** is set to 3 and there are a total of 3 users, if one of them rejects, the minimum count cannot be met because only 2 users with approval rights remain.
:::
### Output Variables
**Get Approval via Email** step does not produce any output, but the success or failure of the step depends on the approvals or rejections received from the sent emails. This outcome affects the subsequent steps in the [Publish flow](/publish-to-stores-module/publish-flow).
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-email-send.git
---
## Common Integrations Overview
Appcircle's Common Integrations facilitate the distribution of your iOS and Android applications to major app stores with minimal effort.
## [Custom Script](/publish-integrations/common-publish-integrations/custom-script)
- Allows you to tailor the publish process to address your specific needs by executing custom commands.
- Automates repetitive tasks, reducing the amount of manual work required.
- Enables the creation of custom Publish flows and actions not available in the default steps.
## [Custom Script from Git](/publish-integrations/common-publish-integrations/custom-script-from-git)
- Allows you to execute scripts directly from a Git repository, enabling centralized script management across multiple publish flows.
- Eliminates the need to update flows when scripts change - simply update the script in Git and all flows automatically use the latest version.
- Provides version control and change tracking for your scripts through Git history, making it easy to review and roll back changes.
- Enables script reusability across different projects and workflows without duplication.
- Automates repetitive tasks while maintaining consistency and reducing manual configuration errors.
## [Get Approval via Email](/publish-integrations/common-publish-integrations/get-approval-via-email)
- Request and track approvals easily via email.
- Customize approval Publish flows with minimum counts and optional/required approvers.
- Monitor approval status in real-time.
- Maintain a clear record of approval actions.
## [Publish to Microsoft Intune](/publish-integrations/common-publish-integrations/send-to-microsoft-intune)
Everything you need to know about submitting your app to the Microsoft Intune can be found here. We cover the necessary preparations, API key configuration, and submission details.
## [Update Metadata on Microsoft Intune](/publish-integrations/common-publish-integrations/update-metadata-on-microsoft-intune)
Learn how to update your app's metadata on Microsoft Intune to improve visibility.
## [Send to Enterprise App Store](/publish-integrations/common-publish-integrations/send-to-enterprise-app-store)
Everything you need to know about sending your app to the Appcircle's Enterprise App Store can be found here. We cover the necessary preparations, and submission details.
Appcircle's integration tools are designed to simplify and automate the publishing process, allowing you to focus on developing great apps while we handle the distribution.
## [Send to Testing Distribution](/publish-integrations/common-publish-integrations/send-to-testing-distribution)
With Appcircle's Publish module, you can submit your application to external stores such as App Store, Google Play, Huawei AppGallery or Microsoft Intune, as well as to Appcircle's Testing Distribution module.
Testing Distribution module allows you to distribute your application without the need for any external tools.
## [Metadata Approval via Email](/publish-integrations/common-publish-integrations/metadata-approval)
The Metadata Approval via Email step is used to get email-based approval before publishing your app's metadata. This ensures that designated users can review and either approve or reject the App Store, Google Play, Microsoft Intune and Huawei AppGallary metadata before proceeding with the publishing step.
## [Send Email](/publish-integrations/common-publish-integrations/send-email)
The **Send Email** step allows you to send customized email notifications during your Appcircle Publish Flow for both iOS and Android builds. This can be used to alert stakeholders, notify of publish statuses, or provide deployment-related information.
---
## Metadata Approval via Email
The Metadata Approval via Email step is used to get email-based approval before publishing your app's metadata. This ensures that designated users can review and either approve or reject the App Store, Google Play, Microsoft Intune and Huawei AppGallary metadata before proceeding with the publishing step.
This step is useful in team environments where metadata needs to be validated manually before release.
When this step runs in your workflow, Appcircle sends a unique approval email to the recipients defined in the step inputs. The email contains a secure link to a dedicated Metadata Approval Panel, which allows recipients to:
- View the metadata details
- Approve or reject the metadata
- Provide feedback in case of rejection
:::caution Metadata Approval Panel
Access to the Metadata Approval Panel is **exclusively** available via the link sent in the approval email; it is **not** accessible through the standard Publish module UI.
:::
### Prerequisites
This step is one of the dependent steps. The table below lists the dependent steps with their descriptions.
| Prerequisite Workflow Step | Description |
|-----------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Update Metadata on Microsoft Intune**](/publish-integrations/common-publish-integrations/update-metadata-on-microsoft-intune) | This step uploads all edited metadata information from the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#microsoft-intune-metadata-information) page to the corresponding sections on Microsoft Intune. Ensure the [**Microsoft Intune API Key**](/account/my-organization/security/credentials/adding-microsoft-intune-api-key) is added to Appcircle and selected. |
| [**Update Metadata on App Store Connect**](/publish-integrations/ios-publish-integrations/update-metadata-on-app-store-connect) | This step uploads all edited metadata information from the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#ios-metadata-information) page to the corresponding sections on App Store Connect. Ensure the [**App Store Connect API Key**](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key) is added to Appcircle and selected. |
| [**Update Metadata on Google Play Console**](/publish-integrations/android-publish-integrations/update-metadata-on-google-play) | This step uploads all edited metadata information from the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#ios-metadata-information) page to the corresponding sections on Google Play Console. Ensure the [**Google Play Service Account**](/account/my-organization/security/credentials/adding-google-play-service-account) is added to Appcircle and selected. |
:::caution Prerequisites
Please note that the **Metadata Approval via Email** step **must** be used before the steps listed in the table above.
Running **Metadata Approval via Email** step after your updated metadata has been applied in your developer accounts may **cause unexpected errors** in your publish flows.
:::
### Input Variables
The parameters required for this step to work as expected are listed below.
| Field | Description |
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| **All Required Approval Emails** | List of email addresses that **must** approve the metadata. If any of these reject or don't approve, the step fails. Example: `info@appcircle.io` |
| **Optional Emails to Approve** | Additional email addresses that can optionally approve. Their approvals contribute to the total approval count. Example: `support@appcircle.io, team@appcircle.io` |
| **Minimum Required Approval Count** | The minimum number of total approvals (required + optional) needed for the step to be considered successful. Example: `2` |
:::caution Minimum Approval Count
If the Minimum Required Approval Count cannot be achieved, the step will fail.
For example, if the Minimum Required Approval Count is set to 3 and there are a total of 3 users, all recipients will need to approve the metadata.
Please note that required approval email users take priority in this case, as all of them must approve—even if the minimum requirement is already met by optional users.
:::
## Approval or Rejection Process
### Approval
To approve a metadata, follow the steps below:
1. Emails are sent to the recipients with a private link to the approval panel.
2. Recipients click the link and are directed to the Metadata Approval Panel.
3. If the user is not logged in, they are redirected to the login screen first and then returned to the panel.
4. The user can approve the metadata by clicking the **Approve** button in the panel that opens.
:::caution Metadata Approval Panel
Please note that all of the data displayed in the metadata approval panel is **read‑only**. No values can be changed within this panel.
:::
:::info Successful Approval
**The step is marked as successful if:**
- All required email addresses approve the metadata.
- The minimum required approval count is satisfied.
:::
:::warning Lock/Unlock Rules for Metadata Update
Please note that in order to make any updates within [**Metadata Details**](/publish-to-stores-module/publish-information/meta-data-information), certain rules must be met. While the Publish Flow is running, Metadata Details are locked and no changes are permitted. Please pay close attention to the business rules outlined below.
**Metadata will be locked when:**
- the **Metadata Approval via Email** step starts, is in progress, or is completed
- the **[Update Metadata on App Store Connect](/publish-integrations/ios-publish-integrations/update-metadata-on-app-store-connect)/Google Play Console** step starts
**Metadata will be unlocked when:**
- the **Metadata Approval via Email** step completes with a status of `Failed` or `Stopped`
- the **[Update Metadata on App Store Connect](/publish-integrations/ios-publish-integrations/update-metadata-on-app-store-connect)/Google Play Console** step completes with a status of `Success`, `Failed`, or `Stopped`
- the Publish Flow completes
:::
### Rejection
When a user wants to reject a metadata, they can reject by clicking the **Reject** button on the metadata approval panel that opens.
**When a rejection occurs;**
- The rejecting user is asked to provide a **Rejection Message**.
- This message is included in the **step logs** for an easy review.
- The app version will also be tagged with `Metadata Rejected` in the Publish profile dashboard.
## Output Variables
**Metadata Approval via Email** step does not produce any output, but the success or failure of the step depends on the approvals or rejections received from the sent emails. This outcome affects the subsequent steps in the [Publish flow](/publish-to-stores-module/publish-flow).
---
## Send Email
The **Send Email** step allows you to send customized email notifications during your Appcircle Publish Flow for both iOS and Android builds. This can be used to alert stakeholders, notify of publish statuses, or provide deployment-related information.
## Configuration Options
To be able to send email in your publish flow, you need to configure the fields listed below. These settings define how the email is sent, including the SMTP server, sender details, recipients, and the email content. Make sure the credentials and connection details match your email service provider’s requirements.
| Field | Description |
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Mail Host** | Domain or IP address of the SMTP server (e.g., `smtp.gmail.com`). |
| **Mail Port** | Port number of the SMTP server. Common values: `465` (SSL) or `587` (TLS). |
| **SMTP Username** | Email address used for SMTP login. |
| **SMTP Password** | Password or app-specific password for the SMTP account. |
| **From** | Sender information in the format: `Name `. |
| **To** | Comma-separated list of recipient email addresses. |
| **Subject** | Subject of the email. Environment variables (e.g., `$AC_BUILD_NUMBER`) can be used. |
| **Use TLS** | Set to `true` to use TLS (if supported by the provider). |
| **Use SSL** | Set to `true` to use SSL (if supported by the provider). |
| **Use Authentication** | Set to `true` if authentication is required by the SMTP server. |
| **Email Provider Account**| Email provider configuration key (e.g., `gmail`). |
| **Email Content** | Body content of the email. Plain text or HTML. Environment variables can be used. |
:::tip Email Provider Account
Please note that this area is optional, if you are not sure about your provider, the default value (gmail) can be used.
:::
### Example Configuration (Gmail)
| Field | Value |
|-------------------------|-----------------------------------------------------------------------|
| **Mail Host** | `smtp.gmail.com` |
| **Mail Port** | `465` |
| **SMTP Username** | `youremail@gmail.com` |
| **SMTP Password** | App-specific password generated via Google account |
| **From** | `Your Name ` |
| **To** | `qa@example.com,pm@example.com` |
| **Subject** | `Build $AC_BUILD_NUMBER completed for $AC_PROJECT_NAME` |
| **Use TLS** | `true` |
| **Use SSL** | `true` |
| **Use Authentication** | `true` |
| **Email Provider Account** | `gmail` |
| **Email Content** | `Hello Team, the build $AC_BUILD_NUMBER for $AC_PROJECT_NAME is done.`|
## Using Environment Variables
You can dynamically populate subject and content using environment variables. They can also be used to securely fill your email settings.
### Creating Environment Variables
First, you need to define the environment variables. To do this, go to the Publish module and select Publish Variables. From there, you can start creating the variables for your email settings.
For more information, please refer to the [Publish Variables](/publish-to-stores-module/publish-variables) documentation.
### Selecting Environment Variables
After creating the environment variables, you will need to select this variable group from your profile settings.
You can now use the defined environment variables in your email settings, including the subject and content. For example:
```text
Subject:
$AC_EMAIL_TITLE
Email Content:
Hi team,
A new package for $AC_PROJECT_NAME has been successfully published.
Best,
Appcircle Team
```
---
## Send to Enterprise App Store
With Appcircle's Publish module, you can submit your application to external stores such as App Store, Google Play, Huawei AppGallery or Microsoft Intune, as well as to Appcircle's Enterprise App Store module.
Enterprise App Store offers a store structure that you can use and customise for internal application distribution. For detailed information, please see the [**Enterprise App Store document**](/enterprise-app-store).
### Prerequisites
There is no prerequisite required for this step to work. You can use this step anywhere you want in the Flow.
:::caution Send to Enterprise App Store
If the binary you want to send is available in the Enterprise App Store profile, the step will fail due to version conflict.
Make sure that you are not sending a version that exists in the Enterprise App Store profile.
:::
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-send-to-enterprise-store
---
## Send to Microsoft Intune
This step enables you to submit your line of business apps to the [Microsoft Intune](https://learn.microsoft.com/en-us/mem/intune/fundamentals/what-is-intune).
### Prerequisites
Below are the prerequisite steps necessary for this operation, accompanied by their descriptions.
### Providing Microsoft Intune API Credentials for Accessing Intune
To send an app from Appcircle to Microsoft Intune, you need to register an application with the Microsoft Identity Platform and provide this application's credentials.
Adding Microsoft Intune API Credentials
After completing the integration with Microsoft Intune, go to [Publishing Settings](/publish-to-stores-module/publish-settings). In the [Store Credential](/publish-to-stores-module/publish-settings#store-credentials) section, select the Microsoft Intune Credential you integrated, from the drop-down list. Then, click on the **Save** button.
### Input Variables
## iOS
Below are the parameters necessary for this step's operation for iOS, along with their descriptions.
| Variable Name | Description | Status |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_INTUNE_PUBLISHER_NAME` | This parameter is used to specify the publisher name for the selected version. By default, it takes the name of your organization or the email address of the user initiating the step. | Optional |
| `$AC_INTUNE_TARGETED_PLATFORM` | The `Applicable Device Type` specifies the the device types that can install this app. Options: `Both`, `iPad`, `iPhone and iPod`. Default: `Both`. | Optional |
| `$AC_INTUNE_MIN_OS_VERSION` | The `Minimum Operating System` specifies the earliest operating system version on which the app can be installed. If you assign the app to a device with an earlier operating system, it will not be installed. Default: `iOS 8.0`. | Optional |
:::warning
If you choose to create a new application in Microsoft Intune while marking the app version as release candidate and execute this step before updating the [metadata information](https://docs.appcircle.io/publish-to-stores-module/publish-information/meta-data-information#microsoft-intune-metadata-information), these values will be assigned to the application being created by default.
:::
---
## Android
Below are the parameters necessary for this step's operation for Android, along with their descriptions.
| Variable Name | Description | Status |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_INTUNE_PUBLISHER_NAME` | This parameter is used to specify the publisher name for the selected version. By default, it takes the name of your organization or the email address of the user initiating the step. | Optional |
| `$AC_INTUNE_TARGETED_PLATFORM` | The `Targeted Platform` specifies the the device types that can install this app. Options: `Android device administrator`, `Android (AOSP)`. Default: `Android (AOSP)`. | Optional |
| `$AC_INTUNE_MIN_OS_VERSION` | The `Minimum Operating System` specifies the earliest operating system version on which the app can be installed. If you assign the app to a device with an earlier operating system, it will not be installed. Default: `Android 4.0 (Ice Cream Sandwich)`. | Optional |
:::danger
If you choose to create a new application in Microsoft Intune while marking the app version as release candidate and execute this step before updating the [metadata information](https://docs.appcircle.io/publish-to-stores-module/publish-information/meta-data-information#microsoft-intune-metadata-information), these values will be assigned to the application being created by default.
- The `Targeted Platform` is set when the application is first created in Microsoft Intune and cannot be changed afterwards. Ensure that you select the correct platform before executing this step.
:::
:::danger
Microsoft Intune does not support the distribution of Android App Bundle (AAB) files. If your release candidate version is an AAB file, this step will fail.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-send-to-intune-ios
https://github.com/appcircleio/appcircle-publish-send-to-intune-android
---
## Send to Testing Distribution
With Appcircle's Publish module, you can submit your application to external stores such as App Store, Google Play, Huawei AppGallery or Microsoft Intune, as well as to Appcircle's Testing Distribution module.
Testing Distribution module allows you to distribute your application without the need for any external tools. For detailed information, please see the [**Testing Distribution Documentation**](/testing-distribution).
### Prerequisites
There is no prerequisite required for this step to work. You can use this step anywhere you want in the Flow.
:::caution Selecting the Testing Distribution Profile
Make sure to select the required Testing Distribution Profile that the Publish Step will use. Otherwise, you’ll encounter an error when starting the Publish Flow.
:::
---
## Update Metadata on Microsoft Intune
This step uploads all edited metadata information from the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#microsoft-intune-metadata-information) page to the corresponding sections on Microsoft Intune.
### Prerequisites
This step operates independently; it does not require any specific prior steps. You can incorporate it anywhere in the Publish Flow according to your workflow.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-update-metadata-intune
---
## Publish Integrations
# Publish Integrations Overview
Publish Integrations in Appcircle provide a seamless connection between your application builds and the respective app stores for Android and iOS. This powerful feature automates the distribution process, making it easier to manage releases and updates.
## [Common Integrations](/publish-integrations/common-publish-integrations)
Appcircle's Common Integrations facilitate the distribution of your iOS and Android applications to major app stores with minimal effort.
## [iOS Integrations](/publish-integrations/ios-publish-integrations)
Here, you'll find comprehensive guides on the various steps involved in preparing and distributing your iOS app through Apple's ecosystem, including both the App Store and TestFlight.
## [Android Integrations](/publish-integrations/android-publish-integrations)
Appcircle's Android Integrations facilitate the distribution of your Android applications to major app stores such as Google Play and Huawei AppGallery with minimal effort.
---
## Add for Review on App Store
Appcircle Publish Module isolates the user to a great extent in the App Store Connect interface with its steps. This allows you to manage the publishing process from a single location.. With the Add for Review on App Store step, you can send your application version in TestFlight directly for review.
:::caution Add for Review on App Store
When this step is executed, Appcircle will directly submit the relevant version for review.
For this reason, if there is an error in your [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information) or [**App Information**](/publish-to-stores-module/publish-information/app-information) details, the step will fail.
:::
### Prerequisites
In order for this step to work, the following steps must be present before this step.
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Send to TestFlight**](/publish-integrations/ios-publish-integrations/sent-to-testflight) | This step allows you to submit your application to TestFlight. |
:::danger Prerequisites
When this step runs, Appcircle will first search for the relevant version match on **TestFlight**. Once the relevant version is found, the binary will be sent directly for review.
For this reason, the binary file must be present on **TestFlight**.
:::
### Input Variables
Below are the parameters necessary for this step's operation, along with their descriptions.
| Variable Name | Description | Status |
|-------------------------------|-------------------------------------|------------------|
| `$AC_XCODE_LIST_DIR` | Specifies the Xcode folder list directory. Current Xcode folder structure examples: `/Applications/Xcode/14.3/Xcode` or `/Applications/Xcode/15.0/Xcode`. | Optional |
| `$AC_XCODE_VERSION` | Specifies the Xcode version. | Required |
---
## App Information from App Store
This step enables you to view app version information from both [**TestFlight**](https://developer.apple.com/testflight/) and the [**App Store**](https://developer.apple.com/documentation/appstoreconnectapi/app_store) on a single screen, including the version you intend to submit. Upon running this step, it displays the latest version information from TestFlight and the App Store as follows:
Below are brief descriptions of the information provided on the App Information screen.
| Information | Description | Additional Info |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| **Bundle ID** | The `bundleIds` resource represents the app's unique identifier that you can register, modify, and delete. | [Apple's documentation](https://developer.apple.com/documentation/appstoreconnectapi/bundle_ids) |
| **App Icon** | Specifies the icon that will appear for the app on the selected platform. | [Apple App Icon documentation](https://developer.apple.com/design/human-interface-guidelines/app-icons) |
| **App Name** | The display name of the application on the selected platform. | |
| **Version** | The current available app versions. For example, `1.0.5`. | |
| **Build Number** | Version code information of your application. For example, `1.0.5(1)`. | |
| **Uploaded Date** | Date the application was first uploaded. The **Release Candidate** version is based on the date it was uploaded to the **Publish module**. | |
| **Expire Date** | The expiration date of the application version in TestFlight and the App Store. The **Release Candidate** version does not have an expiration date. | |
| **Release Type** | Indicates the release type of your application. For example, if you have an application released to the market, you will see the type as **After Approval**. | |
| **Processing State** | This indicates the status of your application; it will appear as **`Valid`** when there are no issues. For instance, if your application has expired in the TestFlight environment, the state will be **`Expire`**. If the application is rejected, the state will be **`Reject`**. | |
:::caution
Make sure the [**App Store Connect API Key**](https://docs.appcircle.io/account/adding-an-app-store-connect-api-key#linking-appcircle-with-app-store-connect) is added to Appcircle and selected in [**Publish Settings**](https://docs.appcircle.io/publish-to-stores-module/#publish-settings).
:::
:::tip App Information from App Store
Since this step compares three different versions, it can be used in various scenarios.
For example, your company's release management may involve a specific approval mechanism. When a step is completed, you need to get approval and continue the process according to the next approval. At this point, you can present version information to the people responsible for Publish with this step, and then you can continue the process by getting approval from the relevant people with the [**Get Approval via Email step**](/publish-integrations/common-publish-integrations/get-approval-via-email). In this way, your entire Publish team will be able to see which version is the latest version in your production and beta test environments and compare it with your [**Release Candidate**](/publish-to-stores-module/publish-information/marking-release-candidates) version.
Similarly, the authorized person in your approval mechanism will provide approval to start your release process based on this comparison.
:::
### Prerequisites
This step does not depend on any other steps to function. However, it is advisable to use it as the initial step in your **Publish Flow**.
### Input Variables
This step does not need any input variable.
:::danger
This step requires only the [**App Store Connect API Key**](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/send-to-app-store#adding-an-app-store-connect-api-key-recommended-method) credentials. Ensure this API key is configured in Appcircle and selected for the appropriate flow.
:::
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-appstore-app-information
---
## Get Approval from TestFlight
This step allows you to check the status of your application after sending it to [**TestFlight**](https://developer.apple.com/testflight/). It is a **scheduled job** and periodically checks the status of the relevant version on TestFlight. Informs you of the version status in internal, external, or both test groups.
:::info
After this step, once the application is uploaded to **TestFlight**, it will successfully terminate or fail the step according to the selected status. There are four different options for this:
- **`One of the External or Internal`**
- **`Internal Only`**
- **`External Only`**
- **`Both`**
For example, if your application was submitted to the **`Internal`** test group in TestFlight and you have selected **`Internal or External`** status from the step, when your application is sent to the **`Internal`** test group, its status will be In Testing and the Appcircle step will be successful. The same situation applies to the other options. If you select **`Internal Only`** or **`External Only`** Only, it will be sufficient for the application to be **`In Testing`** in one of the two test groups. However, if you select **`Both`**, the step will be successful only after the **`In Testing`** requirement is met in both test groups.
:::
### Prerequisites
This step is one of the dependent steps. Below is a table of the dependent steps with their descriptions.
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Send to TestFlight**](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/send-to-app-store#send-apps-to-testflight) | This step sends the relevant application version to TestFlight. Ensure the [**App Store Connect API Key**](https://docs.appcircle.io/account/adding-an-app-store-connect-api-key#linking-appcircle-with-app-store-connect) is added to Appcircle and selected. |
### Input Variables
The parameters required for this step to work as expected are listed below.
| Variable Name | Description | Status |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_VALIDATION_CONDITION` | This parameter determines which condition must be met for the step to be successful. There are four different options: as `One of the External or Internal`, `Internal`, `External`, or `Both`. | Required |
### TestFlight Informations
The **App Information** feature within the **Get Approval from TestFlight** step allows easy access to your application’s version details on **TestFlight**. This feature enables you to view **App Information** about your application and to distribute versions to testing groups efficiently.
#### Missing Compliance
Apple conducts the Missing Compliance check for all apps uploaded to TestFlight. Appcircle promptly displays a notification if your application lacks compliance. For detailed guidance on this compliance check, please refer to [this Apple Developer document](https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations).
#### Test Information and Distribution to Tester
With this feature of Appcircle, you can see the test information of the version you send on **TestFligt** according to **different localizations**. At the same time, you can easily see your **internal and external** test groups and the number of testers they contain. With the toggle next to the test groups, you can send the related version to that test group and enable testers to receive notifications via TestFlight as runtime.
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-testflight-status-check
---
## Check App Store Release Status
With Appcircle's **Check App Store Release Status** component, you can obtain status information for your published application, bind this step to a condition based on the status, and check and run your flow accordingly.
### Prerequisites
Below are the prerequisite steps necessary for this operation, along with their descriptions.
:::caution
This is a standalone step. The steps listed below should precede this step if they are part of your Publish Flow.
:::
| Prerequisite Workflow Step | Description |
|----------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| [**App Information from App Store**](/publish-integrations/ios-publish-integrations/app-information-app-store) | This step compares the Release Candidate version with the TestFlight and the App Store versions. |
| [**Sent to Testflight**](/publish-integrations/ios-publish-integrations/send-to-app-store) | This step allows you to submit your application to TestFlight. |
| [**Get Approval from TestFlight**](/publish-integrations/ios-publish-integrations/approval-test-flight) | This step checks the TestFlight status of your application and advances the Publish Flow according to the specified acceptance condition. |
| [**Add for Review on App Store Connect**](/publish-integrations/ios-publish-integrations/add-for-review-on-app-store) | This step checks the Release status of your application and advances the Publish Flow according to the specified acceptance condition. |
### Input Variables
Below are the parameters necessary for this step's operation, along with their descriptions.
:::caution Success Statuses
For this step to work based on a condition, a valid status must be provided. You can specify multiple statuses by separating them with commas. Some example statuses are listed below. For more information, please refer to the [**Apple documentation**](https://developer.apple.com/help/app-store-connect/reference/app-and-submission-statuses/).
Note: A few status are shown below as examples. For this step to be successful, if the status of the version on App Store Connect matches one or more of the given statuses, the step will be considered successful.
- **PREPARE_FOR_SUBMISSION**: Version ready for submission to review.
- **READY_FOR_REVIEW**: Version ready to be submitted, waiting for submission.
- **WAITING_FOR_REVIEW**: Version submitted, waiting for review.
- **IN_REVIEW**: Version is being reviewed.
- **READY_FOR_SALE**: Version review was successful, released on App Store.
:::
| Variable Name | Description | Status |
|-----------------------|------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_SUCCES_STATUSES` | Specifies the release status that has requirements for successful completion. For example: `WAITING_FOR_REVIEW`, `IN_REVIEW` | Required |
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-appstore-status-check
---
## iOS Integrations Overview
Welcome to the **iOS Publish Flows** section of our documentation. Here, you'll find comprehensive guides on the various steps involved in preparing and distributing your iOS app through Apple's ecosystem, including both the App Store and TestFlight.
## [App Information from App Store](/publish-integrations/ios-publish-integrations/app-information-app-store)
Gain insights into your app's details on the App Store and TestFlight. This guide will help you understand how to retrieve and display version information, track build numbers, and manage release notes.
## [Send to App Store](/publish-integrations/ios-publish-integrations/send-to-app-store)
Everything you need to know about submitting your app to the App Store can be found here. We cover the necessary preparations, API key configuration, and submission details.
## [Send to TestFlight](/publish-integrations/ios-publish-integrations/sent-to-testflight)
This guide provides step-by-step instructions on how to send your build to TestFlight for beta testing, how to configure testing settings, and how to manage tester feedback effectively.
## [Get Approval from TestFlight](/publish-integrations/ios-publish-integrations/approval-test-flight)
After beta testing, you'll need to navigate the approval process. This section will walk you through checking the status of your app on TestFlight and understanding the necessary steps towards final approval.
## [Check App Store Release Status](/publish-integrations/ios-publish-integrations/check-app-store-release-status)
After submission, you'll need to navigate the approval process. This section will walk you through checking the status of your app on App Store Connect and understanding the necessary steps towards final approval.
## [Update Metadata on App Store Connect](/publish-integrations/ios-publish-integrations/update-metadata-on-app-store-connect)
Learn how to update and optimize your app's metadata on App Store Connect to improve visibility, attract more users, and boost downloads. Follow our step-by-step guide for better app store performance and engagement.
Each section is crafted to guide you through the respective processes, ensuring a smooth workflow from app development to launch. Click on the links provided to delve into the specifics of each flow.
---
## Send to App Store
This step enables you to submit your application to the [App Store](https://www.apple.com/app-store/).
:::caution
Ensure the [**App Store Connect API Key**](https://docs.appcircle.io/account/adding-an-app-store-connect-api-key#linking-appcircle-with-app-store-connect) is configured in Appcircle and chosen under [**Publish Settings**](https://docs.appcircle.io/publish-to-stores-module/#publish-settings).
:::
### Prerequisites
Below are the prerequisite steps necessary for this operation, accompanied by their descriptions.
:::caution
Note: This is a standalone step. The steps listed below should precede this step if they are part of your Publish Flow.
:::
| Prerequisite Workflow Step | Description |
| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| [**App Information from App Store**](/publish-integrations/ios-publish-integrations/app-information-app-store) | This step compares the Release Candidate version with the TestFlight and the App Store versions. |
| [**Sent to Testflight**](/publish-integrations/ios-publish-integrations/send-to-app-store) | This step allows you to submit your application to TestFlight. |
| [**Get Approval from TestFlight**](/publish-integrations/ios-publish-integrations/approval-test-flight) | This step checks the TestFlight status of your application and advances the Publish Flow according to the specified acceptance condition. |
### Input Variables
Below are the parameters necessary for this step's operation, along with their descriptions.
| Variable Name | Description | Status |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_XCODE_LIST_DIR` | Specifies the Xcode folder list directory. Current Xcode folder structure examples: `/Applications/Xcode/14.3/Xcode` or `/Applications/Xcode/15.0/Xcode`. | Optional |
| `$AC_XCODE_VERSION` | Specifies the Xcode version. | Required |
| `$AC_STACK_TYPE` | App Store or TestFlight stages. The default value is `TestFlight`. | Optional |
| `$AC_RELEASE_NOTES` | It is the parameter used to send a release note with the selected version. You can find detailed information about **Release Notes** [**here**](https://docs.appcircle.io/workflows/common-workflow-steps/publish-release-notes). | Optional |
:::info
This step may also target **TestFlight** exclusively, depending on the chosen **Stack Type**. If your **Publish Flow** includes the **Send to TestFlight** step, ensure the **Stack Type** is set to **`Release`**.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-send-to-appstore
---
## Send to TestFlight
This step enables you to upload the selected application package to [**TestFlight**](https://developer.apple.com/testflight/).
:::note
Note: If you attempt to upload a version that already exists on **TestFlight**, this step will prompt you to update the **version** or **build number**.
:::
:::caution
Ensure the [**App Store Connect API Key**](https://docs.appcircle.io/account/adding-an-app-store-connect-api-key#linking-appcircle-with-app-store-connect) is configured in Appcircle and selected under [**Publish Settings**](https://docs.appcircle.io/publish-to-stores-module/#publish-settings).
:::
### Prerequisites
The prerequisite steps for this operation are listed below.
| Prerequisite Workflow Step | Description |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [**App Information from App Store**](/publish-integrations/ios-publish-integrations/app-information-app-store) | This step provides information about the version you want to send and your versions in both [**TestFlight**](https://developer.apple.com/testflight/) and the [**App Store**](https://developer.apple.com/documentation/appstoreconnectapi/app_store). |
:::info
The **App Information from App Store** step is not mandatory before the **Send to TestFlight** step. However, if included in your workflow, it should precede the **TestFlight** step.
:::
### Input Variables
Below are the parameters necessary for this step's operation.
| Variable Name | Description | Status |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_XCODE_LIST_DIR` | Specifies the Xcode folder list directory. Current Xcode folder structure examples: `./Applications/Xcode/14.2/Xcode` or `./Applications/Xcode/15.2/Xcode` | Optional |
| `$AC_XCODE_VERSION` | This parameter takes the Xcode version value. It sends the selected Xcode version. You can find detailed information about Xcode versions [**here**](https://docs.appcircle.io/infrastructure/ios-build-infrastructure#available-xcode-versions). | Required |
| `$AC_RELEASE_NOTES` | It is the parameter used to send a release note with the selected version. You can find detailed information about **Release Notes** [**here**](https://docs.appcircle.io/workflows/common-workflow-steps/publish-release-notes). | Optional |
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-publish-send-to-testflight
---
## Update Metadata on App Store Connect
This step uploads all edited metadata information from the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information) page to the corresponding sections on App Store Connect. When this step executes, you can see the detailed updated metadata information with localization.
### Prerequisites
This step operates independently; it does not require any specific prior steps. You can incorporate it anywhere in the Publish Flow according to your workflow.
### Input Variables
Below are the parameters necessary for this step's operation, along with their descriptions.
:::info
- **Uploads screenshots while sending METADATA** : This value is `true` by default and includes screen shots uploaded in [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#ios-metadata-information) during the upload process. If `false`, screen shots will not be uploaded.
- **Update Metadata fields** : This value is `true` by default and ensures that the [**Metadata Information**](/publish-to-stores-module/publish-information/meta-data-information#ios-metadata-information) to be updated is uploaded. If `false`, the entered metadata information will not be uploaded.
- **Clear all previously uploaded screenshots** : This value is `false` by default. If `true`, screen shots on the App Store Connect will be deleted and new ones will be uploaded.
:::danger Clear all previously uploaded screenshots
Note that when this value is selected as `true`, your **screen shots** will be **deleted** from your **App Store Connect** account.
:::
| Variable Name | Description | Status |
| --------------------------------- | -----------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_XCODE_LIST_DIR` | Specifies the Xcode folder list directory. Current Xcode folder structure examples: `/Applications/Xcode/14.3/Xcode` or `/Applications/Xcode/15.0/Xcode`. | Optional |
| `$AC_XCODE_VERSION` | Specifies the Xcode version. | Required |
| `$AC_UPLOAD_SCREENSHOT_FILES` | Uploads screenshot files to App Store Connect for the related app version. | Optional |
| `$AC_UPDATE_METADATA_INFO` | If disabled updating METADATA info will be ignored. | Optional |
| `$AC_CLEAR_SCREENSHOTS` | If enabled all screenshots on App Store Connect will be removed before upload. | Optional |
---
## Binary Management
Appcircle supports publishing the application to the stores without using the Build module. To add an application version manually, you need to add a publish profile beforehand and then **Open** its details.
You can then upload the application by clicking on the **Upload Binary** button on the right.
When the upload is completed successfully, the relevant application versions will appear in the list.
:::caution BUNDLE ID AND PACKAGE NAME MUST BE UNIQUE
You can install iOS app versions with different BundleIDs under the same Publishing Profile. However, you can only initiate the Publish process with the binary that matches the BundleID specified when creating the profile or within the profile itself.
Similarly, for Android Publish Profiles, all app versions must have identical Package Names within the Android Publish Profile.
You can view the Bundle ID (iOS) and Package Name (Android) beneath the Publish Profile name. Users can also verify this information by selecting the [Binary Information](/publish-to-stores-module/publish-information/binary-information) for an app version under the actions menu.
:::
### BundleID Matching
When a binary BundleID uploaded to the Publish profile does not match the master BundleID specified for the profile, a warning icon will appear next to the binary. This icon indicates that the BundleID of the related binary does not match. For this reason, you **cannot start the Publish process** with the mismatched binary and send your application to the stores.
:::caution BundleID Matching
Note that you cannot mark your application version with a mismatched BundleID as a [**Release Candidate**](/publish-to-stores-module/publish-information/marking-release-candidates).
For BundleID change, you can use the [**Resign Binary**](/publish-to-stores-module/publish-information/resign-binary) feature in the Action button or upload a matching binary.
:::
Afterwards, you can start submitting your application to the stores with the publish flow that you have configured.
For this, click on the **Actions** button for the relevant version and go to **Details**. From there, you can manually **Start Flow** for the uploaded application version.
## Store Status
Appcircle now allows you to track the App Store status of your applications directly within the Publish to Stores module. This powerful feature is tailored for **Enterprise License** holders, ensuring continuous monitoring of your application's deployment status.
### How It Works
- **Enterprise License**: This feature is accessible to users with an enterprise license.
- **Continuous Monitoring**: Once a version is set as a **Release Candidate**, it is automatically monitored **every 30 minutes** to check its status on **TestFlight** and the **App Store Distribution**.
- **Priority on Distribution**: If the version is available in both **TestFlight** and **App Store Distribution**, the system prioritizes the status from **App Store Distribution**.
- **Version Status**: If a version has **never** been submitted to the **App Store**, it will show as **`Not Available`**.
- **Completion of Distribution**: When a version reaches **`Ready for Distribution`**, Appcircle stops monitoring it, allowing you to focus resources on versions that still require attention.
:::caution Store Credentials Required
Ensure you select store credentials in the [Publish settings](/publish-to-stores-module/publish-settings#store-credentials) to start monitoring. If the credentials are **not** selected, the status will display as **`Not Available`**.
:::
This streamlined approach ensures that you are always informed of your application's status, simplifying management and enhancing your deployment strategy directly from the Appcircle dashboard.
### Filter By Status
In the Publish to Stores module, where your Publish profiles are listed, you can use the filter option to display specific Publish profiles based on their latest store status.
:::tip
The iOS Publish filter options will only display the available statuses from the existing Publish profiles in your profile list.
:::
## FAQ
### How can I get a binary from another organization to use in the Publish to Stores Module ?
Let’s assume there are two organizations: Organization A and Organization B.
In Organization A, we have a build profile that generates an IPA, APK, or AAB.
In Organization B, we have a Publish profile that we want to send the binary to.
In Organization A's build profile workflow, after the build step, we can add a [Custom Script](/workflows/common-workflow-steps/custom-script/) step that includes the code snippet below to transfer the binary generated in Organization A to the Publish profile in Organization B. In order to do this, we need [Appcircle CLI](/appcircle-api-and-cli/cli-authentication), so this code snippet sets up the necessary information and sends binary with parameters.
```bash
#Bash script
sudo npm install -g @appcircle/cli
appcircle login personal-access-key --secret $ORG_B_PERSONAL_ACCESS_KEY
# If an IPA or AAB is required, change *.apk to *.ipa or *.aab
appcircle publish profile version upload \
--platform \
--publishProfileId "$ORG_B_PUBLISH_PROFILE_ID" \
--app "$AC_OUTPUT_DIR"/*.apk \
--markAsRc \
--summary
```
:::info
- --platform "ios" or "android" **[REQUIRED]** Specifies the platform for the binary.
- --markAsRc true/false **[OPTIONAL]** Marks the binary as a release candidate automatically. (Default: `false`)
- --summary "Release Notes" **[OPTIONAL]** Adds release notes to the app version.
**Note**: To include release notes, the version must first be [marked as a release candidate](/publish-to-stores-module/publish-information/marking-release-candidates).
:::
:::caution
Ensure that, uploading a binary to a Publish profile will require exact same **Package Name** or **Bundle ID**
:::
The key point here is that we need two essential parameters to make this work.
- `ORG_B_PERSONAL_ACCESS_KEY` => Personal Access Key from Organization B.
- `ORG_B_PUBLISH_PROFILE_ID` => Publish profile ID from Organization B.
- `$AC_OUTPUT_DIR` => Automatically defined by the system. See [Reserved Variables](/environment-variables/appcircle-specific-environment-variables/).
To generate Personal Access Key, follow this documentation [API authentication](/appcircle-api-and-cli/api-authentication/)
To obtain the Publish profile ID, follow the steps below:
1. Log in to organization B.
2. Go to Publish to Stores module.
3. Select the desired Publish profile
4. Copy it from the URL. `https://my.appcircle.io/publish/android/123456f-7d89-4545-5454-123456789abc`
5. Then the Publish profile ID is => `123456f-7d89-4545-5454-123456789abc`
After collecting the required parameters, set the following values as [Environment Variables](/environment-variables/):
- `ORG_B_PERSONAL_ACCESS_KEY`
- `ORG_B_PUBLISH_PROFILE_ID`
---
## Creating Publish Profiles
After building the application, we can start the publishing process by sending it to the Publish to Stores module.
For this, it is necessary to first create a publish profile within the Publish to Stores module. Afterwards, the relevant publish profile must be selected from the **Distribution** tab in the configuration of the relevant profile in the Build module.
In order to create a publish profile, click on the "Add New" button in the Publish to Stores module.
:::info
If it's your first time, set up connections to the app stores under [API Integrations](/account/my-organization).
:::
### Adding a New Publish Profile
There are 2 different options for creating a Publish Profile. One of them is manual creation and the other is to import your existing Store profile.
:::caution Creating a Publish Profile
The names of the profiles can be changed later and a different name must be set for each profile. This does not apply to Bundle ID and Package Name values. The Bundle ID and Package Name set for a profile cannot be changed again.
:::
## iOS Publish Profiles
iOS Publish profiles can be created manually or by importing an existing App Store Connect profile.
### Create Profile Manually
Manual creation requires a Publish Profile name and a Bundle ID that must be specified for this profile.
:::info Create Profile Manually
The Bundle ID set during manual creation cannot be changed later and is assigned as the main Bundle ID for that profile.
:::
When manual creation is selected, the name and BundleID fields required for the Publish profile must be filled in.
- **Publish Profile Name**: The name Publish profile is the name given to distinguish your profile from other profiles and appears on the profile card.
- **BundleID**: BundleID is the unique identifier of your application. It is hard-coded when the profile is created and cannot be changed afterwards.
:::danger
Please note that once the BundleID value of your profile has been set, it cannot be changed. Therefore, make sure that it is entered correctly.
:::
After manually creating your profile, you will see your profile card displayed on the Publish screen.
:::caution Main Bundle ID
Once a main Bundle ID is set, this Bundle ID is assigned to the created profile. This means that you can send binaries with different Bundle IDs into this profile, but you can only publish the binary that matches the profile Bundle ID.
An exclamation mark appears next to the binary that does not match the main Bundle ID of the profile. This means that the current Bundle ID of the binary does not match the specified Bundle ID.
:::
### Create from App Store Connect
Another option to create a profile is to import it. With this feature, a Publish profile is created with your existing app profile information on App Store Connect.
:::caution Apple Enterprise API Key
The **Create from App Store Connect** feature requires an **Apple API** key to create a profile. However, since the **Apple Enterprise Program** does not include **TestFlight** or **App Store Connect** features, **Apple Enterprise API Keys** are **not** listed anywhere in the **Publish to Stores module**.
If an **Apple Enterprise API** key has been added in your organization, it **cannot** be used in the Publish to Stores Module. For more information, please visit the [**Enterprise API Key Credential**](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key#enterprise-api-key-option-for-app-store-connect) documentation.
:::
Profiles on App Store Connect are listed with API key connection. In this list, the profile is imported by selecting either multiple or single profiles.
:::caution Create from App Store Connect
The Bundle ID value of the profile imported via App Store Connect is assigned the same value as the profile you imported. It cannot be changed afterwards.
:::
## Android Publish Profiles
Android Publish profiles can be created manually or by importing an existing Google Play Console profile.
### Create Profile Manually
Manual creation requires a **Publish Profile Name** and a **Package Name** that must be specified for this profile.
:::info Create Profile Manually
The Package Name set during manual creation **cannot** be changed later and is assigned as the **main** Package Name for that profile.
:::
When manual creation is selected, the name and Package Name fields required for the Publish profile must be filled in.
- **Publish Profile Name**: The name Publish profile is the name given to distinguish your profile from other profiles and appears on the profile card.
- **Package Name**: Package Name is the unique identifier of your application. It is hard-coded when the profile is created and cannot be changed afterwards.
After manually creating your profile, you will see your profile card displayed on the Publish screen.
### Create from Google Play Console
Another option to create a profile is to import it. With this feature, a Publish profile is created with your existing app profile information on Google Play Console.
First, a Google Play Console API key must be selected. This will be used to retrieve certain information from Google Play Console during the profile creation process.
Next, a Package Name must be provided. Appcircle will use the selected API key and the given Package Name to search for a match in Google Play Console.
If a correct match is found, the profile details will be displayed on the screen.
:::caution Create from Google Play Connect
The Package Name value of the profile imported via Google Play Connect is assigned the same value as the profile you imported. It cannot be changed afterwards.
:::
---
## Managing Publish Profiles
Publish profiles are used to define the target platforms and configurations for the application distribution. You can create multiple publish profiles for different target platforms and configurations and select the relevant publish profile for each build profile.
### Rename Publish Profile
Appcircle allows previously created Publish profiles to be renamed.
To do this, click on the three dots at the top right of the relevant publish profile in the profiles list and select **Rename**.
:::caution
Publish profile names must be unique for both **`iOS`** and **`Android`**.
For example, if you have a Publish profile named **`My Great App`** for iOS Publish, Appcircle will not allow you to create a profile named **`My Great App`** again for Android Publish or iOS Publish.
Also, you cannot rename a Publish profile to an existing name on the same platform.
:::
### Delete Publish Profile
To delete the Publish profile, click on the three dots at the top right of the relevant Publish profile in the profiles list and select **Delete**.
:::caution
Appcircle **does not delete** the application that has been submitted to the stores.
By deleting the Publish profile, all the application versions and Publish action logs related to that publish profile will be removed on the Appcircle side.
:::
---
## Publish to Stores
The Publish to Stores module is a powerful feature in Appcircle that allows you to distribute your mobile applications to the App Store, Google Play, Huawei AppGallery and Microsoft Intune. It provides a streamlined process for sending your apps directly to the stores or to TestFlight for beta testing.
:::tip Learn More
For a complete overview of the Appcircle Publish to Stores module capabilities, check out the [Appcircle's Profile Section](https://appcircle.io/publish-to-stores).
:::
## [Creating Publish Profiles](/publish-to-stores-module/creating-publish-profiles)
After building the application, in order to start the publishing process, you will need to create a Publish profile.
Creating Publish Profiles
## [Binary Management](/publish-to-stores-module/binary-management)
Manage your binaries within the Publish to Stores module.
Binary Management
## [Publish Flow](/publish-to-stores-module/publish-flow)
Appcircle includes a predefined flow in the Publish to Stores module for publishing the application to stores (App Store, Google Play, Huawei AppGallery, Microsoft Intune). This flow can be customized according to your specific publishing requirements.
Publish Flow
## [Publish Information](/publish-to-stores-module/publish-information)
The Publish to Stores module provides users with several key actions to manage their application versions effectively.
Publish Information
## [Publish Settings](/publish-to-stores-module/publish-settings)
Manage your profile and publish settings via the Publish Settings.
Publish Settings
## [Publish Variables](/publish-to-stores-module/publish-variables)
The Publish Variables section within the Publish to Storesmodule is a feature that allows you to set up and manage key-value pairs that are essential for the app publishing process.
Publish Variables
## [Publish Walkthrough for App Store](/publish-to-stores-module/publish-walkthrough-for-app-store)
The Publish to Stores module in Appcircle is a powerful tool designed for managing the release process of mobile applications to various app stores, including the Apple App Store, Google Play, and Huawei AppGallery. This module streamlines the complex process of app release via App Store Connect.
Publish Walkthrough for App Store
## [Publish Walkthrough for Google Play](/publish-to-stores-module/publish-walkthrough-for-google-play)
The Publish to Stores module in Appcircle is a powerful tool designed for managing the release process of mobile applications to various app stores, including the Apple App Store, Google Play, and Huawei AppGallery. This module streamlines the complex process of app release via Google Play.
Publish Walkthrough for Google Play
## [Publish Report](/publish-to-stores-module/publish-report)
The Publish Report provides a detailed overview of all actions performed within the Publish to Stores Module. It allows users to monitor, filter, and export publish-related activities across different platforms, trigger types, and stores.
Publish Report
## [Publish Re-sign Report](/publish-to-stores-module/publish-resign-report)
The Publish Re-sign Report provides detailed visibility into the manual and automatic re-sign operations performed within the Publish to Stores module. This report helps you monitor and analyze re-sign activities across your organization over a selected time period.
Publish Re-sign Report
## [Publish Activity Log](/publish-to-stores-module/publish-activity-log)
You can view Publish to Stores module actions such as Publish Flow and Publish Step statutes, along with resign binary operations within the Organizations or Sub Organizations in the Activity Log section.
Publish Activity Log
---
## Publish Activity Log
# Activity Log
You can view Publish to Stores module actions such as Publish Flow and Publish Step statutes, along with resign binary operations within the Organizations or Sub Organizations in the Activity Log section.
Here is the full list of actions that can be monitored:
- Profile Created
- Profile Deleted
- Publish Step Starting
- Publish Step Started
- Publish Step Success
- Publish Step Failed
- Publishing Failed
- Publishing Stopped
- Publishing Success
- Publishing Success Without Artifacts
- Publishing Restarted
- Publishing Restart Cancelled
- Play Store Release Updated
- Play Store Release Update Failed
- Metadata File Deleted
- Metadata Imported
- Metadata Updated
- Metadata Importing
- Publish Item Archived
- Publish Flow Updated
- Marked as Release Candidate
- Unmarked as Release Candidate
- App Version Uploaded
- App Version Created
- App Version Deleted
- Resign Success
- Resign Failed
- Resign Cancelled
- Release Notes Updated
- App Info Store Update Failed
- App Info Store Update Succeeded
- App Info Store Update Partially Failed
- App Version Rejected
- Review Submission Cancelled
:::caution
Only Organization / Sub-Organization Owners and users with Organization Management Role will have access to this area.
Information about other Organizations and their Sub-Organizations will not be accessible without the required level of clearance.
:::
:::info
Organization Owners can also observe the actions of their Sub-Organizations.
:::
You can edit the required date range by clicking the time filter in the top filter header as the default search time option is the last 30 days. Alternatively, you can choose custom dates from the calendar by selecting 'In Between' option.
Another method to search is by **Actions**. Simply click the filter option and select **Actions**. Then you can choose a specific action to refine your search.
---
## Publish Flow
Appcircle includes a predefined flow in the Publish to Stores module for publishing the application to stores (App Store, Google Play, Huawei AppGallery, Microsoft Intune). This flow can be customized according to your specific publishing requirements.
:::caution Runner Usage
Appcircle's Publish to Stores module requires a **runner** to operate. The runner dependency of each step in the **Publish Flows** is specified in the relevant step's documentation. For detailed information on runner dependencies, please refer to the documentation of the relevant steps.
:::
When you click on the **Publish Flow** button, the list of steps included in the publish flow will appear.
We can access the list of steps that can be used in a publish workflow by clicking on the **Manage Flow** button. You can add or remove new steps and customize your publish workflow as you wish.
You can effortlessly obtain a **YAML** file of your current Publish Flow configurations on our platform with the **Download YAML** button at the bottom.
By simply selecting the download option, you'll receive a YAML file containing all the details of your existing workflow setup.
Customize your workflows effortlessly by uploading your YAML file with the **Replace Flow** button at the top.
Simply select the file containing your desired configurations and integrate them seamlessly into the platform.
---
## App Store Connect Information
For a binary to be successfully sent for review, certain information must be completed. By using Appcircle's App Information feature, you can update the required information for binary submission.
### Localizable Informations
The localization dropdown allows you to select the language in which you want to present your app’s information on the App Store. This feature supports multiple languages, ensuring that you can target specific demographics and cater to a global audience.
When you select a language, you will provide localized versions of your app's information, including name, subtitle, and privacy policies. Localization helps in reaching a wider audience by providing information in the users' native language.
### General Informations
General information area allows you to see and update some of your information that will appear on the market for your application.
In these fields, you can specify the category of your application and provide information about the content it contains.
### Update and Save
You can instantly view your current App Information details and, if desired, simultaneously update these values on your App Store Connect account. Each time this screen is opened, the current information will be retrieved.
:::danger App Information Save
When you make a change to these informations and click the **save button**, the updates will be **immediately** applied to your App Store Connect account. Make sure your selections are **correct** and the information entered is **accurate**.
:::
### Fields Explained
#### Localizable Information
- **Name**: The name of your app as it will appear on the App Store.
- **Subtitle**: A brief summary of your app, limited to 30 characters.
- **Privacy URL**: A URL that links to your privacy policy. A privacy policy is required for all apps.
- **User Privacy Choices URL**(Optional): A URL where users can modify and delete the data collected from the app, or decide how their data is used and shared.
#### General Information
- **BundleID**(Read-Only): The bundle ID must match the one you used in Xcode. It can't be changed after you upload your first build.
- **SKU**(Read-Only): A unique ID for your app that is not visible to users.
- **Apple ID**(Read-Only): An automatically generated ID assigned to your app.
- **Primary Language**: If localized app information isn’t available in a country or region, the information from your primary language will be used instead.
- **Primary Category**: The primary category that best describes this app.
- **Secondary Category**(Optional): The secondary category that best describes this app.
- **Content Rights**: If your app contains, shows, or accesses any third-party content, you must have the rights to it or be permitted to use the content.
---
## Auto Re-sign
The **Auto Re-sign** feature in Appcircle’s Publish to Stores module allows users to automatically re-sign their iOS (`.ipa`) and Android (`.apk`/`.aab`) applications with a different keystore, provisioning profile, or certificate before distribution.
## Enabling Auto Re-sign
To use the **Auto Re-sign** feature in the Appcircle Publish to Stores module, you need to enable the **Auto Re-sign** toggle within the Publish Settings section.
:::caution Business Rule for Auto Publish and Auto Re-sign
Appcircle supports both **Auto Publish** and **Auto Re-sign** features. If both toggles are **enabled** simultaneously, Appcircle, by business rule, will first initiate the automatic re-signing process. Once the re-signing is complete, the automatic publishing process will begin. For more detailed information about **Auto Publish**, please refer to the Auto Publish [documentation](/publish-to-stores-module/publish-settings#auto-publish).
:::
## Auto Re-sign Configuration
To use Appcircle’s Auto Re-sign feature, you must first define a **configuration**. Appcircle will refer to this configuration for each automatic re-signing process and re-sign the incoming binary accordingly.
:::info Auto Re-sign
Please note that if Auto Re-sign is **enabled** and the configuration is **completed**, the re-signing process will automatically begin as soon as a binary is uploaded to the associated profile.
:::
:::caution Auto Re-sign configuration
If the configuration is **not defined correctly**, the re-signing flow **may fail**. Please make sure that your configuration is accurate and properly set up before uploading your binary.
:::
## For iOS
The functionality and configuration steps of **Appcircle’s Auto Re-sign** feature for the iOS platform are explained step-by-step below.
### Information
From the **Information** tab under Auto Re-sign configuration, you can manage the application's bundle identifier and display name values.
#### Bundle Identifier
Appcircle Publish profiles can accept binaries with different bundle identifiers. The binary defined for the profile serves as the reference for Auto Re-sign. When a binary with a different bundle identifier is uploaded, it is re-signed according to the bundle identifier of the profile. The bundle identifier of the resulting re-signed binary is updated to match the one associated with the profile.
> ⚠️ Note: Release flows cannot be initiated with a binary whose bundle identifier differs from that of the profile. For more information, please visit the Binary Management [documentation](/publish-to-stores-module/binary-management).
:::caution Multiple Target Binary
If the binary to be re-signed has multiple targets, each target bundle identifiers **must be registered** in your **Apple Developer** portal. Otherwise, you **may encounter errors** during the re-signing process.
:::
#### Select a Pool
The Pool Selection field defines which organization pool will be used to execute the Auto Re-sign process.
:::caution Pool Selection Is Mandatory
Auto Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Auto Re-sign process will not start.
- Uploaded binaries will remain unsigned.
- No re-signed output will be generated for Publish profile.
Always ensure that a valid macOS pool is selected before saving the Auto Re-sign configuration.
:::
#### Display Name
With the **Display Name** parameter, you can change the visible name of the binary that will be re-signed. The re-signing process starts with the specified display name, and once completed, the `CFBundleDisplayName` value inside the binary is updated accordingly.
### Versioning
By utilizing the versioning capability of the Auto Re-sign feature, you can modify the version and build number of the incoming binary according to the defined strategy during the re-signing process.
#### Update Build Number
With the **Update Build Number** feature, you can automatically increment the build number of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new build number will be generated based on the given offset before the re-signing begins, and the binary will be signed with this updated build number.
- **Build Number Source**: The defined base build number will be used for versioning during the re-signing process. **App Store**, **TestFlight**, and **Uploaded Binary** are available options.
- **App Store**: The build number will be calculated based on the latest live version available on the **Apple App Store**.
- **TestFlight**: The build number will be determined by referencing the latest version available on **TestFlight**.
- **Uploaded Binary**: The build number or version code will be calculated from the **most recent binary** uploaded to Appcircle.
- **Build Number**: The offset value is a number to be added or subtracted from the **build number source**.
#### Update Version Number
With the **Update Version Number** feature, you can automatically increment the version number of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new version number will be generated before the re-signing begins, based on the selected increment strategy and offset, and the binary will be signed with this updated version number.
- **Version Number**: The defined base version number will be used for versioning during the re-signing process. **App Store**, **TestFlight**, and **Uploaded Binary** are available options
- **App Store**: The version number will be calculated by referencing the latest live version available on the **Apple App Store**.
- **TestFlight**: The version number will be determined based on the latest version available on **TestFlight**.
- **Uploaded Binary**: The version number or version name will be calculated based on the most recently **uploaded binary** to Appcircle.
- **Version Number**: The offset value is a number to be added or subtracted from the **version number source**.
- **Increment Strategy**: You can increase the `major`, `minor`, or `patch` value of the version number.
:::caution Update Versioning
Within the Auto Re-sign feature configuration, if any store-based option is selected for versioning, it is mandatory to select an appropriate API key to retrieve the version information. If you do not want to perform versioning using the store, please select the **Uploaded Binary** option instead.
For more information, please visit the **Credentials** [documentation.](/account/my-organization/security/credentials)
:::
### Signing
Appcircle requires valid certificate and provisioning profile to successfully perform the auto re-sign process. The re-signing begins using the associated certificates and provisioning profile..
#### App Store Credential
Appcircle’s Auto Re-sign feature requires an **App Store Connect** credential. Therefore, selecting a credential is mandatory for both versioning and signing processes. This credential is used to download the necessary signing assets and retrieve version-related information when versioning is configured to use App Store data.
For more information, please visit the **App Store Connect API Key** [documentation](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key).
#### Signing Method
The **Signing Method** defines how Appcircle selects the provisioning profile during the re-signing process. This strategy determines whether Appcircle should use an existing provisioning profile. Selecting the appropriate signing strategy ensures compatibility with your target distribution method and proper signing of your binary.
For more information about these signing strategies, please visit the Apple Profiles [documentation](/signing-identities/apple-profiles).
:::caution Enterprise API Key and In-house Signing
The Auto Re-sign feature also supports **In-house** signing. You can perform this by selecting an **Enterprise API Key**. However, please note that only In-house signing is allowed with an Enterprise Key—attempting to use it with any other signing method will result in an error.
:::
#### Create a New Provision Profile
If the **Create a New Provision Profile** option is enabled, Appcircle generates a valid provisioning profile for signing using the Apple API Key selected in the profile settings and your Apple Developer account. If this option is disabled, Appcircle matches an existing valid provisioning profile from your Apple Developer portal for the signing process.
:::caution Create a New Provision Profile
If you **do not** want to create the provisioning profile for signing, Appcircle will attempt to match a valid provisioning profile and use it for the signing process. When this option is disabled and a matching provisioning profile cannot be found, a new provisioning profile will be automatically created.
:::
#### Using Existing Provisioning Profile
When using the Auto Re-sign feature, Appcircle also provides the option to select an existing provisioning profile. If the **Create a New Provision Profile** option is not enabled, the user can manually select a provisioning profile. To be selectable, the relevant profile must already be uploaded under **Apple Profiles** in the **Signing Identity** module.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Apple Profiles](/signing-identities/apple-profiles) documentations.
:::caution Existing Provision Profile
If no provisioning profile is selected, Appcircle will still **attempt to match** a provisioning profile using the selected **App Store Credential**. If the provisioning profile **cannot be found** in the **Apple Developer portal**, a new one **will be generated**.
For example, if the binary being signed has multiple targets and only one provisioning profile has been selected, Appcircle **will try to find** the related provisioning profiles for the other targets in the **Apple Developer portal**, and if they are not found, **it will generate them**.
:::
#### Certificates
In addition to the selected signing strategy, Appcircle requires a corresponding certificate to perform the auto re-sign process. Therefore, make sure that your certificates are uploaded under the **Apple Certificate** section in the **Appcircle Signing Identity module**. The re-signing process will begin using the certificate you have selected.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Apple Certificates](/signing-identities/apple-certificates) documentations.
:::caution Enterprise API Key and In-house signing
If you want to perform **In-house** signing using an **Enterprise API** Key, make sure that a compatible signing certificate is selected. Otherwise, Appcircle will not be able to verify the certificate and the signing process will fail.
:::
## For Android
The functionality and configuration steps of **Appcircle’s Auto Re-sign** feature for the Android platform are explained step-by-step below.
### Information
From the Information tab under Auto Re-sign configuration, you can manage the application's package identifier value.
#### Package Identifier
Appcircle Publish profiles can accept binaries with different package name. The binary defined for the profile serves as the reference for Auto Re-sign. When a binary with a different package name is uploaded, it is re-signed according to the package name of the profile. The package name of the resulting re-signed binary is updated to match the one associated with the profile.
> ⚠️ Note: Release flows cannot be initiated with a binary whose package name differs from that of the profile. For more information, please visit the Binary Management [documentation](/publish-to-stores-module/binary-management).
#### Select a Pool
The Pool Selection field defines which organization pool will be used to execute the Auto Re-sign process.
:::caution Pool Selection Is Mandatory
Auto Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Auto Re-sign process will not start.
- Uploaded binaries will remain unsigned.
- No re-signed output will be generated for Publish profile.
Always ensure that a valid macOS pool is selected before saving the Auto Re-sign configuration.
:::
### Versioning
By utilizing the versioning capability of the Auto Re-sign feature, you can modify the version code and version name of the incoming binary according to the defined strategy during the re-signing process.
#### Update Version Code
With the **Update Version Code** feature, you can automatically increment the version code of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new version code will be generated based on the given offset before the re-signing begins, and the binary will be signed with this updated version code.
- **Version Code Source**: The defined base version code will be used for versioning during the re-signing process. **Google Play**, and **Uploaded Binary** are available options.
- **Google Play**: The version code will be set by referencing the latest live version on **Google Play Console**.
- **Uploaded Binary**: The version code will be calculated from the **most recent binary** uploaded to Appcircle.
- **Version Code Offset**: The offset value is a number to be added or subtracted from the **version code source**.
#### Update Version Name
With the **Update Version Name** features, you can automatically increment the version name of the uploaded binary during the auto re-sign process using the specified offset value. When this feature is enabled, a new version name will be generated before the re-signing begins, based on the selected increment strategy and offset, and the binary will be signed with this updated version name.
- **Version Number/Version Name Source**: The defined base version name will be used for versioning during the re-signing process. **Google Play** and **Uploaded Binary** are available options
- **Google Play(Android)**: The version name will be set by referencing the latest live version on **Google Play Console**.
- **Uploaded Binary**: The version name will be calculated based on the most recently **uploaded binary** to Appcircle.
- **Version Name Offset**: The offset value is a number to be added or subtracted from the **version name source**.
- **Increment Strategy**: You can increase the `major`, `minor`, or `patch` value of the version name.
:::caution Update Versioning
Within the Auto Re-sign feature configuration, if any store-based option is selected for versioning, it is mandatory to select an appropriate API key to retrieve the version information. If you do not want to perform versioning using the store, please select the **Uploaded Binary** option instead.
For more information, please visit the **Credentials** [documentation.](/account/my-organization/security/credentials)
:::
### Signing
Appcircle requires a necessary Keystore to successfully perform the auto re-sign process. The re-signing begins using the associated keystore.
#### Google Play Console Credential
A **Google Play Console** credential is only required if versioning is configured to use store-based data. When versioning is set to retrieve version information from the Google Play Console, an API key must be provided to access live version details during the re-signing process.
#### Keystores
The **Keystores** section is where you manage the signing credentials required for Android re-signing. To successfully perform the auto re-sign process, Appcircle needs access to a valid keystore. You must upload the keystore file, provide the necessary alias, and enter the key and store passwords within the **Android Keystores** section of the **Signing Identity** module. The re-signing will be executed using the selected keystore credentials.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Android Keystores](/signing-identities/android-keystores) documentations.
#### Convert AAB To APK
The **Convert AAB to APK** option allows you to automatically convert an Android App Bundle (AAB) file into an APK during the re-signing process. This is especially useful when your distribution channel requires an `APK` instead of an `AAB`. When enabled, Appcircle will handle the conversion and signing of the resulting APK seamlessly.
---
## Binary Information
The "Binary Information" feature in the Publish to Stores module provides essential details about the app's binary file. This information is critical for understanding the specifics of each build.
## Viewing Binary Information
To access the binary details for a specific version of your app:
1. **Navigate to the Appropriate Version:**
- Within the Publish to Stores module, locate and select the version you want to examine.
2. **Open Binary Information:**
- Click on the "Binary Information" option to display the binary details.
## Contents of Binary Information
The Binary Information section typically includes:
- **App Name:** The name of the application.
- **Binary:** The file name of the binary.
- **Binary Size:** The size of the binary file.
- **Version:** The release version of the application.
- **Version Code:** An internal version number used for identifying builds.
- **Bundle ID:** The unique bundle identifier for iOS apps.
- **Signed Certificate Name:** The name of the certificate used to sign the app.
- **Provision Profile Type:** The type of provisioning profile used for the build.
Additionally, you'll find:
- **Release Notes:** Any notes or remarks associated with the release.
- **Entitlements:** A list of app entitlements that grant specific capabilities to the app.
## Example
Here's an example of how binary information might appear:
```plaintext
App Name: My App
Binary: my-app.ipa
Binary Size: 25 MB
Version: 1.0.0
Version Code: 100
Bundle ID: com.mycompany.myapp
Signed Certificate Name: iOS Distribution
Provision Profile Type: App Store
Release Notes: Initial release
Entitlements: Push Notifications, In-App Purchases
```
## Release Notes
Release Notes are an important part of the binary information, providing context and details about what is included in each version of the application. These notes are shared with the users or testers and often contain information about new features, bug fixes, and other updates.
### Adding Release Notes
Before publishing your binary to the app stores, you can add Release Notes in the Publish to Stores module:
1. **Access Binary Information:**
- Navigate to the 'Binary Information' section for the selected app version in the Publish to Stores module.
2. **Input Release Notes:**
- Click on the text field under 'Release Notes' to type in your message.
- Detail the key points that users should know about the new app version, such as new features, improvements, or issues resolved.
3. **Save Release Notes:**
- Once you have entered the release notes, save your changes.
- These notes will accompany the binary when it is published, so ensure they are clear and concise.
### Best Practices for Release Notes:
- **Be Clear:** Write in a simple, direct language so that all users can understand the changes.
- **Be Concise:** Keep the notes brief but informative — avoid overwhelming the user with too much information.
- **Highlight Important Changes:** Clearly state any major new features, bug fixes, or any changes that affect user interactions.
- **Localization:** If your app supports multiple languages, consider localizing the release notes for each supported language.
:::tip Release Notes Localization for Google Play
Appcircle supports automatic parsing and submission of localized release notes to Google Play Console. When you provide release notes in multiple languages using the supported format, the system automatically separates and submits them as individual localized entries for each language.
**Supported Format:**
Use Google Play language codes with square brackets to define language-specific content:
```html
- Added dark mode support
- Fixed login issues
- Performance improvements
- Karanlık mod desteği eklendi
- Giriş sorunları düzeltildi
- Performans iyileştirmeleri
- Dark-Mode-Unterstützung hinzugefügt
- Anmeldeprobleme behoben
- Leistungsverbesserungen
- Se agregó soporte para modo oscuro
- Se corrigieron problemas de inicio de sesión
- Mejoras de rendimiento
```
**How to Use:**
1. Format your release notes using the language code pattern shown above
2. Provide the formatted content via Build module or enter manually in the Binary Information
3. The system will automatically parse and submit each language variant to Google Play Console
**Supported Language Codes:** Use standard Google Play locale codes (e.g., `en-US`, `tr-TR`, `de-DE`, `fr-FR`, `ja-JP`, `zh-CN`). For a complete list of supported locale codes, refer to [Google Play Console documentation](https://support.google.com/googleplay/android-developer/table/4419860).
:::
Release Notes are an essential tool for communication with your users. They can significantly impact the user's perception and adoption of new updates. Always include them as part of your publishing process.
:::caution Release Notes Character Limit
**For TestFlight**
When submitting updates through TestFlight, the "What to Test" section has a 4,000-character limit. If your release notes exceed this limit, Apple will automatically trim the message to fit. Please ensure your notes are within this limit to avoid any important information being cut off.
**For Google Play Console**
When submitting updates to Google Play Console, each language has a [500-character limit](https://support.google.com/googleplay/android-developer/answer/9859348?hl=en) for release notes. Google Play supports up to [48 languages](https://play.google.com/console/about/translationservices/), allowing a total of 24,000 characters across all localized entries (500 characters × 48 languages).
:::
## Entitlements Detail
Entitlements are key-value pairs that define various permissions and features your app can use. You might see entries like:
- `aps-environment`: Determines the push notification environment.
- `application-identifier`: Uniquely identifies your app.
- `keychain-access-groups`: Defines groups for sharing keychain data.
- `get-task-allow`: Controls the app's ability to be debugged.
Remember, the binary information reflects the build details at the time of its creation and is crucial for troubleshooting and validating app versions.
Ensure to review the binary information for each build to confirm that the correct details are included before proceeding with the publish flow. This information is essential for ensuring that the app is correctly configured and ready for submission to the app stores.
## Binary Comparison
In the top-right corner of the Binary Information screen, you can click the **Compare** button to compare the current binary with another of your choice. The comparison highlights differences between the two binaries using color-coded indicators for easy identification.
:::caution Build Details Comparison
Binaries generated through the Appcircle Build Module include associated build details. **However**, if the compared binary was **manually** uploaded to Appcircle, those details **will not be available** for comparison.
:::
---
## Cancel Submission
With Appcircle's **Cancel Submission** feature, you can cancel your submitted version on **App Store Connect**. With this feature, you can easily withdraw the relevant version from the review without going to App Store Connect.
:::caution Cancel Submission
This feature is only active for versions with a status of **Waiting for Review** or **In Review** on App Store Connect. If the version does not have one of these statuses, the feature will appear disabled.
:::
---
## Check Release Status
Appcircle performs status checks for your published applications. This status gives you information about the status of the relevant version on the market. You can find detailed information about Appcircle's status feature in the [**Store Status Documentation**](/publish-to-stores-module/binary-management#store-status).
Appcircle updates a published app for status updates **every 30 minutes** if the app is [**Marked as RC**](/publish-to-stores-module/publish-information/marking-release-candidates). However, the user can also do this manually.
:::caution Check Release Status Manually
This feature is currently only available for **iOS profiles**. It will be available for Android profiles as soon as possible.
:::
With the Check Release Status function, you can instantly update the status information of the version marked as Release Candidate.
:::info
Make sure that one of the versions is [**Marked as Release Candidate**](/publish-to-stores-module/publish-information/marking-release-candidates) so that you can do a status check.
:::
:::danger Check Release Status
To avoid exceeding **API request limits** and causing other issues, manual status checks are limited to one request **every 10 minutes**.
:::
---
## Delete
# Deleting a Build Version
The "Delete" function in the Publish to Stores module allows users to remove specific versions of an app from the module. This action does not affect any versions of the app that have been submitted to app stores; it only removes the version from Appcircle's Publish to Stores module.
## Steps to Delete a Build Version
1. **Locate the Version:**
- Find the app version you wish to delete in the Publish to Stores module.
2. **Access Delete Option:**
- Click on the trash can icon or the menu option for the version you want to delete.
3. **Confirm Deletion:**
- A confirmation dialog will appear to ensure that you intend to delete the version.
- Carefully read the confirmation message. It will specify the version you are about to delete.
4. **Proceed with Deletion:**
- If you're sure you want to proceed, click on the "Delete" button.
- If you've changed your mind, select "Cancel" to keep the version.
## Important Notes:
- **Check Before Deleting:** Always double-check which version you are deleting to prevent removing the wrong one.
- **Irreversible Action:** Deletion is permanent. Once a version is deleted, it cannot be recovered through Appcircle.
- **Does Not Affect Store Submissions:** Deleting a version from Appcircle's Publish to Stores module does not remove it from any app stores where it has been published.
## Use Cases for Deleting a Build Version
- **Cleaning Up:** Remove outdated or unnecessary builds to keep your Publish to Stores module organized.
- **Storage Management:** Free up space in your Publish to Stores module by deleting old or superseded versions.
Remember to use this feature judiciously to maintain the integrity of your build history and avoid accidental loss of important build versions.
:::caution
Appcircle does not delete the application that has been submitted to the stores. This deletion will only delete the version of the application in the Publish to Stores module.
:::
---
## Downloading Binaries
The "Download" function in the Publish to Stores module allows you to easily download the built application files, such as IPA for iOS or APK/AAB for Android, directly to your local system.
## Steps to Download Your Binary
1. **Navigate to the Desired Version:**
- In the Publish to Stores module, locate the version of the app that you want to download.
2. **Open the Options Menu:**
- Click on the three dots (menu icon) next to the version to see more options.
3. **Select 'Download':**
- From the dropdown menu, choose the "Download" option.
4. **Save the File:**
- Your browser will prompt you to save the file. Choose a destination on your local machine and confirm to start the download.
5. **Verification (Optional):**
- After the download is complete, it is recommended to verify the integrity of the file, which can be done by checking the checksum, if available.
## Use Cases for Downloading Binaries
- **Local Testing:** Quickly grab a build for local testing or sharing with testers who may not have access to the Publish to Stores module.
- **Backup:** Keep a local backup of certain builds for record-keeping or rollback purposes.
- **Distribution:** Manually distribute the build to other services or stakeholders as needed.
Please note that the availability of binaries for download might depend on the retention policy set within the Publish to Stores module or the build's life cycle management rules. Make sure to download the binaries you need before they are auto-purged if such a policy is in place.
---
## Google Play Console Information
For Android binaries, by using Appcircle's Google Play Console Information feature, you can update the required information for binary submission.
### Contact Information
You can fill in your contact information to be displayed on Google Play, including your email address, phone number, and website.
### General Information
The general information area allows you to see and update the default language and configure your auto review setting for your app on Google Play Console.
#### Default Language
The default language for an app on Google Play Console is the primary language in which the app’s store listing (title, description, and other metadata) is displayed when a user visits the app’s page. If a user’s device language is not supported by the app’s store listing, they will see the information in the default language.
#### Auto Send for Review
Auto Send for Review is where you select whether your changes should automatically go for review on the Google Play Console. Please note that this setting is optional.
:::info Understanding the `changesNotSentForReview` Parameter in Google Play Android Publisher API
When making release requests via the Google Play Android Publisher API, the `changesNotSentForReview` parameter determines whether your changes are immediately sent for review or not. However, Google enforces certain constraints, requiring this parameter to be either `true` or `false` depending on the current status of the app and other factors.
:::
To handle this behavior efficiently, we provide four different options for managing releases:
1. **Send for Review Automatically but Rescue Errors**:
- The system will attempt to send changes for review.
- If an error occurs due to `changesNotSentForReview` being set incorrectly, the API call will be retried with the opposite value.
2. **Don't Send for Review Automatically but Rescue Errors**:
- The system will attempt to keep changes in a draft state without sending them for review.
- If an error occurs due to `changesNotSentForReview` being set incorrectly, the API call will be retried with the opposite value.
3. **Always Send for Review Automatically**:
- The system will always attempt to send changes for review.
- If an error occurs, the process will fail without retrying.
4. **Never Send for Review Automatically**:
- The system will always attempt to keep changes in a draft state.
- If an error occurs, the process will fail without retrying.
By selecting the appropriate option, you can ensure that your release process aligns with Google's requirements while maintaining flexibility in handling potential API constraints.
### Update and Save
You can instantly view your current App Information details and, if desired, simultaneously update these values on your Google Play Console account. Each time this screen is opened, the current information will be retrieved.
:::danger App Information Save
When you make a change to this information and click the **save button**, the updates will be **immediately** applied to your Google Play Console account. Make sure your selections are **correct** and the information entered is **accurate**.
:::
### Fields Explained
#### Contact Information
- **Email Address**: The email address that will be displayed on Google Play.
- **Phone Number**: The phone number that will be displayed on Google Play.
- **Website**: The website that will be displayed on Google Play.
#### General Information
- **Default Language**: The default language for your app.
- **Auto Send for Review**: Select whether your changes should automatically go for review on the Google Play Console.
---
## History
The History section has two parts: The Publish History and The Resign History.
The Publish History section is a record of all the publishing actions that have been performed for different versions of an application. It serves as a log for tracking the deployment lifecycle of each release.
The Resign History section is a record of all the resign actions that have been performed within the Publish to Stores module for a specific app version.
## Overview
Once you select the History section you can access both the Publish History and the Resign History.
You can access the Publish History to gain insight into the sequence of events for each published version. It is an invaluable tool for auditing, troubleshooting, and understanding the timeline of version deployments.
Build History will provide the original build logs from the build profile that was distributed to the selected publish profile.
You can also access the Resign History for an app version by navigating to it's tab to monitor the resign actions for that specific version.
### Accessing Publish History
To view the Publish History, navigate to the History section in the Publish to Stores module. Once History is selected, The Publish History tab will be displayed by default. This section lists all versions of the app along with the dates and times their publishing actions started along with their publish status.
### Viewing Logs
- **Description:** Each entry in the Publish History is clickable and will provide a detailed log of the publish action.
- **Purpose:** These logs contain information about the start time, the steps executed during publishing, any issues encountered, and the eventual success or failure of the publish action.
### Example Entry
Here is an example of what an entry in the Publish History might look like:
- **Current Tag:** Indicates the version is the most recent one that has been published.
- **Start Date:** Shows the date and time when the publish action for this version commenced.
### Log Details
Upon selecting a specific version, you will be presented with a detailed log. This log may include:
- The initiation of the publish action.
- Progress updates through various stages of the process.
- Any warnings or errors that were logged.
- The completion status of the publish action.
### Best Practices
- **Regular Reviews:** It is recommended to review the Publish History regularly to monitor the health and status of your publishing pipeline.
- **Error Handling:** In the case of a failed publish action, use the detailed logs to identify and troubleshoot the issue.
- **Record Keeping:** Keep records of your Publish History for compliance purposes and to maintain a historical reference.
---
The Publish History is a key feature that provides transparency and traceability in the application deployment process. By regularly reviewing this section, you can ensure that your publish actions are performing as expected and maintain a high level of quality control over your release management process.
### Accessing Build History
To view the Build History, go to the History section for an app version in the Publish to Stores module, and then navigate to the Build History tab.
This displays the build logs of the selected binary, initiated in the original build profile before being distributed to the publish profile.
:::info
Please note that to access the build logs from this tab, the selected binary must be automatically distributed from a build profile.
:::
### Accessing Resign History
To view the Resign History, navigate to the History section in the Publish to Stores module, then simply select the Resign History tab.
### Viewing Logs
Each signing process will be listed for that binary. If you click on the displayed resign action , you can get more details about the process by seeing the logs.
:::info
You need the check the history of the original application that has been signed.
:::
Read more about Resign Binary
---
## Publish Information Overview
The Publish to Stores module provides users with several key actions to manage their application versions effectively. Below is an overview of each menu item and its function within the system:
## [App Store Connect Information](/publish-to-stores-module/publish-information/app-information)
For a binary to be successfully sent for review, certain information must be completed. By using Appcircle's App Information feature, you can update the required information for binary submission.
## [Check Release Status](/publish-to-stores-module/publish-information/check-release-status)
With the Check Release Status function, you can instantly update the status information of the version marked as Release Candidate. Make sure that one of the versions is marked as Release Candidate so that you can do a status check.
## [Publish Details](/publish-to-stores-module/publish-information/publish-details)
This option provides an in-depth view of the selected version's publish process. Users can review the steps taken, configurations used, and outcomes of the publish sequence. It's an essential resource for understanding the specific details of a version's journey through the publish workflow.
## [Auto Re-sign](/publish-to-stores-module/publish-information/auto-resign-configuration)
The **Auto Re-sign** feature in Appcircle’s Publish to Stores module allows users to automatically re-sign their iOS (`.ipa`) and Android (`.apk`/`.aab`) applications with a different keystore, provisioning profile, or certificate before distribution.
## [Google Play Console Information](/publish-to-stores-module/publish-information/google-play-information)
For Android binaries, by using Appcircle's Google Play Console Information feature, you can update the required information for binary submission.
## [Marking Release Candidates](/publish-to-stores-module/publish-information/marking-release-candidates)
This action is used to change the status of a build that has been previously marked as a Release Candidate (RC). This might be necessary if the build is found to have issues that require it to be retracted from the release candidate status, indicating it's not yet ready for production release.
## [Binary Information](/publish-to-stores-module/publish-information/binary-information)
Selecting this menu item displays detailed information about the application binary. This includes metadata such as the build version, creation date, binary size, and any relevant identifiers. It's particularly useful for developers and release managers who need to verify binary specifics before distribution.
## [Metadata Details](/publish-to-stores-module/publish-information/meta-data-information)
The Meta Data Information option provides a comprehensive overview of the version's metadata. This includes details such as the application name, version, build number, and other relevant information. Users can review and edit metadata to ensure accurate and consistent versioning across the application.
## [Resign Binary](/publish-to-stores-module/publish-information/resign-binary)
The Resign Binary feature allows users to resign both iOS and Android application binaries. For iOS applications, users can change provisioning profiles or app entitlements, while for Android applications, users can resign binaries with a new keystore. This feature is essential for updating app distribution settings and security credentials without requiring a new build.
## [History](/publish-to-stores-module/publish-information/history)
The History has two sections: The Publish History and The Resign History.
The Publish History gives users a chronological log of all publish actions taken for a specific version. It allows users to track and audit the deployment process over time, which can be crucial for compliance, troubleshooting, and historical analysis.
The Resign History gives users a chronological log of all resign actions that was done within the Publish to Stores Module for a specific app version.
## [Downloading Binaries](/publish-to-stores-module/publish-information/download)
This functionality enables users to download the binary directly from the Publish to Stores module. This is useful for offline review, storage, or distribution purposes. The download feature ensures that users can access and disseminate the application's build even outside the publish platform.
## [Cancel Submission](/publish-to-stores-module/publish-information/cancel-submission)
Canceling a submission on the App Store can be crucial for developers who need to make last-minute changes or corrections. Learn how to efficiently cancel your app submission, understand common pitfalls, and ensure a smoother app review process.
## [Reject Binary](/publish-to-stores-module/publish-information/reject-binary)
Binary rejection on Appcircle can delay your app's launch. Discover the top reasons for binary rejection, how to address them effectively, and ensure your app meets guidelines for a successful approval process. Optimize your app's chances today!
## [Delete](/publish-to-stores-module/publish-information/delete)
The Delete option provides a way to remove a version from the system. It should be used with caution as it will permanently eliminate the selected version and all associated data from the Publish to Stores module. This feature helps in maintaining a clean and organized workspace by removing obsolete or unnecessary versions.
---
Each menu item is an integral part of the Publish to Stores module, providing comprehensive tools for managing application versions from creation to deployment. Users should familiarize themselves with these options to fully leverage the capabilities of the Publish system.
For further details on each menu item, refer to the corresponding section in this documentation.
---
## Marking Release Candidates
### Mark Version as Release Candidate
Appcircle allows you to mark your app version as RC and designate any version as a **Release Candidate** with ease by simply selecting the desired app version and clicking on the **Mark as RC** button.
:::caution
In order to execute a flow, it must be marked as a Release Candidate (RC). If it is not marked as RC, it cannot be executed.
:::
The chosen version will be visibly distinguished, allowing users to easily identify it as a `Release Candidate`.
:::tip
If you configure an app version with `Auto Publish=On` in its build configurations within the build module before distribution to the Publish profile, Appcircle will automatically mark the app version as a `Release Candidate` and execute the Publish Flow operation directly.
Please note that this is valid for auto-published app versions. Any app version that was uploaded manually via UI or API can not be marked as `Release Candidate` automatically.
:::
---
## Metadata Details
## Overview
The Metadata Information section in the Appcircle dashboard is essential for defining the presence of your application on digital distribution platforms. This document will guide you through each field and its significance to ensure your app's metadata is complete and effective.
:::info
Please note that accessing Metadata Details requires an organization with Enterprise License.
:::
## iOS Metadata Information
### Localization Settings
The localization dropdown allows you to select the language in which you want to present your app’s metadata on the App Store. This feature supports multiple languages, ensuring that you can target specific demographics and cater to a global audience.
When you select a language, you will provide localized versions of your app's metadata, including promotional texts, descriptions, and what’s new in this version. Localization helps in reaching a wider audience by providing information in the users' native language.
### Metadata Auto-Population
If there is existing metadata associated with your app on the App Store, the **Metadata Information** page will automatically populate these fields with the existing data. This feature simplifies the update process by allowing you to review and modify the pre-filled information rather than starting from scratch. It ensures consistency and accuracy in your app’s metadata across different versions and localizations.
### Metadata from Last Updated
With Appcircle's **Retrive from Last Updated** feature, you can automatically update your metadata. When a new version is added, you can directly retrieve the metadata information updated in the previous version with the **Retrive From Last Updated** function on the metadata screen.
:::caution Metadata from Last Update
With this feature, the last metadata information you saved in Appcircle is copied to the relevant version.
Please note that if this function is used, **no data will be pulled from App Store Connect**. The data retrieved will be the metadata information saved in the **previous version**.
:::
### Fields Explained
#### iOS Previews and Screenshots
- **Drag and Drop**: Upload up to 3 app previews and 10 screenshots.
- **iPhone**: Supported resolutions are 1290 x 2796px or 2796 x 1290px.
- **iPad**: Supported resolutions are 2048 x 2732px or 2732 x 2048px.
#### App Information
- **Promotional Text**: Optional text to inform App Store visitors about any current app features without requiring an updated submission.
- **Description**: Provide a detailed description of your app, highlighting its features and functionalities.
- **What’s New**: Describe what’s new in this version of your app, such as new features, improvements, and bug fixes.
:::info What’s New Field
Please note, this field is constantly visible on Appcircle. However, on App Store Connect, it will **only** appear when a new version is **released**. For this reason, if you are not going to release a **new version**, you may not see the information you enter here on **App Store Connect**.
:::
- **Name**: The name of your app as it will appear on the App Store.
- **Subtitle**: A brief summary of your app, limited to 30 characters.
- **Keywords**: Include keywords that describe your app. Separate keywords with English commas, Chinese commas, or a mix of both.
- **Support URL**: A URL with support information for your app. This will be visible on the App Store.
- **Marketing URL**: A URL with marketing information about your app. This will be visible on the App Store.
#### App Version Information
- **Version**: The version number of the app following standard software versioning conventions.
- **Copyright**: The name of the person or entity that owns the copyright to your app.
#### App Review Information
- **Sign-In Information**: If your app requires a sign-in, provide credentials that will be used by the review team.
- **Contact Information**: Provide the name, phone number, and email of the contact person for the App Review team.
- **Notes**: Include any additional information that you want to share with the App Review team.
#### App Release Information
- **App Store Version Release**: Choose how you want to release your app on the App Store:
- Manually release this version
- Automatically release this version
- Automatically release this version after App Review, no earlier than a specified date and time
- **Phased Release for App Store Automatic Updates**: Opt in to gradually release updates over a 7-day period to users.
- **Reset iOS App Store Summary Rating**: Decide if you want to reset the app's rating when the new version is released.
:::danger Reset iOS App Store Summary Rating
Please note, this comes with **Keep Existing Rating** selected by default. If you choose to **Reset rating when this version released** option, it will reset all past **reviews and ratings** of your app in **App Store**.
:::
## Android Metadata Information
### Localization Settings
The localization dropdown allows you to select the language in which you want to present your app’s metadata on the Google Play Console. This feature supports multiple languages, ensuring that you can target specific demographics and cater to a global audience.
When you select a language, you will provide localized versions of your app's metadata, including video, descriptions, and app name. Localization helps in reaching a wider audience by providing information in the users' native language.
### Metadata Auto-Population
If there is existing metadata associated with your app on the Google Play Console, the **Metadata Information** page will automatically populate these fields with the existing data. This feature simplifies the update process by allowing you to review and modify the pre-filled information rather than starting from scratch. It ensures consistency and accuracy in your app’s metadata across different versions and localizations.
:::info
**Updating Android Metadata:** You can easily update your Google Play Console metadata for your app via Appcircle by following these steps:
- Update your app's metadata on Appcircle within the Publish to Stores module.
- Add the **Update Metadata on Google Play Console** Publish flow step to your workflow.
- Run your Publish Flow of your app by selecting the Publish Details under actions menu.
:::
This step can be configured further by selecting the step options.
:::caution
Your app version within the Publish profile needs to be marked as Release Candidate before you can retrieve or update Google Play Console metadata.
:::
### Fields Explained
#### Android Previews and Screenshots
- **Drag and Drop**: Upload up to 8 screenshots.
- **App Icon**: Supported resolutions are 512 to 512 px.
- **Feature Grapich**: Supported resolutions 1024 to 500 px.
- **Phone**: Supported resolutions are 320 to 3840 px. And it has 16:9 or 9:16 aspect ratio.
- **Tablet**: Supported resolutions are 320 to 3840 px for 7" display and 1080 to 7680 px for 10" display. And it has 16:9 or 9:16 aspect ratio.
- **Android TV**: Supported resolutions are 320 to 3840 px for Android TV and 1280 to 720 px for TV Banner.
- **Wear OS**: Supported resolutions are 384 to 3840px. And it has 1:1 aspect ratio.
#### App Information
- **Video**: Add a video by entering a YouTube URL. This video must be public or unlisted, ads must be turned off, and it must not be age restricted, and it should be landscape.
- **App Name**: This is how your app will appear on Google Play.
- **Short Description**: A short description for your app. Users can expand to view your full description.
- **Full Description**: A full description for your app.
:::warning Mandatory Google Play Metadata Fields
On **Google Play Console**, certain metadata fields are **mandatory** and must be completed before you can **save** the metadata details in Appcircle.
The following fields are required by Google Play:
- **App Name**
- **Short Description**
- **Full Description**
- **App Icon**
- **Feature Graphic**
- **Phone Screenshots**
If any of these required fields are missing, Google Play Console will not allow the metadata to be saved or updated. Make sure all mandatory fields are properly filled and uploaded before running the **Update Metadata on Google Play Console** publish step.
:::
## Microsoft Intune Metadata Information
The metadata information field can be changed according to the store credentials selection in Publish Settings. If Intune credential is selected as store credentials, the metadata screen will automatically include Microsoft Intune metadata information.
:::danger Microsoft Intune Metadata and Credential
If the Microsoft Intune credential is not selected, the metadata fields will not change. For this reason, make sure that you have integrated [**Microsoft Intune credential**](/account/my-organization/security/credentials/adding-microsoft-intune-api-key) and selected the correct credentials in [**Publish Settings**](/publish-to-stores-module/publish-settings#store-credentials).
:::
### Metadata Auto-Population
If there is existing metadata associated with your app on the Microsoft Intune, the **Metadata Information** page will automatically populate these fields with the existing data. This feature simplifies the update process by allowing you to review and modify the pre-filled information rather than starting from scratch. It ensures consistency and accuracy in your app’s metadata across different versions.
### Fields Explained
- **Name**: Name for the app. This name will be visible in the Intune apps list and to users in the Company Portal.
- **Description**: Help your device users understand what the app is and/or what they can do in the app. This description will be visible to them in Company Portal.
- **Publisher**: The name of the developer or company that distributes the app. This information will be visible to users in Company Portal.
- **Applicable Device Type**: Select the device types that can install this app
- **Minimum Operating System**: Select the earliest operating system version on which the app can be installed. If you assign the app to a device with an earlier operating system, it will not be installed.
- **Category**: Categorize the app to make it easier for users to sort and find in Company Portal. You can choose multiple categories
- **Featured App**: Featured apps are prominently placed in Company Portal so that users can quickly get to them.
- **Information URL**: Link people to a website or documentation that has more information about the app. The information URL will be visible to users in Company Portal.
- **Privacy URL**: Provide a link for people who want to learn more about the app's privacy settings and terms. The privacy URL will be visible to users in Company Portal.
- **Developer**: The name of the company or Individual that developed the app. This information will be visible to people signed into the admin center.
- **Owner**: The name of the person in your organization who manages licensing or is the point-of-contact for this app. This name will be visible to people signed in to the admin center.
- **Notes**: Add additional notes about the app. Notes will be visible to people signed in to the admin center.
## Conclusion
Filling out the Metadata Information section accurately is crucial for the successful listing and update of your app on the App Store and Microsoft Intune. It ensures that potential users receive the most current information and that your app meets all necessary guidelines for
---
## Publish Details
This option provides an in-depth view of the selected version's publish process. Users can review the steps taken, configurations used, and outcomes of the publish sequence. It's an essential resource for understanding the specific details of a version's journey through the publish workflow.
## Accessing Publish Details
To view the details of your publish flow:
1. **Select the Version:**
- Locate and select the build version you want to review in the Publish to Stores module.
2. **Open Publish Details:**
- Click on the "Publish Details" option to open the detailed view of the publish flow.
3. **Review the Logs:**
- Examine the logs to monitor the progress of your publishing actions.
- The logs will provide step-by-step updates on the status of each task within the flow.
## Features of Publish Details
- **Workflow Status:** Displays the current status of the publishing flow, indicating whether actions are in progress, completed, or if there are any errors.
- **Step-by-Step Logs:** Provides a detailed log for each step within the publish process, including timestamps, which can be useful for troubleshooting and verification.
- **Restart Flow:** If needed, you can restart the publish flow from scratch. Please note that restarting the flow will cause current logs to be lost.
## Publish Flow for Android & iOS
- **Android:**
- The publish flow for Android includes steps like sending builds to the Google Play Store and managing additional settings specific to the Android ecosystem.
- **iOS:**
- For iOS, the publish flow includes steps for sending builds to TestFlight, getting approval from TestFlight, and submitting to the App Store.
Ensure to regularly check the Publish Details to confirm that your app versions have been successfully published to the respective app stores. The logs within this section are crucial for identifying and resolving any issues during the publish process.
---
## Reject Binary
Appcircle's **Reject Binary** feature allows you to reject the binary entering the publish process if it is not suitable. This feature adds flexibility to your publish management and enables more detailed control over your publishing processes.
If there is a problem with the binary sent for publish or the metadata is invalid, you can use the **Reject Binary** feature to invalidate the binary by leaving a note so that your team does not make a mistake.
:::danger Reject Binary
When a binary file is **rejected**, it can no longer be [**Marked as Release Candidate**](/publish-to-stores-module/publish-information/marking-release-candidates) and the rejection **cannot** be reversed.
:::
### Rejection Reason
To use the Reject Binary feature, you must provide a rejection message. This message will inform other team members of the reason for the rejection.
This message is presented to the user with a tool type on the Rejected tag on the binary.
---
## Re-sign Binary(Publish-information)
The **Re-sign Binary** feature in Appcircle allows you to re-sign both iOS and Android application binaries. For iOS applications, you can use new provisioning profiles or modify the app's entitlements, which is useful for adjusting the app’s capabilities or updating its distribution settings without requiring a new build. For Android applications, you can re-sign your binaries with a new keystore, allowing you to update the app's signing credentials crucial for app distribution and updates.
This feature streamlines the process of updating app distribution and security settings, ensuring that your applications can be quickly adapted to meet changing requirements or distribution strategies.
## Re-sign iOS Binary
When you need to distribute an iOS application to different environments (like QA, staging, or production) or need to change the app’s entitlements, the **Re-sign Binary** feature simplifies this process. You can resign an app binary with a new provisioning profile that matches the intended distribution certificate.
### Fields and Options
The functionality and configuration steps of **Appcircle’s Re-sign** feature for the iOS platform are explained step-by-step below.
### Information
From the **Information** tab under Re-sign configuration, you can manage the application's bundle identifier and display name values.
#### Bundle Identifier
Appcircle Publish profiles can accept binaries with different bundle identifiers. The binary defined for the profile serves as the reference for Re-sign. When a binary with a different bundle identifier is uploaded, it is re-signed according to the bundle identifier of the profile. The bundle identifier of the resulting re-signed binary is updated to match the one associated with the profile.
> ⚠️ Note: Release flows cannot be initiated with a binary whose bundle identifier differs from that of the profile. For more information, please visit the Binary Management [documentation](/publish-to-stores-module/binary-management).
:::caution Multiple Target Binary
If the binary to be re-signed has multiple targets, each target bundle identifiers **must be registered** in your **Apple Developer** portal. Otherwise, you **may encounter errors** during the re-signing process.
:::
#### Select a Pool
The Pool Selection field defines which organization pool will be used to execute the Re-sign process.
:::caution Pool Selection Is Mandatory
Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Re-sign process will not start.
- Selected binaries will remain unsigned.
- No re-signed output will be generated for Publish profile.
Always ensure that a valid macOS pool is selected before saving the Re-sign configuration.
:::
#### Display Name
With the **Display Name** parameter, you can change the visible name of the binary that will be re-signed. The re-signing process starts with the specified display name, and once completed, the `CFBundleDisplayName` value inside the binary is updated accordingly.
### Versioning
By utilizing the versioning capability of the Re-sign feature, you can modify the version and build number of the selected binary according to the defined strategy during the re-signing process.
#### Update Build Number
With the **Update Build Number** feature, you can automatically increment the build number of the selected binary during the re-sign process using the specified offset value. When this feature is enabled, a new build number will be generated based on the given offset before the re-signing begins, and the binary will be signed with this updated build number.
- **Build Number Source**: The defined base build number will be used for versioning during the re-signing process. **App Store**, **TestFlight**, and **Uploaded Binary** are available options.
- **App Store**: The build number will be calculated based on the latest live version available on the **Apple App Store**.
- **TestFlight**: The build number will be determined by referencing the latest version available on **TestFlight**.
- **Uploaded Binary**: The build number or version code will be calculated from the **most recent binary** uploaded to Appcircle.
- **Build Number**: The offset value is a number to be added or subtracted from the **build number source**.
#### Update Version Number
With the **Update Version Number** feature, you can automatically increment the version number of the selected binary during the re-sign process using the specified offset value. When this feature is enabled, a new version number will be generated before the re-signing begins, based on the selected increment strategy and offset, and the binary will be signed with this updated version number.
- **Version Number**: The defined base version number will be used for versioning during the re-signing process. **App Store**, **TestFlight**, and **Uploaded Binary** are available options
- **App Store**: The version number will be calculated by referencing the latest live version available on the **Apple App Store**.
- **TestFlight**: The version number will be determined based on the latest version available on **TestFlight**.
- **Uploaded Binary**: The version number or version name will be calculated based on the most recently **uploaded binary** to Appcircle.
- **Version Number**: The offset value is a number to be added or subtracted from the **version number source**.
- **Increment Strategy**: You can increase the `major`, `minor`, or `patch` value of the version number.
:::caution Update Versioning
Within the Re-sign feature configuration, if any store-based option is selected for versioning, it is mandatory to select an appropriate API key to retrieve the version information. If you do not want to perform versioning using the store, please select the **Uploaded Binary** option instead.
For more information, please visit the **Credentials** [documentation.](/account/my-organization/security/credentials)
:::
### Signing
Appcircle requires valid certificate and provisioning profile to successfully perform the re-sign process. The re-signing begins using the associated certificates and provisioning profile.
#### App Store Credential
Appcircle’s Re-sign feature requires an **App Store Connect** credential. Therefore, selecting a credential is mandatory for both versioning and signing processes. This credential is used to download the necessary signing assets and retrieve version-related information when versioning is configured to use App Store data.
For more information, please visit the **App Store Connect API Key** [documentation](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key).
#### Signing Method
The **Signing Method** defines how Appcircle selects the provisioning profile during the re-signing process. This strategy determines whether Appcircle should use an existing provisioning profile. Selecting the appropriate signing strategy ensures compatibility with your target distribution method and proper signing of your binary.
For more information about these signing strategies, please visit the Apple Profiles [documentation](/signing-identities/apple-profiles).
:::caution Enterprise API Key and In-house Signing
The Re-sign feature also supports **In-house** signing. You can perform this by selecting an **Enterprise API Key**. However, please note that only In-house signing is allowed with an Enterprise Key—attempting to use it with any other signing method will result in an error.
:::
#### Create a New Provision Profile
If the **Create a New Provision Profile** option is enabled, Appcircle generates a valid provisioning profile for signing using the Apple API Key selected in the profile settings and your Apple Developer account. If this option is disabled, Appcircle matches an existing valid provisioning profile from your Apple Developer portal for the signing process.
:::caution Create a New Provision Profile
If you **do not** want to create the provisioning profile for signing, Appcircle will attempt to match a valid provisioning profile and use it for the signing process. When this option is disabled and a matching provisioning profile cannot be found, a new provisioning profile will be automatically created.
:::
#### Using Existing Provisioning Profile
When using the Re-sign feature, Appcircle also provides the option to select an existing provisioning profile. If the **Create a New Provision Profile** option is not enabled, the user can manually select a provisioning profile. To be selectable, the relevant profile must already be uploaded under **Apple Profiles** in the **Signing Identity** module.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Apple Profiles](/signing-identities/apple-profiles) documentations.
:::caution Existing Provision Profile
If no provisioning profile is selected, Appcircle will still **attempt to match** a provisioning profile using the selected **App Store Credential**. If the provisioning profile **cannot be found** in the **Apple Developer portal**, a new one **will be generated**.
For example, if the binary being signed has multiple targets and only one provisioning profile has been selected, Appcircle **will try to find** the related provisioning profiles for the other targets in the **Apple Developer portal**, and if they are not found, **it will generate them**.
:::
#### Certificates
In addition to the selected signing strategy, Appcircle requires a corresponding certificate to perform the re-sign process. Therefore, make sure that your certificates are uploaded under the **Apple Certificate** section in the **Appcircle Signing Identity module**. The re-signing process will begin using the certificate you have selected.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Apple Certificates](/signing-identities/apple-certificates) documentations.
:::caution Enterprise API Key and In-house signing
If you want to perform **In-house** signing using an **Enterprise API** Key, make sure that a compatible signing certificate is selected. Otherwise, Appcircle will not be able to verify the certificate and the signing process will fail.
:::
### Resigning Process
To re-sign a binary, follow these steps:
1. **Select the Version**: Choose the version of your app you wish to resign from the **Version List** in the Publish to Stores module.
2. **Configure Re-signing Options**: Navigate to the **Re-sign Binary** action and configure the necessary fields such as the provisioning profile, entitlements, and other settings.
3. **Sign the Binary**: After configuring, click the **Sign** button to re-sign the binary. This process will create a new package with the updated provisioning profile and entitlements.
### Post-Resignation
Once the binary is resigned, a new package is automatically created to reflect the changes. This ensures that any distribution or testing utilizes the most current setup without requiring a complete rebuild.
The newly created package can then be distributed or tested according to your publish flow requirements. This update ensures that your application conforms to the necessary provisioning and entitlement specifications for different environments, such as development, staging, or production, without additional build steps.
This feature streamlines the application update process by allowing for quick adjustments to the app's configurations, significantly reducing the time and resources needed for separate build cycles.
## Re-sign Android Binary
Re-signing an Android binary allows you to apply a new keystore to your application after the initial build. This is useful for updating the signing configuration or switching to a different keystore as needed without needing to rebuild the app.
### Fields and Options
The functionality and configuration steps of **Appcircle’s Re-sign** feature for the Android platform are explained step-by-step below.
### Information
From the Information tab under Re-sign configuration, you can manage the application's package identifier value.
#### Package Identifier
Appcircle Publish profiles can accept binaries with different package name. The binary defined for the profile serves as the reference for Re-sign. When a binary with a different package name is selected, it is re-signed according to the package name of the profile. The package name of the resulting re-signed binary is updated to match the one associated with the profile.
> ⚠️ Note: Release flows cannot be initiated with a binary whose package name differs from that of the profile. For more information, please visit the Binary Management [documentation](/publish-to-stores-module/binary-management).
#### Select a Pool
The Pool Selection field defines which organization pool will be used to execute the Re-sign process.
:::caution Pool Selection Is Mandatory
Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Re-sign process will not start.
- Selected binaries will remain unsigned.
- No re-signed output will be generated for Publish profile.
Always ensure that a valid macOS pool is selected before saving the Re-sign configuration.
:::
### Versioning
By utilizing the versioning capability of the Re-sign feature, you can modify the version code and version name of the selected binary according to the defined strategy during the re-signing process.
#### Update Version Code
With the **Update Version Code** feature, you can automatically increment the version code of the selected binary during the re-sign process using the specified offset value. When this feature is enabled, a new version code will be generated based on the given offset before the re-signing begins, and the binary will be signed with this updated version code.
- **Version Code Source**: The defined base version code will be used for versioning during the re-signing process. **Google Play**, and **Uploaded Binary** are available options.
- **Google Play**: The version code will be set by referencing the latest live version on **Google Play Console**.
- **Uploaded Binary**: The version code will be calculated from the **most recent binary** uploaded to Appcircle.
- **Version Code Offset**: The offset value is a number to be added or subtracted from the **version code source**.
#### Update Version Name
With the **Update Version Name** features, you can automatically increment the version name of the selected binary during the re-sign process using the specified offset value. When this feature is enabled, a new version name will be generated before the re-signing begins, based on the selected increment strategy and offset, and the binary will be signed with this updated version name.
- **Version Number/Version Name Source**: The defined base version name will be used for versioning during the re-signing process. **Google Play** and **Uploaded Binary** are available options
- **Google Play(Android)**: The version name will be set by referencing the latest live version on **Google Play Console**.
- **Uploaded Binary**: The version name will be calculated based on the most recently **uploaded binary** to Appcircle.
- **Version Name Offset**: The offset value is a number to be added or subtracted from the **version name source**.
- **Increment Strategy**: You can increase the `major`, `minor`, or `patch` value of the version name.
:::caution Update Versioning
Within the Auto Re-sign feature configuration, if any store-based option is selected for versioning, it is mandatory to select an appropriate API key to retrieve the version information. If you do not want to perform versioning using the store, please select the **Uploaded Binary** option instead.
For more information, please visit the **Credentials** [documentation.](/account/my-organization/security/credentials)
:::
### Signing
Appcircle requires a necessary Keystore to successfully perform the re-sign process. The re-signing begins using the associated keystore.
#### Google Play Console Credential
A **Google Play Console** credential is only required if versioning is configured to use store-based data. When versioning is set to retrieve version information from the Google Play Console, an API key must be provided to access live version details during the re-signing process.
#### Keystores
The **Keystores** section is where you manage the signing credentials required for Android re-signing. To successfully perform the re-sign process, Appcircle needs access to a valid keystore. You must upload the keystore file, provide the necessary alias, and enter the key and store passwords within the **Android Keystores** section of the **Signing Identity** module. The re-signing will be executed using the selected keystore credentials.
For more information, please visit the [Signing Identity Module](/signing-identities) and [Android Keystores](/signing-identities/android-keystores) documentations.
#### Convert AAB To APK
The **Convert AAB to APK** option allows you to automatically convert an Android App Bundle (AAB) file into an APK during the re-signing process. This is especially useful when your distribution channel requires an `APK` instead of an `AAB`. When enabled, Appcircle will handle the conversion and signing of the resulting APK seamlessly.
### Re-signing Process
When you opt to resign an Android binary:
1. **Package ID**: This is your Android application's unique identifier and cannot be changed during the re-signing process.
2. **Version Name & Code**: Adjust the version name and code if necessary. This helps in maintaining versioning integrity across different release channels.
3. **Keystores**: Select the keystore you wish to use for re-signing the binary. This could be a newly added keystore or one previously used in other projects.
After configuring the necessary options, click the **Sign** button to start the re-signing process.
### Post-Resignation
Once the binary has been re-signed, it will create a new package with the updated signing configurations. The newly re-signed binary will appear in your version list marked with the new version code if updated during the process.
---
## Publish Report
The Publish Report provides a detailed overview of all actions performed within the Publish to Stores Module. It allows users to monitor, filter, and export publish-related activities across different platforms, trigger types, and stores.
These are the displayed fields within the Publish Report:
- Org Name
- Profile Name
- App Name
- Version
- Version Code
- Initiated By
- Trigger Type
- Platform
- Store
- Start Date
- Duration
## Filtering Options
Users can refine the report data using multiple filters:
- **Date Range:** Select specific time periods to analyze publish activity.
- **Platform:** Filter by iOS or Android
- **Trigger Type:** View actions triggered manually or automatically.
- **Store:** Filter by target app stores such as App Store Connect, Google Play Store, Microsoft Intune or Huawei AppGallery.
- **Email:** Filter by the email address of the user who initiated the publish process.
- **Profile Name:** Filter by the name of the Publish profile.
- **App Name:** Filter by the application name that was used in the Publish action.
- **Status:** Filter by Status of the Publish such as Success, Failed or Canceled.
:::info
In the filter options, you can only view and select the organization and sub-organization you belong to.
:::
---
## Publish Re-sign Report
The Publish Re-sign Report provides detailed visibility into the manual and automatic re-sign operations performed within the Publish to Stores module. This report helps you monitor and analyze re-sign activities across your organization over a selected time period.
These are the displayed fields within the Publish Report:
- Org Name
- Profile Name
- Platform
- Source Binary
- Target Binary
- Status
- Initiated By
- Trigger Type
- Start Date
- Duration
## Filtering Options
Users can refine the report data using multiple filters:
- **Date Range:** Select specific time periods to analyze publish re-sign activity.
- **Platform:** Filter by iOS or Android
- **Trigger Type:** View actions triggered manually or automatically.
- **Email:** Filter by the email address of the user who initiated the publish process.
- **Profile Name:** Filter by the name of the Publish profile.
- **App Name:** Filter by the application name that was used in the Publish action.
- **Status:** Filter by Status of the Publish such as Success, Failed or Canceled.
:::info
In the filter options, you can only view and select the organization and sub-organization you belong to.
:::
:::warning
Please note that the Publish Re-sign Report displays only the re-sign operations that were triggered in the Publish to Stores module.
:::
---
## Publish Settings
When a build is completed on the Build module and its artifacts are distributed to the Publish to Stores module, we can start the publish process to the stores using the **Auto Publish** toggle in **Settings**.
Your configured publish flow will be executed automatically when you enable **Auto Publish**.
You can also select a runner pool from the **SELECT A POOL** dropdown list.
"Appcircle Linux Pool (x86_64)" and "Appcircle Standard macOS Pool (arm64)" are Appcircle cloud-hosted pools and only available for the cloud services.
:::info
You can use both cloud-hosted pools for the Android publish profiles.
On the other hand, for iOS publish profiles, the only option for Appcircle Cloud is Apple Silicon-based "Appcircle Standard macOS Pool (arm64)".
"Appcircle Linux Pool (x86_64)" support is not available for the iOS publish profiles.
:::
If there are any self-hosted pools in your organization, you can also select them from the list. Self-hosted Appcircle users will only see the self-hosted pools in this list.
Self-hosted Pools
:::info
If group or variable definitions have been made in **Publish Variables**, you will see the list of variable groups in **Settings**, and you can select one or more of them to use in your publish flow.
:::
## Auto Publish
This switch, when enabled, automatically starts the publishing process for new app versions as they become available.
## Select a Pool
You can select a runner pool from the dropdown list to execute the publish flow.
There are two default pools available for cloud services:
- Appcircle Linux Pool (x86_64)
- Appcircle Standard macOS Pool (arm64)
:::info
You can use both cloud-hosted pools for the Android publish profiles.
On the other hand, for iOS publish profiles, the only option for Appcircle Cloud is Apple Silicon-based "Appcircle Standard macOS Pool (arm64)".
"Appcircle Linux Pool (x86_64)" support is not available for the iOS publish profiles.
:::
Self-hosted Appcircle users will see their self-hosted pools in this list.
## Publish Variables
Publish Variables are key-value pairs that can be used to store configuration settings, credentials, and other data required during the publish process. You can add new variables directly in the Publish Variables section without the need for an additional menu or button.
For detailed information on Publish Variables, follow the link below.
Publish Variables
## Store Credentials
Store credentials are the connection details for the stores that you will publish your app to.
For detailed information on store connections, follow the links below.
:::caution Apple Enterprise API Key
The Apple Enterprise Program is intended solely for in‑house distribution within an organization. Consequently, an Apple Enterprise API Key cannot be used in the Publish to Stores module because the Enterprise Program **does not** provide any **App Store Connect** or **TestFlight** infrastructure.
:::
| Store | Connection |
| ----------------- |-----------------------------------------------------------------------------------------------------------------------------|
| App Store | [Adding an App Store Connect API Key](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key.md) |
| Google Play | [Adding Google Play Service Account](/account/my-organization/security/credentials/adding-google-play-service-account.md) |
| Huawei AppGallery | [Adding Huawei API Key](/account/my-organization/security/credentials/adding-huawei-api-key) |
| Microsoft Intune | [Adding Microsoft Intune API Credentials](/account/my-organization/security/credentials/adding-microsoft-intune-api-key) |
#### Publish Priority
The publish priority configuration feature includes three levels: Low, Medium, and High.
These priority levels influence the starting order of queued publish processes, ensuring that higher-priority publish processes are initiated first.
For instance, if a high-priority publish is added to the queue after a low-priority publish, the high-priority publish will commence before the low-priority one.
This functionality allows for better management of publish processes, enabling teams to prioritize critical updates and enhancements efficiently.
:::info
This feature is only available for organizations with Enterprise license.
:::
---
## Publish Variables
The **Publish Variables** section within the Publish to Stores module is a feature that allows you to set up and manage key-value pairs that are essential for the app publishing process.
To use these defined variables, it will be necessary to select them from the [Publish Settings](/publish-to-stores-module/publish-settings/).
Publish Variables are key-value pairs that can be used to store configuration settings, credentials, and other data required during the publish process. You can add new variables directly in the Publish Variables section without the need for an additional menu or button.
## How to Add a New Publish Variable
1. **Input the Key-Value Pair:**
- Locate the input fields under the 'Publish Variables' header.
- Enter the name of the variable in the 'Key' input field.
- Enter the corresponding value in the 'Value' input field.
2. **Select Variable Type:**
- Choose the type of variable you're adding. Options typically include:
- **Text**: for string or numeric values.
- **File**: if you're assigning a file as the variable's value.
3. **Add the Variable:**
- Click the 'Add' button to save the new variable.
4. **Review and Confirm:**
- Once added, the new variable will appear in the list of Publish Variables.
- Ensure that the details are correct and the variable is saved properly.
## Example Variable
In the example provided:
- **Key Name**: `Foo`
- **Value**: `Bar`
- **Type**: `Text`
Remember to handle these variables with care, especially if they contain sensitive information such as passwords, tokens, or API keys.
:::info
Please note that Publish Variables can only be used within the Publish to Stores module.
:::
### Downloading environment variables
You can download and view environment variables in **JSON** format. For this, you can use the "Download" button by clicking on the three dots next to one of the variable groups under "Publish > Publish Variables > Variable Groups".
In the downloaded file content, you will see a structure with **key-value** pairs.
In addition, if the value part of the environment variable is set to hidden during the text-based environment variable addition process, the "isSecret" value will be `true` and the key, along with the value **will not** be listed in the downloaded file. The same rule is valid for file type variables. If it is not hidden, this value will be `false`, and the value will be visible.
:::info
An example of publish variable downloaded as a JSON file:
```json
[
{
"key": "API_URL",
"value": "https://api.example.com",
"isSecret": false,
"isFile": false,
"id": "API_URL"
}
]
```
As seen in the example above;
- if the **isSecret** value is `false`, it has visible value
- if the **isSecret** value is `true` or **isFile** value is `true` , the key and the value will not be downloaded.
:::
### Uploading environment variables
The Upload feature allows users to bulk-import environment variables into any existing Variable Group (e.g., Staging, Prod, or Dev) within the Publish > Publish Variables > Variable Groups section.
This feature streamlines the process of configuring variables by enabling users to upload a predefined JSON file instead of manually entering each variable.
The uploadable file must be a `.json` file with an array of variable objects. Each variable object must include the following fields:
```json
[
{
"key": "API_URL",
"value": "https://api.example.com",
"isSecret": false,
"isFile": false,
"id": "API_URL"
},
{
"key": "API_KEY",
"value": "12345-abcde-67890-fghij",
"isSecret": true,
"isFile": false,
"id": "API_KEY"
}
]
```
:::warning
- File type variables (isFile: `true`) cannot be uploaded using JSON. These must be added manually via the UI.
- The Download feature does not include secret values or file contents for security reasons.
- You can edit your own JSON files to update variables in a group. However, duplicated keys are not allowed.
:::
## Reserved Variables
There are some reserved variables that are automatically defined by Appcircle and can be used in the publish flow.
:::tip Additional Environment Variables Reference
This documentation also includes additional output environment variables from publish flow steps that may be useful to users.
For any input or output variables not listed here, please refer to the "Input Variables" or "Output Variables" sections on each publish flow step’s [documentation](/publish-integrations).
If there is an environment variable you believe should be included here, please [contact us here](https://appcircle.io/support/).
:::
### Common Publish Reserved Variables
| Variable | Description |
|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AC_RELEASE_NOTES | Specifies the release notes from the [Build profile](/build) (if published from there) or from one of the Publish steps, to be published to the stores (`Google Play`, `Huawei AppGallary`, or `App Store`). |
| AC_ORGANIZATION_ID | Specifies the organization ID where the publish process starts. |
| AC_USER_ID | Specifies the user ID who started the publish process. |
| AC_USER_EMAIL | Specifies the email address of the user who started the publish process. |
| AC_STORE_NAME | Name of the store where the app is being published. |
| AC_PLATFORM_TYPE | Platform type (e.g., `iOS:1`, `Android:2`). |
| AC_UNIQUE_NAME | Unique name of the app (starts with `com.` for Android and iOS). |
| AC_PUBLISH_APP_VERSION | Version of the app being published (e.g., `1.0.1`). |
| AC_PUBLISH_APP_VERSION_ID | App version ID being published on Appcircle. |
| AC_PUBLISH_APP_VERSION_CODE | Version code of the app being published. |
| AC_APP_EXPIRES_ON | Expiration date of the signed application. The date format is as follows: `2025-12-31T08:43:29Z` |
| AC_APP_VERSION_NAME | Name of the app version being published. |
| AC_STORE_CREDENTIAL_ID | ID of the store credential where the app is being published. |
| AC_PUBLISH_PROFILE_ID | Specifies the profile ID who started the publish process on Appcircle. |
| AC_TASK_ID | Task ID associated with the publish process on Appcircle. |
| AC_PUBLISH_ID | Publish ID on Appcircle. |
| AC_PUBLISH_STEP_ID | Publish step ID on Appcircle. |
| AC_RESOURCE_ID | Resource ID used in the publishing process on Appcircle. |
| AC_ORGANIZATION_POOL_ID | Pool ID of the organization where the publish process starts. |
| AC_SOURCE_ID | Source ID of the process (e.g., `Publish`). |
| AC_MODULE_NAME | Name of the module in the process (e.g., `Publish`). |
| AC_PUBLISH_PROFILE_NAME | Specifies the Appcircle profile name who started the publish process. |
| AC_PUBLISH_STEP_NAME | Name of the publish flow step being run. |
| AC_PUBLISH_FLOW_NAME | Name of the publish workflow being run. |
| AC_PUBLISH_STEPS_STATUS | Provides detailed information about the status of the publish steps executed so far. Steps that are disabled will not appear in this environment variable. The JSON output for executed steps includes the following fields: - **StepName**: The name of the executed step. - **StepId**: The unique ID of the executed step. - **StepStatus**: The status of the step. Possible values: `Success`, `Warning`, `Failed`, `NotStarted`, or `Stopped`. - **Duration**: The time taken to complete the step, represented in seconds (e.g., `0.0000000`). - **StartDate**: The start time of the step, formatted as an ISO 8601 timestamp (e.g., `2024-12-13T15:45:59.6426984Z`). - **FinishDate**: The completion time of the step, also formatted as an ISO 8601 timestamp (e.g., `2024-12-13T15:45:59.6426984Z`). For additional details and instructions on how to format this output for readability, refer to the [**How can I print the status of publish steps with detailed information?**](/publish-integrations/common-publish-integrations/custom-script#how-can-i-print-the-status-of-publish-steps-with-detailed-information) documentation. |
| AC_APP_FILE_URL | URL of the app file being published. |
| AC_APP_FILE_NAME | Name of the app file being published (with file extension). |
| AC_STACK_TYPE | The type of software stack used during the publishing process, such as Xcode, Gradle, etc. Please follow the necessary mapping values below: - **App Store = 12** - **TestFlight = 10** - **Alpha = 0** - **Beta = 1** - **Production = 2** - **Internal = 3** |
| AC_AUTHORIZATION | (Removed, redundant) |
| AC_PURPOSE | The intended purpose of the app, detailing its functionality or target audience. |
| AC_PUBLISH_ENVIRONMENT_VARIABLE_IDS | A list of environment variable identifiers used during the app publishing process, ensuring that the correct configuration is applied. |
:::caution Release Notes
User can use `AC_RELEASE_NOTES` environment variable, if the `apk`, `aab` or `ipa` files comes from Build module.
:::
### Marketplace Reserved Variables
#### Huawei AppGallery
| Variable | Description |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------|
| AC_HUAWEI_APP_ID | The unique identifier assigned to the application registered in the Huawei AppGallery for integration purposes. |
| AC_API_KEY | A secret key used by Appcircle to authenticate API requests and provide secure access to third-party services, such as app stores. |
| AC_API_KEY_FILE_NAME | The name of the file that stores the API key, used for secure access during integration. |
| AC_GEM_FILE | The configuration or dependency file for Ruby's gem package manager, used in the Appcircle build process. |
| AC_PLUGIN_FILE | The file containing plugins or extensions for Appcircle, used to extend functionality during the build or distribution process. |
| AC_MARKETPLACE_TYPE | Specifies the type of app marketplace, such as Google Play, App Store, or Huawei AppGallery, where the app will be distributed. |
| AC_FASTFILE_CONFIG | Configuration file for Fastlane’s Fastfile, used to automate app release and build processes in Appcircle. |
#### Google Play Store
| Variable | Description |
|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AC_RELEASE_STATUS | Represents the current release status of the application, indicating whether the app is in development, in testing, or has been released to a specific marketplace. |
| AC_APP_FILE_CONFIG | Configuration settings related to the app's file management, including details about file formats, paths, and settings required during the build or release process. |
| AC_API_KEY | A secure key used to authenticate API requests and authorize access to specific Appcircle services. |
| AC_API_KEY_FILE_NAME | The name of the file that contains the API key, typically used for secure integration with external services. |
| AC_MARKETPLACE_TYPE | Defines the app marketplace type, such as Google Play, Apple App Store, or Huawei AppGallery, where the app is distributed. |
#### App Store Connect
| Variable | Description |
|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
| AC_API_KEY_FILE_NAME | The name of the file that contains the App Store Connect API key, used for authenticating App Store Connect integrations. |
| AC_API_KEY | A secure API key for accessing App Store Connect services. |
| AC_APPLE_APP_SPECIFIC_USERNAME | The Apple username specifically used for app-related tasks and authentication in App Store Connect. |
| AC_APPLE_APP_SPECIFIC_PASSWORD | The application-specific password for secure access to Apple services such as App Store Connect. |
| AC_APPLE_ID | The unique Apple ID associated with the developer account used to manage app releases and distribution. |
| AC_APPLE_STORE_SUBMIT_API_TYPE | Specifies the type of API used for submitting apps to the Apple App Store, typically defining the submission process. |
| AC_BUNDLE_ID | The unique identifier (Bundle ID) for the app, used for identifying the app in App Store Connect and during submission. |
| AC_MARKETPLACE_TYPE | Defines the marketplace type, such as Apple App Store, where the app will be distributed. |
| AC_XCODE_VERSION | The version of Xcode used for building and submitting the app to the App Store. |
| AC_FASTFILE_CONFIG | Configuration for Fastlane’s Fastfile, used to automate the app release and build process. |
| AC_SCREEN_SHOT_LIST | A list of app screenshots required for submission to the App Store, showcasing the app's interface and functionality. |
| AC_APP_PREVIEW_LIST | A list of app preview videos required for submission to the App Store, highlighting the app's features. |
| AC_METADATA_LOCALIZATION_LIST | A list of metadata localizations for the app, containing translated descriptions, keywords, and other localized content for different regions. |
#### Microsoft Intune
| Variable | Description |
|--------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| AC_ORGANIZATION_NAME | The name of the organization or team that owns the app and is associated with the Apple Developer account. |
| AC_BUNDLE_ID | The unique identifier (Bundle ID) for the app, used for identifying the app in App Store Connect and during submission. |
| AC_ICON_RESOURCE_REFERENCE_ID | The reference ID for the app's icon resource, used to associate the correct icon during the build and submission process. |
| AC_MARKETPLACE_TYPE | Defines the marketplace type, such as Apple App Store, where the app will be distributed. |
| AC_XCODE_VERSION | The version of Xcode used for building and submitting the app to the App Store. |
### iOS Publish Reserved Variables
| Variable | Description |
|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AC_XCODE_LIST_DIR | Specifies the Xcode folder list directory. |
| AC_XCODE_VERSION | Specifies the Xcode version. |
| AC_VALIDATION_CONDITION | Used for the [Get Approval from TestFlight](/publish-integrations/ios-publish-integrations/approval-test-flight). TestFlight's `internalBuildState` and `externalBuildState` will be checked according to the selection. |
| AC_SUCCESS_STATUSES | You can customize `Acceptable/Succeeded` App Store statuses for your app. |
| AC_STACK_TYPE | `App Store` or `TestFlight` stages. |
| AC_APP_FILE_URL | The URL where the IPA file for the app is hosted, used for distribution or submission purposes. |
| AC_APP_FILE_NAME | The name of the IPA file that will be uploaded to the app store for submission. |
| AC_APPLE_STORE_SUBMIT_API_TYPE | Specifies the type of API used for submitting apps to the Apple App Store, typically defining the submission process. |
### Android Publish Reserved Variables
| Variable | Description |
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AC_RELEASE_STATUS | Used for the [Send to Google Play](/publish-integrations/android-publish-integrations/publish-to-google-play) step. Allows you to specify `draft` or `completed` app statuses on the Google Play Console. |
| AC_STACK_TYPE | Used for the [Send to Google Play](/publish-integrations/android-publish-integrations/publish-to-google-play) step. Specifies the release track to send the binary. After the binary is uploaded, you can release it from the Google Play. |
| AC_TRACK_TO_CHECK | Used for the [Get Approval from Google Play](/publish-integrations/android-publish-integrations/get-approval-from-google-play) step. It's recommended to check the track that you've sent the app in previous steps. |
| AC_ACCEPTED_STATUSES | Used for the [Get Approval from Google Play](/publish-integrations/android-publish-integrations/get-approval-from-google-play) step. Statuses of `completed`,`inProgress`,`draft`,`halted` can be used. |
| AC_HUAWEI_APP_ID | Used for the [Send to Huawei AppGallery](/publish-integrations/android-publish-integrations/publish-to-huawei-appgallery) step. Huawei requires `Huawei App ID` to be sent app to Huawei App Gallery. |
| AC_APP_FILE_URL | The URL where the APK file for the Android app is hosted, used for distribution or submission purposes. |
| AC_APP_FILE_NAME | The name of the APK file that will be uploaded to the app store for submission. |
| AC_ICON_RESOURCE_REFERENCE_ID | The reference ID for the app's icon resource, used to associate the correct icon during the build and submission process. |
| AC_APP_ICON_URL | The URL of the app icon that will be displayed in the app store and on devices. |
| AC_APP_ICON_FILE_NAME | The name of the file containing the app icon, used during the app submission process. |
## FAQ
### How to change environment variable and exchange it between steps?
In the Appcircle Publish to Stores module, the steps within a Publish flow operate independently. This means that each step is executed in a separate, clean runner environment. This feature allows steps to run independently and individually. Therefore, to exchange environment variables between steps, the modified ENV value needs to be saved as an output variable.
Below is an example of how this can be done. Once an ENV variable is modified in a step and saved to the output direction, it will become accessible in another step.
- For the first step. Suppose we create a release note using the [**Publish Release Note Component**](/workflows/common-workflow-steps/publish-release-notes) during the build process. We then want to modify and use this release note during the Publish process.
:::caution
Predefined Publish Variables can also be modified using this method; however, once the flow is completed, they will revert to their originally defined default values.
:::
```bash
# Take AC_RELEASE_NOTES value
ac_build_release_notes="$AC_RELEASE_NOTES"
# Check the variable if it is null
if [ -z "$ac_build_release_notes" ]; then
echo "Error: AC_RELEASE_NOTES variable was not determined or it is null."
exit 1
else
# Print current value
echo "Before: $ac_build_release_notes"
# Change release note value
ac_build_release_notes="Release note changed\n New Release note prepared"
# Print changed value
echo -e "Changed: $ac_build_release_notes"
# Write new env value AC_CHANGED_RELEASE_NOTES to .env file in output direction
echo -e "AC_CHANGED_RELEASE_NOTES=\"${ac_build_release_notes}\"" >> $AC_OUTPUT_DIR/AC_OUTPUT.env
fi
```
- For the second step: We can now access this environment variable directly in another step.
```bash
echo "Print Changed Release Note Variable"
echo $AC_CHANGED_RELEASE_NOTES
```
---
## Publish Walkthrough for App Store
## Why Use the Publish to Stores Module: Features and Benefits
The Publish to Stores module in Appcircle is a powerful tool designed for managing the release process of mobile applications to various app stores, including the Apple App Store, Google Play, and Huawei AppGallery. This module streamlines the complex process of app release, enabling users to:
- **Centralized Release Management**: Monitor, manage, and audit releases from a single platform, making the release process more efficient and organized.
- **Automate Releases**: Automate the submission of applications to multiple stores, reducing the manual workload and minimizing the risk of errors.
- **Flexibility in Publishing**: Appcircle provides the flexibility to publish your applications to various platforms, including app stores and internal app distribution systems. This ensures that your application reaches the right audience through the most suitable channels.
- **Isolation from Complex Interactions**: Eliminate the need for direct interaction with individual app stores like the App Store, Google Play Console, and Huawei AppGallery. Appcircle acts as a central hub, isolating you from the complexities and variances of each store’s submission processes.
By using the Publish to Stores module, you can ensure a smooth, reliable, and scalable release process for your mobile applications, enhancing the overall efficiency and effectiveness of your app release strategy.
https://appcircle.io/publish-to-stores
## Getting Started
The Publish to Stores module in Appcircle is a versatile tool that simplifies the app release process. To make the most of this module, it's important to ensure that you meet all prerequisites and properly configure the necessary settings. The following sections outline the initial steps to start a release process using the Publish to Stores module.
## Prerequisites for Using the Publish to Stores Module
Before you can start using the Publish to Stores module, there are several key prerequisites to address:
### Creating an App Store Connect API Key
The most important requirement before getting started is an Apple Developer account and an API key generated for that account. For detailed instructions on generating an App Store Connect API key, please refer to this section in our documentation as follows:
https://docs.appcircle.io/account/my-organization/security/credentials/adding-an-app-store-connect-api-key
:::caution App Store Connect Integration Permissions
Ensure that your developer accounts have the necessary permissions to publish apps, manage metadata, and access analytics. If you're part of a team, verify that you have the appropriate role within your developer account (Release Manager and above role).
Please visit the [**Apple App Store Connect Permission**](https://developer.apple.com/help/account/manage-your-team/roles/) documentation for more information.
:::
### Adding an App Store Connect API Key
For App Store Connect integration, go to Integrations under My Organization. Select the App Store Connect API Key from the Connections section. Fill in and save the information in the next screen.
- **Issuer ID**: Identifies the issuer who created the authentication token. Your issuer ID from the API Keys page in App Store Connect, for example, `57246542-96fe-1a63-e053-0824d011072a`
- **Key ID**: The .p8 file ID value.
- **.p8 File**: Generated API key file.
:::caution For .p8 File
**You can download the file only once**. If the file is lost, you need to generate a new key.
:::
For more information about the generating App Store Connect API key and App Store Connect integration in Appcircle, please refer to the [documentation](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key#login-to-app-store-connect).
### App Metadata and Binary Preperation
Before starting the release process, it's essential to prepare all necessary app metadata and binary files. This preparation ensures a smooth and efficient publishing experience.
:::info Binary
The binary file can be uploaded to the Publish to Stores module either manually, through the Build module, or through the Testing Distribution module. For more detailed instructions, please refer to the [**Upload Binary**](/publish-to-stores-module/publish-walkthrough-for-app-store#uploading-a-binary) section.
:::
- Gather all required metadata for your app for the targeted store(s), such as:
- App name
- Description
- Keywords
- App icons and screenshots
- Privacy policy URL
- Contact information
- Having this information prepared in advance will streamline the publishing process.
## Publish Setup Process
### Creating a Publish Profile
- Your Publish profile should be correctly set up within the Appcircle platform. This includes having a configured project with the necessary app builds (binary files) available for release. To set up a profile, click the **Add New** button on the top right.
:::tip Creating a Publish Profile
If you haven't create a Publish profile in Appcircle before, follow the detailed [**Creating a Publish profile guide**](/publish-to-stores-module/creating-publish-profiles) provided in the Appcircle documentation to ensure everything is ready for publishing.
:::
- There are two different ways to create a Publish Profile. One option is to create the profile manually, and the other is to retrieve an existing profile from App Store Connect. For detailed information please visit the [**Creating Publish Profile**](/publish-to-stores-module/creating-publish-profiles) documentation.
:::info Create from App Store Connect
To use this profile creation method, you must have an API key integration in place. Please refer to the detailed documentation for [**Create from App Store Connect**](/publish-to-stores-module/creating-publish-profiles#create-from-app-store-connect) and [**API integration**](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key).
:::
### Selecting an App Store API Key
Once the required integrations are set up, you can access these platforms from your profile within the Publish to Stores module. To initiate a release process, you need to select the credentials for the related store from the `Settings` screen under the Publish profile.
- All available integrations will be shown in the `Settings` screen.
### Updating App Store Connect Information
- Within the Publish to Stores module, you can update and review your app's information directly. This includes updating app name, subtitle, categories, and other store-related information such as privacy URLs, primary languages, etc. Please visit the [**App Store Connect Information**](/publish-to-stores-module/publish-information/app-information) documentation for detailed information.
### Updating TestFlight Beta Information
- Within the Publish to Stores module, you can update and review your **TestFlight Beta Information** directly. This includes editing the description, feedback email, beta app review details, and other store-related information such as privacy URLs, etc.
### Customizing the Publish Flow
Publish flow is used to automate multiple tasks and introduce automation checkpoints for application publishing to stores. You can create and manage flows within the Publish to Stores module as outlined below:
- **Update the Publish Flow**: Update the flow based on your needs in the `Publish Flow` section.
:::info
You can back up your current Publish flow by clicking the `Download YAML` button at the bottom. You can also upload your Publish flow as a YAML file using the `Replace Flow` button at the top right.
:::
- You can choose from predefined flows or create a custom flow based on your specific needs.
- **Configure Flow Steps**: Define each step of the flow, such as fetching app information, submitting to TestFlight, or updating metadata. Configure the settings for each step according to your requirements.
- **Save**: Once the flow is configured, you can save it for use in the publish process.
### Publish Flow Sample
The Publish to Stores module is designed to cater to a wide range of needs, making it suitable for both enterprise-level companies and individual developers. Here is an example of a custom flow you might create:
#### Beta Testing and Release Flow
With the Appcircle Publish to Stores module, you can manage your entire release process from scratch without needing to access the developer interfaces of the app stores. Below is an example flow that demonstrates how to manage a release process including testing from start to finish. The steps are utilized in the following order:
- [**App Information from App Store**](/publish-integrations/ios-publish-integrations/app-information-app-store): This step compares the Release Candidate version with the latest versions in both the TestFlight and Production environments, giving you an idea of how the release process will begin.
- [**Get Approval via Email**](/publish-integrations/common-publish-integrations/get-approval-via-email): After the version comparison is completed, an approval email is sent to the Release Manager to decide whether or not to proceed with the release process. This email informs the Release Manager about the release that is set to go to Beta Test. If the Release Manager sees no issues, they can click the Approve link within the email to move the process forward.
- [**Send to TestFlight**](/publish-integrations/ios-publish-integrations/sent-to-testflight): With this step, the binary is uploaded to TestFlight.
- [**Get Approval from TestFlight**](/publish-integrations/ios-publish-integrations/approval-test-flight): This step is presented with a UI that includes test information for the app you sent to TestFlight for beta testing. Here, you can either send the binary to a selected test group immediately or obtain approval from testers to confirm that the binary is issue-free. If the step succeeds under the selected conditions, it will proceed accordingly.
- [**Metadata Approval**](/publish-integrations/common-publish-integrations/metadata-approval): This step sends an approval email to the Release Manager before updating the metadata on App Store Connect. The Release Manager can click the approval link in the email to proceed. If there are no issues, they can approve the metadata. If there is a problem, they can reject it with an appropriate rejection message.
- [**Update Metadata on App Store Connect**](/publish-integrations/ios-publish-integrations/update-metadata-on-app-store-connect): This step will assist you in updating metadata. It comes with a custom UI that displays previews of the metadata to be uploaded, allowing you to update metadata in the app stores for this new release. With support for localization and screenshots, you can manage metadata updates without the need for direct access the app store listing management interfaces.
- [**Get Approval via Email**](/publish-integrations/common-publish-integrations/get-approval-via-email): After receiving approval from TestFlight and uploading the metadata, you can send an approval email to the Release Manager to review the Beta Test and the updated metadata. If everything is in order, the Release Manager can approve the process, allowing the flow to continue and submit the version for release.
- [**Submit for Review on App Store**](/publish-integrations/ios-publish-integrations/add-for-review-on-app-store): After receiving the final approval from the Release Manager, the binary file and the updated metadata are sent to the final step of the release process: app review. This step directly submits the version for review in the store.
### Setting Up Notifications
- Keeping your team informed about the release progress is essential for a coordinated effort. The Publish to Stores module can be integrated with collaboration tools like [**Slack**](/account/my-organization/notifications/slack-notifications) or [**Microsoft Teams**](/account/my-organization/notifications/teams-notifications) for notifications. By setting up these integrations, you can automatically send notifications about key events in the release process—such as successful publishing or issues that need attention—ensuring that everyone stays in the loop and can act swiftly when needed. Please visit the related [**Notifications Integration**](/account/my-organization/notifications) documentation for more detailed information.
## Managing Releases
Effective release management is crucial for ensuring the success of your app updates. The Publish to Stores module provides you with the tools to monitor, control, and optimize the release process. You can track the status of your releases in real-time, manage approvals, and address any issues that arise during the process. Also, the Publish to Stores module offers customizable flows to provide more detailed management of the release process.
Additionally, the module allows you to roll back to previous versions if needed, ensuring that you have full control over your app's distribution. By leveraging these features, you can maintain a smooth and efficient release cycle, minimizing disruptions and maximizing the impact of your updates.
### Uploading a Binary
Easily upload your binary file to the Publish to Stores module **manually**, via the **Build** or **Testing Distribution** modules, or through **Appcircle CLI and API** to begin the release process.
#### Manual Binary Upload
You can upload your binary file directly to the Publish to Stores module using the manual upload option.
#### Uploading via Build Module
You can deploy your binary file to the Publish to Stores module from the Build module automatically. This method automates the binary publish process, ensuring that your binary is transferred directly from the Build pipeline to the Publish to Stores module, ready for release. It simplifies the flows and reduces the risk of manual errors.
:::info Uploading via Build Module
To upload a binary from the Build module, please refer to the [**Distribution Configuration**](/build/build-process-management/configurations#distribution-configuration) and [**Post-Build Operations**](/build/build-process-management#binary-actions) documents for step-by-step instructions.
:::
#### Uploading via Testing Distribution Module
You can send your binary file to the Publish to Stores module from the Testing Distribution module.
:::info Uploading via Testing Distribution Module
To upload a binary from the Testing Distribution module, please refer to the [**Testing Distribution**](/testing-distribution/create-or-select-a-distribution-profile#send-your-application-to-publish) document for step-by-step instructions.
:::
#### Upload via Appcircle CLI & API
If you have your own CI environment, you can use the Appcircle API & CLI to upload binaries to the related publish Profile.
- **Other CI/CD Tools**: You can integrate the Publish to Stores module with continuous integration/continuous deployment (CI/CD) tools like Jenkins and GitHub Actions to automate your build and release pipeline. With the Appcircle [**API & CLI**](/appcircle-api-and-cli), you can seamlessly connect these tools, allowing for automated triggers that initiate a release as soon as a new build is ready. This integration ensures a consistent and efficient publish process, reducing manual intervention and the risk of errors. You can check out [**Appcircle Marketplace**](/marketplace) for more integrations.
To get more information, please refer to our [**API & CLI**](/appcircle-api-and-cli) documentation.
### Marking Binary as Release Candidate
- Designate the current build as the Release Candidate, signaling that it is ready for final testing and potential release. You can refer to the [**Marking as Release Candidate**](/publish-to-stores-module/publish-information/marking-release-candidates) document for detailed information.
### Updating Metadata
- Within the Publish to Stores module, you can manage your app's metadata directly. This includes updating app descriptions, keywords, and other store-related information. Please visit the [**Metadata Details**](/publish-to-stores-module/publish-information/meta-data-information) documentation for more information.
- Regularly review and update your app's metadata to ensure it is current and relevant, as outdated information can negatively impact your app's visibility and user experience.
- After updating your app's metadata, use the [**Metadata Approval**](/publish-integrations/common-publish-integrations/metadata-approval)
step to get approval before submitting the metadata to App Store Connect.
### Starting the Flow
- You can start the Publish flow manually by clicking on the `Publish Details` or you can run it to automate the entire publishing process. The flow will handle everything from submitting the binary to obtaining approvals and completing the release actions for the selected app stores.
### Managing Release Status
After initiating a release, the Publish to Stores module provides tools to monitor and manage the process:
#### Release Dashboard
View the status of your releases in real-time, including pending approvals, successful submissions, and any errors that occur.
#### Rollback Options
If needed, you can rollback to a previous version of your app or pause a release to address any issues. Appcircle provides [**Cancel Submission**](/publish-to-stores-module/publish-information/cancel-submission) and [**Reject Binary**](/publish-to-stores-module/publish-information/reject-binary) features. If a version faces an issue or the wrong binary was sent for release, you can reject the binary or cancel the current submission in Appcircle.
- You can cancel the submission on App Store Connect if the binary was sent for review.
#### Rejecting a Binary
- The binary can be rejected to be excluded from the publish process, and the rejection reason is displayed as a tag on binary
### Auditing Releases
The Publish to Stores module provides comprehensive auditing and reporting features that give you full visibility into your release process.
- **Activity Log**: The Activity Log keeps a detailed record of every action taken during the release process, including who performed each action and when it occurred. This log is invaluable for tracking changes, identifying issues, and ensuring accountability within your team.
## Publish to Stores module Troubleshooting
When using the Publish to Stores module, it's essential to know how to troubleshoot potential issues that may arise during the release process. Whether you're dealing with failed submissions, integration errors, or flow execution problems, having a clear understanding of common issues and their solutions can save you time and ensure a smooth release.
### Common Issues and Solutions
While the Publish to Stores module is designed for reliability, you may occasionally encounter issues due to various reasons. Here are some common problems and their solutions:
- **Failed Submissions**: Submissions can fail for various reasons. One common issue is a conflicting version number—if the version you're trying to submit already exists on the store, you'll need to increment the version number. Another issue could be an invalid binary, which might occur if the app doesn’t meet store requirements, have technical issues or if there are missing assets. Always check the error logs for specific details, correct any issues, and attempt the submission again.
- **Integration Errors**: Integration errors often stem from misconfigured store connections. If the API connection fails, it could be due to incorrect credentials or an expired API token. Additionally, ensure that the account you are using has the necessary permissions to perform actions like submitting apps or updating metadata. Double-check all API keys, tokens, and permissions to resolve these issues.
- **Flow Execution Problems**: If a flow doesn't execute as expected, it might be due to incorrect configuration settings. Review each step of the flow to ensure everything is set up correctly, such as conditions, triggers, and action sequences. If the problem persists, try testing the flow in a staging environment to isolate the issue before rerunning it in production.
### Frequently Asked Questions About the Publish to Stores module
#### How do I update my app's metadata?
To update your app's metadata, navigate to the Publish to Stores module, select the relevant profile, click the Actions button for the binary, and go to Metadata details. You can now update the metadata fields such as the app name, description, and screenshots. After saving your changes, submit the updated metadata for review if required.
#### How do I send my app's metadata for review before publishing?
If you would like to get email-based approval before publishing your app's metadata, you can add the [**Metadata
Approval**](/publish-integrations/common-publish-integrations/metadata-approval) step in your workflow. When this step runs in your workflow, Appcircle sends a unique approval email to the recipients defined in the step inputs where thet can view
the metadata details, approve or reject metadata, and provide
feedback in case of rejection.
#### Is it possible to automate notifications for team members during the release process?
Yes, it is possible. The Publish to Stores module allows you to set up automated notifications for your team members at various stages of the release process. You can configure notifications to be sent via email or integrate with collaboration tools like Slack or Microsoft Teams, ensuring that everyone involved is kept up to date on the release status.
For more information, please refer to the [**Notification Integrations**](/account/my-organization/notifications) document.
#### Can I track the progress of the app release in real-time?
Yes, the Publish to Stores module provides real-time tracking of the app release process. You can monitor each step of the flow, view the status of your submission, and receive notifications about any changes or issues. This feature allows you to stay informed and take action immediately if necessary.
#### What happens if a release is rejected by Apple?
If your binary is rejected by Apple in App Store Connect, the status on Appcircle will change to **Rejected**. You can view the binary's status directly from Appcircle without the need to visit App Store Connect. However, the rejection reasons are not shared with external parties through the App Store Connect APIs. To find out the specific reason for the rejection, you can view them on App Store Connect.
#### Can I use the Publish to Stores module with other CI tools?
Yes, you can use other CI tools to upload a binary to the Publish to Stores module. By utilizing Appcircle [**API & CLI**](/appcircle-api-and-cli) within your chosen CI tool, you can directly send the binary to the relevant profile and manage the Publish process.
Additionally, you can check our existing integrations in the [**Appcircle Marketplace**](/marketplace) documentation for integration alternatives for the **Appcircle API and CLI**.
#### Can I manage the team members roles for Publish to Stores module?
Appcircle provides users with a comprehensive role management system. This system allows you to assign specific permissions to all organization members on an organization-wide basis.
For more information, please refer to the [**Role Management**](/account/my-organization/profile-and-team/role-management) document.
#### Can I manage multiple app store accounts within the Publish to Stores module?
Yes, the Publish to Stores module allows you to manage multiple app store accounts within a single interface. You can set up and integrate different accounts, such as Apple App Store, Google Play, and Huawei AppGallery, and then select the appropriate account during the release process. This flexibility ensures that you can handle releases across multiple platforms efficiently.
#### How do I create a custom flow in the Publish to Stores module?
To create a custom flow, navigate to the Publish to Stores module and select the "Publish Flow" option. From there, you can choose and arrange the steps needed for your release process, configure each step according to your requirements, and save the flow for future use. Custom flow allows you to tailor the release process to fit your specific needs.
#### Why can't I edit the Publish Flow?
The Publish to Stores module is an **enterprise-level** solution, so only users with an **Appcircle Enterprise Licence** have access to all of its features. Users with other licences have limited access to the module. To get more information for Enterprise Licence please [**contact us**](https://appcircle.io/contact) directly.
#### How can I roll back to a previous version if needed?
If you need to roll back to a previous version, you can do so by selecting the desired version from your release history within the Publish to Stores module. This process involves re-uploading the previous binary and metadata, then executing a flow to re-release that version. Rolling back ensures that you can quickly address any issues with the current release without significant downtime.
### Further Support and Resources
If you need additional help with the Publish to Stores module, the following resources are available:
- **Technical Documentation**: Refer to the Appcircle user documentation for detailed guides and troubleshooting tips for the Publish to Stores module.
- **Commercial Details**: The Publish to Stores module is an **enterprise-level** solution; therefore, for commercial details, please [**contact us**](https://appcircle.io/contact) directly.
---
## Publish Walkthrough for Google Play Console
## Why Use the Publish to Stores module: Features and Benefits
The Publish to Stores module in Appcircle is a powerful tool designed for managing the release process of mobile applications to various app stores, including the Apple App Store, Google Play Console, and Huawei AppGallery. This module streamlines the complex process of app release, enabling users to:
- **Centralized Release Management**: Monitor, manage, and audit releases from a single platform, making the release process more efficient and organized.
- **Automate Releases**: Automate the submission of applications to multiple stores, reducing the manual workload and minimizing the risk of errors.
- **Flexibility in Publishing**: Appcircle provides the flexibility to publish your applications to various platforms, including app stores and internal app distribution systems. This ensures that your applications reaches the right audience through the most suitable channels.
- **Isolation from Complex Interactions**: Eliminate the need for direct interaction with individual app stores like the Apple App Store, Google Play Console, and Huawei AppGallery. Appcircle acts as a central hub, isolating you from the complexities and variances of each store’s submission processes.
By using the Publish to Stores module, you can ensure a smooth, reliable, and scalable release process for your mobile applications, enhancing the overall efficiency and effectiveness of your app release strategy.
https://appcircle.io/publish-to-stores
## Getting Started
The Publish to Stores module in Appcircle is a versatile tool that simplifies the app release process. To make the most of this module, it's important to ensure that you meet all prerequisites and properly configure the necessary settings. The following sections outline the initial steps to start a release process using the Publish to Stores module.
## Prerequisites for Using the Publish to Stores module
Before you can start using the Publish to Stores module, there are several key prerequisites to address:
### Creating and Adding a Google Play Developer API Key
The most important requirement before getting started is a Google Play Console account and an API key generated for that account.
For detailed instructions on generating a Google Play Console API key, please refer to the Appcircle documentation below:
- [**Creating and Adding a Google Play Developer API Key to Appcircle**](/account/my-organization/security/credentials/adding-google-play-service-account)
Once the Google API Key file is successfully integrated, you can proceed to the next step.
:::caution The JSON file is not recoverable
The Google API key JSON file can only be downloaded once and cannot be retrieved later from Google Play Console or Appcircle. **Make sure to store it securely right after downloading.**
:::
### Binary Preparation
Before starting the release process, make sure your AAB or APK binary is properly signed with the correct keystore. Proper signing is required for Google Play to accept the build and ensures a smooth publishing experience.
:::info Binary Upload Methods
The binary file can be uploaded to the Publish to Stores module either manually or through the Build or Testing Distribution modules. For more detailed instructions, please refer to the [**Upload Binary**](/publish-to-stores-module/publish-walkthrough-for-google-play#uploading-a-binary) section.
:::
## Publish Setup Process
### Creating a Publish Profile
- Your Publish profile should be correctly set up within the Appcircle platform. The package name defined in the Publish profile must exactly match the package name registered in your Google Play Console. To create a profile, click the **Add New** button on the top right.
:::tip Creating a Publish Profile
If you haven't create a Publish profile in Appcircle before, follow the detailed [**Creating a Publish profile guide**](/publish-to-stores-module/creating-publish-profiles) provided in the Appcircle documentation to ensure everything is ready for publishing.
:::
- There are two different ways to create a Publish profile. One option is to create the profile manually, and the other is to retrieve an existing profile from Google Play Console. For detailed information, please visit the [**Creating Publish Profile**](/publish-to-stores-module/creating-publish-profiles) documentation.
:::info Create from Google Play Console
To use this profile creation method, you must have a Google Play API key integration. And the package name defined in the Publish profile must exactly match the package name registered in your Google Play Console. Please refer to the detailed documentation for [**Create from Google Play Console**](/publish-to-stores-module/creating-publish-profiles#create-from-google-play-console) and [**API integration**](/account/my-organization/security/credentials/adding-google-play-service-account).
:::
### Selecting a Google Play Developer API Key
If you choose to create the profile manually, you must select the required Google Play Developer API key integration from your profile in the Publish to Stores module after the profile is created. To initiate the release process, select the credentials for the relevant store from the `Settings` screen under the selected Publish profile.
- All available integrations will be shown in the `Settings` screen. Here, you should select the Google Play Developer API key that you want to link to release your app.
### Updating Google Play Console App Information
- Within the Publish to Stores module, you can update and review your app's information directly. This includes updating email address, phone number, website URL, primary languages, and auto-send for review options. Please visit the [**Google Play Console Information**](/publish-to-stores-module/publish-information/google-play-information) documentation for detailed information.
### Customizing the Publish Flow
Publish flow is used to automate multiple tasks and introduce automation checkpoints for application deployments to stores. You can manage flow within the Publish to Stores module as outlined below:
- **Update the Publish Flow**: Update the flow based on your needs in the `Publish Flow` section.
:::info
You can back up your current Publish flow by clicking the `Download YAML` button at the bottom. You can also upload your Publish flow as a YAML file using the `Replace Flow` button at the top right.
:::
- You can choose predefined steps or create custom steps based on your specific needs.
You can drag and drop steps into your Publish flow. Any unwanted Publish flow steps can be removed or deactivated.
You can also reorder steps so that they will be executed in the order you specify.
- **Configure Flow Steps**: Fill in all required inputs for each step in the flow with the necessary information according to your requirements.
- **Save**: Once the flow is configured, you can save it for use in the deployment process.
### Publish Flow Sample
Here is a sample Publish flow for an Android app, including track selection and deployment steps.
- [**Custom Script**](/publish-integrations/common-publish-integrations/custom-script): You can use the Custom Script steps to add extra functionalities in your Publish flow. Appcircle will execute the commands specified in your custom scripts, allowing you to perform custom actions. These scripts will run on the runner, giving you access to all the capabilities of the Publish environment.
- [**Get Approval via Email**](/publish-integrations/common-publish-integrations/get-approval-via-email): The Get Approval via Email step allows you to get approval from the email addresses entered as input in the step before moving on to the next steps in Publish.
- [**Send to Google Play**](/publish-integrations/android-publish-integrations/publish-to-google-play): With this step, the binary is uploaded to the desired Google Play Console Track.
You can select one of the following options:
- Internal track
- Alpha track
- Beta track
- Production track
- Custom track (a user-defined track for specific testing or release scenarios outside the standard tracks)
- [**The Distribute to Track**](/publish-integrations/android-publish-integrations/distribute-to-track): This step enables automated deployment of Android applications to specific tracks within the Google Play Console. This functionality allows developers to manage releases efficiently, targeting different user groups such as internal testers, beta users, or the general public.
- [**App Information from Google Play**](/publish-integrations/android-publish-integrations/app-information-from-google-play): The App Information from Google Play step checks the status of the app releases in the Google Play Console. This allows you to monitor the progress of your app.
### Setting Up Notifications
- Keeping your team informed about the release progress is essential for a coordinated effort. The Publish to Stores module can be integrated with collaboration tools like [**Slack**](/account/my-organization/notifications/slack-notifications) or [**Microsoft Teams**](/account/my-organization/notifications/teams-notifications) for notifications. By setting up these integrations, you can automatically send notifications about key events in the release process—such as successful deployments or issues that need attention—ensuring that everyone stays in the loop and can act swiftly when needed. Please visit the related [**Notifications Integration**](/account/my-organization/notifications) documentation for more detailed information.
## Managing Releases
Effective release management is crucial for ensuring the success of your app updates. The Publish to Stores module provides you with the tools to monitor, control, and optimize the release process. You can track the status of your releases in real time, manage approvals, and address any issues that arise during the process. Also, the Publish to Stores module offers customizable flow to provide more detailed management of the release process.
### Uploading a Binary
Easily upload your binary file to the Publish to Stores module **manually**, via the **Build** or **Testing Distribution** modules, or through **Appcircle CLI and API** to begin the release process.
#### Manual Binary Upload
You can upload your binary file directly to the Publish to Stores module using the manual upload option.
#### Upload via Build Module
You can automatically deploy your binary file to the Publish to Stores module directly from the Build module. This method streamlines the binary deployment process by transferring your binary immediately after the build pipeline completes, making it ready for release. It simplifies the flow and reduces the risk of manual errors.
:::info Upload via Build Module
To upload a binary from the Build module, please refer to the [**Distribution Configuration**](/build/build-process-management/configurations#distribution-configuration) document for auto upload or the [**Post-Build Operations**](/build/build-process-management#binary-actions) document for manual upload.
:::
#### Upload via Testing Distribution
You can send your application from a testing distribution profile to a designated Publish profile. For detailed steps, see the [**Upload via Testing Distribution**](/testing-distribution/create-or-select-a-distribution-profile#send-your-application-to-publish) documentation.
#### Upload via Appcircle CLI & API
If you have your own CI environment or need to integrate Appcircle into a specific process or job, you can use the Appcircle API & CLI to upload binaries to the related Publish profile.
- **Other CI/CD Tools**: You can integrate the Publish to Stores module with CI/CD tools like Jenkins and GitHub Actions to automate your build and release pipeline. With the Appcircle [**API & CLI**](/appcircle-api-and-cli), you can seamlessly connect these tools, allowing for automated triggers that initiate a release as soon as a new build is ready. This integration ensures a consistent and efficient deployment process, reducing manual intervention and the risk of errors. You can check out [**Appcircle Marketplace**](/marketplace) for more integrations.
To get more information, please refer to our [**API & CLI**](/appcircle-api-and-cli) documentation.
### Marking Binary as Release Candidate
- Designate the current build as the Release Candidate, signaling that it is ready for potential release. You can refer to the [**Marking as Release Candidate**](/publish-to-stores-module/publish-information/marking-release-candidates) document for detailed information.
### Updating Metadata
- Within the Publish to Stores module, you can directly manage your app’s metadata. This includes editing the screenshots, video, app name, and descriptions. Please visit the [**Metadata Details**](/publish-to-stores-module/publish-information/meta-data-information#android-metadata-information) documentation for more information.
- Regularly review and update your app's metadata to ensure it is current and relevant, as outdated information can negatively impact your app's visibility and user experience.
### Starting the Flow
- You can start the Publish flow manually by clicking on the `Publish Details` or you can run it to automate the entire publishing process. The flow will handle everything from submitting the binary to obtaining approvals and completing the release actions for the Google Play Console.
### Managing Release Status
After initiating a release, the Publish to Stores module provides tools to monitor and manage the process.
#### Release Dashboard
View the real time status of your release.
#### Rejecting a Binary
- The binary can be rejected to be excluded from the publish process, and the rejection reason is displayed as a tag on the binary.
### Auditing Releases
The Publish to Stores module provides comprehensive auditing and reporting features that give you full visibility into your release process.
- **Activity Log**: The activity log keeps a detailed record of every action taken during the release process, including who performed each action and when it occurred. This log is invaluable for tracking changes, identifying issues, and ensuring accountability within your team.
## Publish to Stores module Troubleshooting
When using the Publish to Stores module, it's essential to know how to troubleshoot potential issues that may arise during the release process. Whether you're dealing with failed submissions, integration errors, or flow execution problems, having a clear understanding of common issues and their solutions can save you time and ensure a smooth release.
### Frequently Asked Questions About the Publish to Stores module
#### What happens if I upload an APK/AAB signed with a different keystore?
Google Play rejects the upload with an error like
"Upload failed. You uploaded an APK or Android App Bundle that is signed with a different certificate."
If you’ve lost your original keystore and Play App Signing is enabled, you can request a new upload key. Otherwise, you must use the original keystore or publish the app under a new package name.
For more information, please refer to the [**What to do if I lost my key store**](/signing-identities/android-keystores#what-to-do-if-i-lost-my-keystore-signing-file) document.
#### Can I re-sign an Android binary with a different keystore?
Yes. The Resign Binary step allows you to re-sign your APK or AAB using a different keystore. This is useful when distributing the same build under a different signing identity. Make sure to use a trusted and correct keystore when re-signing your binary. The Publish to Stores module fully supports Android binary re-signing.
:::caution
Re-signing an Android binary with a different keystore may cause installation or update issues. Android does not allow an app signed with one keystore file to be updated with another. If a different keystore is used incorrectly, the application may fail to install or update, and you may encounter a "Package not found" error. Also, changing the signing key is not allowed on Google Play Console after the first release, unless you're using Play App Signing with an approved key change process.
:::
For more information, please refer to the [**Resign binary**](/publish-to-stores-module/publish-information/resign-binary) document.
#### How to distribute an Android app to different release tracks (Alpha, Beta, Production, etc.) on Google Play?
By configuring the `Distribute to track` step, you can upload your application to a specific track such as Internal, Alpha, Beta, or Production. This enables you to manage multiple release flows and target different user groups within the same pipeline.
For more information, please refer to the [**Distribute to Track**](/publish-integrations/android-publish-integrations/distribute-to-track) document.
#### How can I control the rollout percentage when distributing to a Google Play track?
In the `Distribute to track` step, if you set `AC_RELEASE_STATUS` to partial, a rollout percentage slider becomes available. Use it to define what percentage of users should receive the update initially (e.g., 10%). This lets you perform phased rollouts and monitor stability before doing a full release.
:::warning
Keep in mind that, once a rollout has started, the percentage can only be increased. It cannot be reduced. If you need to stop the release, you must halt the rollout entirely and upload a new release.
:::
#### How do I update my app's metadata?
To update your app's metadata, navigate to the Publish to Stores module, select the relevant profile, click the `Actions` button for the binary, and go to `Metadata details`. You can now update the metadata fields, such as the app name, description, and screenshots. After saving your changes, submit the updated metadata for review if required.
:::caution
You must also complete the metadata submission process on Google Play Console to ensure the changes take effect.
For more details, refer to the [**Update Metadata on Google Play Console**](/publish-integrations/android-publish-integrations/update-metadata-on-google-play).
:::
#### Is it possible to automate notifications for team members during the release process?
Yes, it is possible. The Publish to Stores module allows you to set up automated notifications for your team members at various stages of the release process. You can configure notifications to be sent via email or integrate with collaboration tools like `Slack` or `Microsoft Teams`, ensuring that everyone involved is kept up to date on the release status.
For more information, please refer to the [**Notification Integrations**](/account/my-organization/notifications) document.
#### Can I use the Publish to Stores module with other CI tools?
Yes, you can use other CI tools to upload a binary to the Publish to Stores module. By utilizing Appcircle [**API & CLI**](/appcircle-api-and-cli) within your chosen CI tool, you can directly send the binary to the relevant profile and manage the publish process.
Additionally, you can check our existing integrations in the [**Appcircle Marketplace**](/marketplace) documentation for integration alternatives for the **Appcircle API and CLI**.
#### Can I manage team member roles for the Publish to Stores module?
Appcircle provides users with a comprehensive role management system. This system allows you to assign specific permissions to all organization members on an organization-wide basis.
For more information, please refer to the [**Role Management**](/account/my-organization/profile-and-team/role-management) document.
#### Can I manage multiple Play Store accounts within the Publish to Stores module?
Yes, the Publish to Stores module allows you to manage multiple Play Store accounts within a single interface. You can set up and integrate different accounts, such as Apple App Store, Google Play, and Huawei AppGallery, and then select the appropriate account during the release process. This flexibility ensures that you can handle releases across multiple platforms efficiently.
#### How do I customize my Publish flow in the Publish to Stores module?
To customize a flow (available only with an **enterprise plan**), navigate to the Publish to Stores module and select the "Publish Flow" option. From there, you can choose and arrange the steps needed for your release process, configure each step according to your requirements, and save the flow for future use. Custom flow allows you to tailor the release process to fit your specific needs.
#### Why can't I edit the Publish Flow?
The Publish to Stores module is an **enterprise-level** solution, so only users with an **Appcircle Enterprise License** have access to all of its features. Users with other licenses have limited access to the module. To get more information about the Enterprise License, please [**contact us**](https://appcircle.io/contact) directly.
#### How can I roll back to a previous version if needed?
Google Play does not support directly rolling back to a previously published version. However, you can functionally roll back by re-releasing the previous binary using a higher `version code`.
To do this in Appcircle, go to the Publish to Stores module, select the previous version from your release history, and `Resign` the binary that you want to re-release.
For more information, please refer to the [**Resign binary**](/publish-to-stores-module/publish-information/resign-binary).
:::warning
Make sure to increment the `version code`; otherwise, Google Play will reject the upload.
:::
### Further Support and Resources
If you need additional help with the Publish to Stores module, the following resources are available:
- **Technical Documentation**: Refer to the Appcircle user documentation for detailed guides and troubleshooting tips for the Publish to Stores module.
- **Commercial Details**: The Publish to Stores module is an **enterprise-level** solution; therefore, for commercial details, please [**contact us**](https://appcircle.io/contact) directly.
---
## Latest Release Notes
# Latest Release Notes
## 3.29.9 - 2026-02-26 Binary Re-sign Support for Enterprise App Store, Account Page Improvements, Bug Fixes and more
### 🆕 New Features
- The Manual and Auto Binary [Re-sign](/enterprise-app-store/resign-binary) feature has been introduced for the Enterprise App Store module, enabling binaries to be re-signed similarly to the Publish and Testing Distribution modules.
- Support for regex-based trigger conditions has been added to enable more flexible matching while evaluating performance and impact on existing configurations.
### :muscle: Improvements
- Metadata fields containing user-defined `$ENV` values will no longer be overwritten by backend data when the Retrieve from Last Updated action is performed.
- The visibility of multi-line tooltip texts has been improved.
- The user authentication method, such as Password or SSO, will now be displayed on the Account page.
- The Team Activity Log section has been renamed to Organization Activity.
- Users authenticated via SSO or LDAP can no longer change their passwords on the Account page, and password updates must be performed by logging out and signing in again using standard password authentication.
- New actions have been added to the Signing Identity configurations for Notification channels, including Email and MS Teams.
- Organization PAT create and revoke actions will now be displayed in the Team Activity Log.
- The File Name column will now display the actual file name instead of the Keystore Alias in the Android Keystore lists.
- File types will now be displayed as `APK`,`AAB` and `IPA` on the app version list within the Enterprise App Store profiles.
- After downloading an app, the Testing Portal will now redirect users back to the app version list.
- Exception and error messages have been improved throughout Appcircle modules for better clarity.
- Updates, deletions, and additions of Build Triggers will now be displayed in the Notification Center.
- The clean parameter in the archive command within the Xcodebuild for Devices step has been made optional. This will prevent already built frameworks from being rebuilt.
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest stable release of the [Xcode 26.3](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_3-release-notes) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
### 🐞 Fixes
- Several UI issues affecting viewer role users that caused inconsistent behavior have been fixed.
- An issue causing Keystore uploads to fail when the key alias contained non-ASCII characters has been fixed.
- An issue has been fixed where Publish Metadata Details did not accept the version number as a Publish Variable (`$AC_PUBLISH_APP_VERSION`).
- An issue has been fixed where the auto re-sign operation did not start for publish profiles with disabled publish flow steps.
- An issue has been fixed where the “App Information From App Store” Publish flow step caused an error while checking the App Store connection status.
- An issue has been fixed where Fortify-related validation rules could fail when incompatible data was provided by some organizations. Validation criteria have been improved to ensure more reliable processing.
- An issue has been fixed where setting the build status could return a 404 error for Bitbucket self-hosted repositories due to endpoint validation problems.
- An issue has been fixed where the QR code was not displayed on the LDAP 2FA login screen in the Testing Portal.
### :warning: Breaking Changes
- AAB files can no longer be published to Beta or Live channels within the Enterprise App Store profiles.
- The automatic background conversion of uploaded AAB files to APK using Android keystore has been removed from Enterprise App Store module. Users can use 'Convert AAB to APK' toggle within the Auto Re-sign configurations.
- Access to both iOS and Android Publish roles is now required to send a binary to the Publish module from other modules such as Enterprise App Store and Testing Distribution.
- Manual Re-sign operations now use the same configuration structure as Auto Re-signs across Appcircle modules, and Entitlements are no longer supported.
- Microsoft is retiring Office 365 Connectors, including the Incoming Webhook integration used by Microsoft Teams. The migration deadline has been extended, and organizations must transition to the new [workflow-based](/account/my-organization/notifications/teams-notifications#connecting-microsoft-teams-via-workflows) webhook model by April 30, 2026 to avoid service disruption. If you are using the Incoming Webhook integration in Appcircle, we strongly recommend migrating to the new workflow-based webhook connection method as soon as possible.
## 3.29.8 - 2026-01-21 Single Active Session, Metadata Details Update, Bug Fixes and more
### 🆕 New Features
- The Single Active Session feature has been introduced for [Enterprise App Store](/enterprise-app-store/portal-settings#session-management) and [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile#single-active-session) modules. This restricts users to one active session across browsers and devices by terminating previous sessions on a new login, supporting SSO, Static, and LDAP authentication types.
- [KOBIL AppShield Scanner](/workflows/common-workflow-steps/kobil-appshield-scanner) component has been added and can be used by Appcircle users without creating a KOBIL account, providing dynamic analysis to detect security mechanisms in mobile apps.
- The Custom Script from Git component is now available in Publish flows, enabling you to execute scripts directly from your Git repositories. This enhancement improves script reusability and manageability across your publish flows.
### :muscle: Improvements
- Performance improvements have been made to the Team Management UI.
- The [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile#settings) and [Enterprise App Store](/enterprise-app-store/enterprise-app-store-profile#profile-settings) profile settings have been reworked, and some settings have been moved to a different tab to improve consistency. Refer to the related documentation to see the latest state.
- If the Notification Center is closed, it will now open when toast messages are clicked.
- A notification will now be displayed in the Notification Center when a new user is invited to the organization.
- Metadata Approval step name has been changed to Metadata Approval via Email.
- Publish module now supports Custom Script execution with Node.js and Python runtimes, enabling script reuse and more advanced automation during the Publish phase.
- Cache Push and Cache Pull steps now generate and restore cache per build profile by default instead of per branch, improving cache reuse and reducing fragmentation; [documentation](/workflows/common-workflow-steps/build-cache/how-to-configure-branch-based-caching) has been added for users who want to continue using branch-based caching.
- The React version used in the UI and its dependencies have been upgraded to ensure improved performance, enhanced security, and better overall stability.
- CDN support has been implemented to enhance the stability and performance of CodePush package distribution.
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest Beta release of the [Xcode 26.3 RC1](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_3-release-notes) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
### 🐞 Fixes
- An issue has been fixed where SAML-type SSO configurations were appearing in OpenID SSO configurations in the “Create from existing SSO configuration” option.
- An issue has been fixed where the notification service could throw an error when users clicked the Manage button in self-hosted admin settings while configuring SMTP settings.
- An issue has been fixed where Enterprise Portal binary tag entries were accepting manual text input.
- An issue has been fixed where quotation marks caused errors during the Send to TestFlight publish step in the release notes section.
- An issue has been fixed where the “Manually release this version” option selected in the Metadata Details section was not being updated correctly when the flow was executed with Update Metadata.
- An issue has been fixed where certain environment variables were not consistently populated for user-triggered builds, despite being expected to be available across all trigger types.
- An issue has been fixed where incorrect field labels in the Bitbucket API token configuration for self-hosted environments to improve clarity and reduce user confusion during setup.
- An issue has been fixed where some users received Bad Request errors during binary downloads on the Testing Portal.
- An issue has been fixed where deleting app versions with the same bundle or package IDs negatively affected delete operations across different testing distribution profiles.
- An issue has been fixed where users with a large number of app versions in Testing Distribution experienced errors when deleting apps.
### :warning: Breaking Changes
- Partial saving for App Store Metadata Details is no longer supported. Users must now provide all required fields before submission, as the previous preparation and incremental completion workflow has been removed. All mandatory information will be requested at the time of submission, and submissions cannot be completed progressively.
## 3.29.7 - 2025-12-17 BitBucket API Token Support, Publish Improvements, Bug Fixes and more
### :muscle: Improvements
- A new expiry date can now be selected when rotating active or expired API keys.
- The Connection Pooling option will now be available in the LDAP creation settings instead of being limited to the edit screen.
- Uploaded binaries in Publish profiles will now appear in the Publish report with a Not Started status, which will be updated when an active publish flow begins.
- The Appcircle Publish module now automatically parses multi-language release notes and submits them to Google Play Console as separate localized entries for each [supported language](https://support.google.com/googleplay/android-developer/table/4419860?hl=en). Language formatted release notes can be provided via Build module or manual entry in [Binary Information](/publish-to-stores-module/publish-information/binary-information). For more information please check [Best Practices for Release Notes](/publish-to-stores-module/publish-information/binary-information#best-practices-for-release-notes) documentation.
- Active and registered provisioning profiles uploaded to Appcircle can now be selected instead of being automatically retrieved from the store for Auto Re-sign configurations of Testing Distribution profiles.
- The Duration (minutes) column in reports will now be displayed as Xm Xs instead of Xm.x. For example 10m 30s instead of 10.5.
- Provisioning profile validation is now performed using the App Store UUID instead of the profile name, and profile replacement is intentionally not supported to prevent potential data loss.
- The [Appcircle macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest GA release of the [Xcode 26.2](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_2-release-notes) (`17C52`) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
- A new macOS-based build stack (Sequoia `15.6.1`) is released for the self-hosted Appcircle environments, which has the latest GA release of [Xcode 26.2](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_2-release-notes) (`26.2` `17C52`) installed along with Xcode 16.4-26.1.1 versions. Follow the [setup guide](/self-hosted-appcircle/self-hosted-runner/runner-vm-setup#download-macos-vm) for installation instructions.
### 🐞 Fixes
- An issue was fixed where adding a branch to a remote repository caused UI issues with configuration and trigger counts during branch addition to an Appcircle build profile.
- An issue was fixed where Git tags were not pushed alongside commits, ensuring tags are now included when pushing multiple local operations together.
- An issue was fixed where tag-based build triggers did not run when tags were created on older existing branches.
- An issue was fixed where deleting an SSO configuration for Testing Distribution caused UI inconsistencies that left it appearing active on the screen.
- An issue has been fixed where EAS and Tester Distribution Portal UIs ignored the OTP server’s configured expiration time and always displayed a hardcoded 5-minute countdown, ensuring the UI now respects server-defined expiry with appropriate tolerance.
- An issue was fixed where certain version numbers were sorted incorrectly on the Enterprise Portal.
- An issue was fixed where removing binaries from a Testing Distribution profile still left the latest version number displayed on the profile card.
- An issue was fixed where some users were unable to switch between Testing Distribution profiles within the Testing Portal.
- An issue was fixed where binaries with foreign character names were displayed incorrectly in the Publish module.
- An issue has been fixed where some users encountered a JSON parsing error when sending newly created applications marked as RC to Intune using the “Create a new app” option.
- An issue has been fixed where an incorrect validation error for the Short Description length was displayed after retrieving metadata from Google Play Console, even when the character limit was not exceeded.
- An issue has been fixed where adding new devices for development provisioning failed due to an error returned by Apple, preventing devices from being added successfully.
- An issue was fixed where some build profiles were missing from the profile filter list on the Build activity log screen for certain date ranges.
### :warning: Breaking Changes
- Support for [Bitbucket API tokens](/build/manage-the-connections/connection-guides/connecting-to-bitbucket#api-token-permissions-for-bitbucket-cloud-integration) is being introduced to replace app passwords, with connection updates provided ahead of the June 9, 2026 deprecation deadline for existing app passwords.
- Partial draft saving for Google Play metadata information has been removed, and all required fields must now be completed before submission.
- Email Approval Publish step now requires the logged-in account email to match the approval email, preventing copied approval links from being used by different users.
- A [pool selection](/publish-to-stores-module/publish-information/auto-resign-configuration#select-a-pool) option has been added to auto re-sign configurations for Testing Distribution and Publish modules. This setting must now be configured to use the auto re-sign feature.
## 3.29.6 - 2025-11-14 Testing Distribution Improvements, Bug Fixes and more
### :muscle: Improvements
- A confirmation prompt was added for deleting testing group users.
- The organization filter option in testing distribution reports is now displayed in alphabetical order.
- The automatically generated TestFlight external public link is now displayed directly in the Appcircle UI whenever a new external test is created.
- The maximum size limit for Release Notes has been increased from 4,000 to 25,000 characters to fully support all Google Play languages and their per-language character limits.
- An informative tooltip is now displayed when users hover over the Start Build button without selecting a branch.
- A warning is now shown when existing SSO settings are reused, informing users that the JSON file is pre-filled and allowing them to modify it if needed.
- Validation check has been added to the host field in self-hosted SMTP settings.
- Users with the Build Environment Group Viewer role can no longer upload environment variables via JSON file. Additionally, users with the Publish Environment Group Viewer role can now download environment variables for the Publish module.
- A warning is now displayed in the UI when users enter a duplicated variable name.
- The Environment Variable Export action is now displayed in the Build Activity Log for better traceability.
- Enterprise App Store customization has been improved to provide better transparency for portal logo blending with the selected background color.
- The [Appcircle macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest GA release of the [Xcode 26.1.1](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_1-release-notes) (`17B100`) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
- A new macOS-based build stack (Sequoia `15.6.1`) is released for the self-hosted Appcircle environments, which has the latest GA release of [Xcode 26.1](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_1-release-notes) (`26.1.1` `17B100`) installed along with Xcode 16.4-26.0.1 versions. Follow the [setup guide](/self-hosted-appcircle/self-hosted-runner/runner-vm-setup#download-macos-vm) for installation instructions.
### 🐞 Fixes
- Workflow editor save failures that occurred when the editor was left open for extended periods were fixed, and session state is now properly handled to prevent errors.
- An issue was fixed with the build profile search filters, where accurate results were not being returned.
- An issue was fixed in which completing a build for a branch located at the end of the branch list resulted in no branch being selected after the build was completed.
- An issue was fixed where refreshing the branch list resulted in duplicated progress icons being displayed.
- An issue was fixed where a selected provisioning profile could be chosen again when many profiles were available. The selected provision is now excluded from subsequent selection lists.
- An issue was fixed where the build timer stopped when workflow steps did not produce logs for an extended period.
- An issue was fixed where removing a saved tag in Build Settings did not re-enable the Save button.
- Overall typos, URL issues, and text errors were fixed in the signing identity module.
- An issue was fixed in which the Apple device filter malfunctioned when only one device was registered.
- An issue was fixed where some events in the signing identity module did not generate notification messages.
- An issue was fixed where the copy button did not work for the Profile ID option in the publish settings.
- An issue was fixed where notification channels, such as email, displayed an incorrect version when a binary was uploaded while a Release Candidate binary was present in the Publish profile.
- An issue was fixed in which the profile icon update screen for the Enterprise App Store profile did not display the active icon.
- An issue was fixed in which background colors of the Enterprise Portal affected transparent logos.
- Multiple bugs in the team management combobox component were fixed, including the size shrinking issue, improper filtering behavior. The combobox filtering option is now removed for sub-organizations.
- An issue was fixed where users with the Viewer Organization Management role received incorrect access denied errors when viewing the team member list.
- An issue was fixed where Publish notification emails displayed the previous version number instead of the currently published version.
- An issue was fixed where testing group CSV imports incorrectly displayed duplicated values as imported.
- Minor fixes and improves were applied for profile search was improved in the testing distribution module.
- An issue was fixed where source profiles were not displayed in the app version reports.
- An issue was fixed where the total message count was incorrect in the app sharing reports.
## 3.29.5 - 2025-10-27 New Retention Period Settings, Activity Log Improvements, Bug Fixes and more
### 🆕 New Features
- The new [Artifact Report](/account/my-organization/artifacts/retention-period#artifacts-reports) has been introduced, allowing users to monitor deletion operations, including manual artifact deletions and automatic system retention deletions, with filtering capabilities.
### :muscle: Improvements
- The [Appcircle macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest GA release of the [Xcode 26](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_0_1-release-notes) (`26.0.1` `17A400`) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
- A new macOS-based build stack (Sequoia 15.6.1) is released for the self-hosted Appcircle environments, which has the latest GA release of [Xcode 26](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_0_1-release-notes) (`26.0.1` `17A400`) installed along with Xcode 16.x versions and up-to-date [build tools](/infrastructure/ios-build-infrastructure#ios-build-environment) for iOS and Android builds. Follow the [setup guide](/self-hosted-appcircle/self-hosted-runner/runner-vm-setup#download-macos-vm) for installation instructions.
- A warning is now displayed in the testing group creation input area when a duplicate email address is entered.
- CodePush activities are now displayed in the Build Activity Log.
- Overall UI and stability improvements have been made to the Account page.
- Re-sign notifications are now displayed under the corresponding module’s notifications.
- The Publish module has been renamed to Publish to Stores.
- The workflow editor UX was improved: Delete icons now provide proper cursor feedback and hover states, making it clearer which elements are draggable versus deletable.
- The URL structure now includes the organization ID. Users who have access to multiple organizations can directly switch to another organization and access shared resources (profiles, modules, etc.) via shared links. If they don’t have permission for the target organization, they’ll receive a permission error. When the organization ID is not present in the URL, users will automatically access the corresponding resource within their own organization.
- A warning message has been added to the rollback option in the CodePush interface.
### 🐞 Fixes
- An issue causing display problems with live publish flow logs in some Edge browsers was fixed.
- An issue has been fixed where the start date was not displayed correctly at the beginning of the re-sign process but appeared properly after completion.
- An issue was fixed where the upload screen remained stuck in the uploading state when a user attempted to upload an existing binary on the Publish profile.
- An issue was fixed where foreign characters in binary names were displayed as URL-encoded text on the Publish flow screen.
- An issue was fixed where binaries sent to Intune included the data flow expiration date instead of the provisioning profile expiration date.
- An issue was fixed where clicking the status of a published binary displayed broken text in certain scenarios.
- An issue was fixed where marking a binary as RC through the publish flow screen did not display the app selection pop-up for Microsoft Intune–connected profiles.
- An issue has been fixed where publish results for some app versions were incorrectly reflected in the Publish Report.
- An issue has been fixed where starting a publish flow after marking another app version as a Release Candidate did not reflect updated changes.
- An issue was fixed where application binaries uploaded to Microsoft Intune appeared successful in Appcircle but did not show up in the Intune portal.
- An issue has been fixed where build profile configurations required a branch to be selected for access.
- An issue has been fixed where sub-organization builds were incorrectly displayed in the root organization's dashboard.
- An issue has been fixed where build profiles using the Azure DevOps OAuth connection failed to connect and could not be updated with an alternative connection.
- An issue has been fixed where long repository names caused UI issues during repository selection when connecting a build profile.
- An issue has been fixed where users with insufficient OAuth Azure permissions were blocked from changing or disconnecting the repository connection in the UI.
- An issue has been fixed where the build status for some profile branches was getting stuck in the running state.
- An issue has been fixed where CodePush app name validation allowed names shorter than three characters, as well as special characters and spaces.
- An issue was fixed where the Save button in the Versioning tab of Build Profile configurations appeared active without any changes being made on Edge browsers.
- An issue was fixed where receiving an event message caused the branch list to refresh on Build profiles.
- An issue was fixed where the Auto Code Signing tab’s certificate list did not display expired tags in build configurations.
- An issue was fixed where the existing GitLab webhook was deleted and recreated each time the Refetch action was triggered.
- An issue has been fixed where some users experienced freezing when deleting an .APK binary from their testing distribution profile.
- An issue has been fixed where some users were unable to switch Android app versions within the Testing Distribution profile.
- An issue has been fixed where some app versions were displayed as unsigned in the Testing Distribution profile despite being signed.
- An issue has been fixed where long passwords caused login failures on the Enterprise Portal.
- An issue has been fixed where multiple notifications appeared in various areas of Appcircle.
- An issue has been fixed where some users were unintentionally navigated back to a previously used section after switching browser tabs.
- An issue has been fixed where some users received notifications from other sub-organizations.
- An issue has been fixed where users experienced incorrect navigation when switching between Appcircle authentication types.
- An issue was fixed where the Shared Credential setting displayed a sub-organization list for root organizations that did not have any sub-organizations.
- An issue was fixed where the Microsoft Intune credential settings did not display a help documentation link button.
- An issue was fixed where navigating to the dashboard from another module caused an incorrect title to appear on the browser tab.
- An issue was fixed where selecting the in-between time filter option caused UI issues when the user attempted to select another type of filter on report pages.
- An issue was fixed where successful Microsoft Intune flow steps displayed incorrect API errors after the publish flow was completed.
- An issue was fixed where clicking the full-size button on the custom script screen did not fully expand the view.
- An issue was fixed where landscape-oriented images could not be added when uploading screenshots in the iOS Metadata screen.
- An issue was fixed where users could not view both organization and sub-organization data by default in the Publish Report without applying filters.
- An issue was fixed where the “Package Identifier Validation for Android” feature was incorrectly applied to iOS apps as well. The validation is now properly isolated and only affects Android apps.
- An issue was fixed where special characters in app names were replaced with URL-encoded values after refreshing the page in the Publish flow.
## 3.29.4 - 2025-09-26 Build Activity Log, Report Improvements, Bug Fixes and more
### 🆕 New Features
- Introducing [Build Activity Log](/build/build-activity-log) – Actions such as creating, deleting, and adding Build profiles or updating configurations performed in your Organization or Sub-Organizations can now be viewed in the Build Activity Log section.
- Added a new [Check Network Access component](/workflows/common-workflow-steps/check-network-access) to the Build Module to validate connectivity to common endpoints and custom URLs, ensuring early detection of network issues during workflows.
- Publish flows can now be initiated with a single click using the new Start Publish Process button located next to the action list button for each app version.
### :muscle: Improvements
- All organization owners will now receive an email notification when a [Domain Verification](/account/my-organization/security/domain-verification) status is changed.
- Improvements were made to the [In-app Notifications](/account/my-account/in-app-notifications) to display and store system-related errors across Appcircle.
- Users can now navigate to a specific module via a shared URL using their SSO Alias when accessing organizations with SSO authorization. The shared URL will need manual editing as shown in the example: `my.appcircle.io/sso/ssoAlias?redirectURL=...`
- Personal API Tokens have been renamed to [Personal Access Keys](/account/my-organization/security/personal-access-key). Refer to the [API documentation](/appcircle-api-and-cli/api-authentication) for the latest supported endpoints and models.
- The [Machine Plan](/infrastructure/machine-plans) of the organization will now be displayed in the Build logs.
- Improvements were made to the branch search functionality within Build profiles.
- Overall API optimizations were made to improve the performance of all endpoints.
- Re-signed app versions will now display a Re-Sign label for easier identification within the Testing Portal.
- A password visibility toggle has been added to the Testing Portal login screen for Static and LDAP authentication types.
- The Upload Binary button for Testing Distribution profiles is now located at the top-right corner, consistent with other modules.
- Non-existing provisioning profiles used in the auto re-sign process (auto-downloaded or generated) in Publish module, will now be added to the Signing Identity module.
- UI improvements were made to the Publish module, including updated action icons, settings, and upload binary buttons.
- Publish profiles will now show a progress information on the app version list during binary uploads and re-sign operations, similar to the Testing Distribution module.
- “Last Step” has been replaced with Publish Status, displaying store status based on track metadata along with status options (Not Started, Waiting, Running, Stopped, Warning, Failed, Succeeded, Timeout) for improved profile visibility.
- Overall UI and Text description improvements were applied to Auto Re-sign related configuration areas.
- Improvements were made to CSV reports to enhance the display of column headers and data values.
- All reports across Appcircle now support caching, allowing users to save their last-used search filters for future use.
### 🐞 Fixes
- An issue was fixed where the trigger user email address was incorrectly displayed for some Bitbucket-connected repositories after build actions.
- An issue was fixed where changes saved for the Auto Send for Review setting were reverted after the settings window was closed.
- An issue was fixed where users did not receive proper notifications when uploading duplicate provisioning profiles or when provisioning profiles were added through auto re-sign.
- An issue was fixed where users faced parsing error during Send to Microsoft Intune Publish step.
- An issue was fixed where newly imported provisions were not immediately displayed in the manual provision selection screen of the auto re-sign feature in the Publish module until the page was refreshed.
- An issue was fixed where provision profiles created or downloaded during auto re-sign were not properly imported to the Signing Identity module when using credentials shared from the root organization.
- An issue was fixed where provision profiles generated or downloaded through the Publish module were not correctly recognized and displayed as existing within the Get Provision Profile from App Store Connect feature in Signing Identity.
- An issue was fixed where the pop-up message for certain type-certified app versions appeared off-screen after selecting the install button on the Testing Portal.
- An issue was fixed where organizations containing special characters could not be deleted.
- An issue was fixed where users of the self-hosted version `3.29.3` experienced problems while saving SMTP settings.
### :warning: Breaking Changes
- Following Apple’s update, 6.9” screenshot sizes are now optional, and 6.5” sizes are required. Appcircle [Metadata Details](/publish-to-stores-module/publish-information/meta-data-information) UI has been updated accordingly, while still supporting 6.9” screenshots as optional.
## 3.29.3 - 2025-09-08 Publish and Re-sign Reports, Auto Re-sign Improvements, Bug fixes and more
### 🆕 New Features
- A [Publish Report](/publish-to-stores-module/publish-report) section has been added to the Publish module, where an organization’s publish actions can be tracked with various filters such as trigger type, user, app name, and more.
- A [Re-sign Report](/publish-to-stores-module/publish-resign-report) section has been added to the Publish module, where an organization’s re-sign processes can be tracked.
- Introducing [Machine Plans](/infrastructure/machine-plans) – Users can now upgrade to higher-tier machine plans (Velocity and Ultra in addition to Standard) depending on their license. This gives you access to more powerful build resources in the Cloud, helping you achieve faster and more consistent build times.
- Now self-hosted Appcircle users can use the "GitHub App Cloud Oauth2" option while connecting to the GitHub Cloud from their self-hosted Appcircle server, similar to the cloud users. See the [guide](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/git-providers#github-app-cloud) for a detailed how-to.
### :muscle: Improvements
- [Machine Plans](/infrastructure/machine-plans) are now displayed in the Build History for each build.
- The autofill button is now disabled when the Build profile does not have any selected branch.
- The Custom Script step within the Build module has been updated to support additional languages. In addition to Ruby and Bash, scripts written in Python and NodeJS can now be run.
- The required permission level has been downgraded to API only for GitLab OAuth connections.
- Improvements were made to GitLab PAT and OAuth connection speed for repositories with a high number of branches.
- The active machine plan is now displayed on build configuration screens.
- UI improvements were made to the Microsoft Intune Release Candidate selection screen on Publish profiles, such as disabling the Mark as RC button when no changes were made and hiding the available apps when a new app was selected.
- Support was added for defining multiple Bundle ID and Provisioning Profile matches during auto re-signing.
- The Publish status is now displayed as a tag next to each publish entry in the [Publish History](/publish-to-stores-module/publish-information/history#accessing-publish-history).
- The Bundle ID/Package ID fields have been added to the iOS and Android auto re-sign options for the Testing Distribution module, where this information can be updated to be used in auto re-sign processes.
- Testing Distribution [Auto Re-sign](/testing-distribution/resigning-binaries#auto-re-sign) options have been separated into ‘iOS Auto Re-sign’ and ‘Android Auto Re-sign’ options.
- Users can no longer share `.AAB` binaries to the Testing Portal via Testing Distribution profiles. The ‘Convert `.AAB` to `.APK`’ feature can be used to automatically convert them to `.APK` format.
- Newly created [API Keys](/account/my-organization/security/api-keys) are now displayed with a default expiration date of 6 months, which can be edited by the user to up to 1 year.
- A warning email is now sent a week before an organization’s [API Key](/account/my-organization/security/api-keys) expires.
- The [Billing](/account/my-organization/billing) page UI was updated with spacing adjustments and color enhancements.
- A new filtering header system, similar to the Notification Center, was implemented in the [Build](/build/build-history), [Publish](/publish-to-stores-module/publish-report), [Signing Identity](/signing-identities/signing-reports), and [Testing Distribution](/testing-distribution/reports) module reports.
### 🐞 Fixes
- An issue was fixed where not all fields within the Metadata Details were being flagged as mandatory according to the Google Play rule set.
- An issue was fixed where Enterprise App Store profile headers were not displaying the Beta and Live tags when an app version was published to these channels.
- An issue was fixed where auto re-signed app versions were not being displayed in the app version list without refreshing the browser within the Testing Distribution profiles.
- An issue was fixed where clicking on “Share with Testers” caused UI issues after an Android app version was uploaded.
- An issue was fixed where some users occasionally experienced login issues with the Testing Portal.
- An issue was fixed where changing the Testing Distribution profile name caused saved Auto Re-sign settings to revert.
- An issue was fixed where signed `.AAB` binaries were incorrectly shown as unsigned after conversion to `.APK` in Testing Distribution profiles.
- An issue was fixed where the configuration tabs within the Build profile were not redirecting users to the specific documentation link.
- An issue was fixed where refreshing the browser window while editing the Connection settings caused UI issues.
- An issue was fixed where using an in-app update secret from a Sub-organization caused problems with the app version download URL due to custom domain usage.
- An issue was fixed where organizations with special characters in their name were not being deleted.
- An issue was fixed where new notifications were not being displayed in the Notification Center when it was already open.
### :warning: Breaking Changes
- As [Microsoft announced](https://learn.microsoft.com/en-gb/appcenter/retirement) that the remaining App Center features will be retired after March 31, 2025, the App Center CodePush step in Appcircle will also be deprecated.
- All fields that are mandatory on App Store Connect when saving metadata and submitting the app version for review are now also mandatory in Appcircle Metadata, meaning the Metadata Details form cannot be saved unless all required fields are completed.
- To prevent issues with the license registration process caused by regional time formats, license registrations and expiries are now recorded in UTC format at 12 PM.
:::danger
#### Upgrading from `3.28.3` or older versions
Recently Appcircle made an upgrade for its IAM services, which has an important data migration related to the IAM upgrade. See the "breaking changes" note **[here](https://docs.appcircle.io/release-notes#3-29-1)** for the details.
If you have a Docker/Podman Appcircle server deployment ([standalone](https://docs.appcircle.io/self-hosted-appcircle#dockerpodman-standalone-architecture) or [DMZ-supported](https://docs.appcircle.io/self-hosted-appcircle#dockerpodman-architecture-with-dmz-support) architecture) that is `3.28.3` or an older version, as a **first step**, you must **upgrade to version `3.29.0`** successfully, take the recommended backup, and then go on with version `3.29.3` or later.
You cannot upgrade directly from `3.28.3` or an older version to `3.29.3` or later. You must have an intermediate upgrade step with version `3.29.0` in order to be sure that all previously released data migrations have been applied before the IAM upgrade.
:::
## 3.29.2 - 2025-08-22 Auto Re-sign on Testing Distribution, Build History Improvements, Bug Fixes and more
### 🆕 New Features
- The [Auto Re-sign](/testing-distribution/resigning-binaries#auto-re-sign) feature was added to the Testing Distribution module.
### :muscle: Improvements
- An update was made for [Publish iOS](/account/my-organization/profile-and-team/role-management#publish-to-stores-module-ios-permissions) and [Publish Android](/account/my-organization/profile-and-team/role-management#publish-to-stores-module-android-permissions) operator roles, and access to Publish Flow settings was removed for them.
- The “Create from existing SSO settings” option was disabled for SAML-type SSO configurations.
- The exact renewal time is now shown next to the expiry date on the billing page.
- Auto Re-sign operations will now be specifically mentioned as Auto Re-sign within notifications sent via Email, Teams, and Slack.
- Displayed certificates in Auto Re-sign options will now be shown according to the selected signing method.
- Users can now directly navigate to the relevant build logs by clicking on the build status within the build history.
### 🐞 Fixes
- Some inconsistencies between the descriptions of different SSO configuration types were fixed.
- Incorrect font and date format within the API Key creation settings were fixed.
- An issue was fixed where the “Leave Organization” confirmation button was displayed as “Delete” instead of “Leave.”
- An issue was fixed where users were able to create a sub-organization with a duplicated name.
- An issue was fixed where certain uploaded binaries were displayed with an incorrect icon on Publish profiles.
- The Marketing URL field the Metadata details has been marked mandatory in Appcircle as it is now enforced by Apple.
- An issue was fixed where, on certain error messages, the information link did not redirect the user to the relevant documentation.
- An issue was fixed where workflow and configuration names containing the ‘_’ character were being duplicated with an incorrect name.
- An issue was fixed where refreshing certain branches took too long.
- An issue where build logs displayed an incorrect Xcode version when a specific version was selected in the build configurations has been fixed.
- An issue was fixed where deleting the SSO configuration for Testing Distribution profiles caused UI issues on the Testing Distribution authentication settings.
- An issue was fixed where using the ESC button on the “Share with Testers” step in Testing Distribution profiles caused UI issues.
- An issue was fixed where expiration notifications for Apple profiles, certificates and Android keystores were sent simultaneously instead of periodically.
### :warning: Breaking Changes
- The [Get Approval via Email](/publish-integrations/common-publish-integrations/get-approval-via-email) publish step now requires approvers to log in to Appcircle and make their decision within the Appcircle interface. Previously, decisions could be made directly from the received email without an Appcircle account. This change ensures consistency with the Metadata Approval publish step but requires approvers to have Appcircle user access.
- We’ve removed the automatic conversion of uploaded AAB files to APK using the Appcircle keystore. This change is not backward compatible: AAB files can no longer be shared with testers. Please upload APK files directly or use the new “Convert AAB to APK” option available in resign operations. For detailed guidance, check out the [re-signing documentation](/testing-distribution/resigning-binaries#auto-re-sign). Migration Steps
## [Auto Re-sign](https://docs.appcircle.io/testing-distribution/resigning-binaries#android-auto-re-sign-configurations)
1. If a keystore is not yet uploaded, [upload it](https://docs.appcircle.io/signing-identities/android-keystores#2-upload-android-keystore-file).
2. Open the **Testing Distribution profile** → click the three dots **𐄛** → **Settings**.
3. Under the **Info** tab, enable **Auto Re-sign** and click **Save**.
4. From the same menu (**𐄛**), open **Auto Re-sign Configurations for Android**.
5. In the **Signing** tab, select your uploaded keystore.
6. Enable **Convert AAB to APK**.
7. Click **Save**. From now on, uploaded AABs will automatically be converted to APKs.
---
## [Manual Re-sign](https://docs.appcircle.io/testing-distribution/resigning-binaries#re-signing-android-binaries)
1. If a keystore is not yet uploaded, [upload it](https://docs.appcircle.io/signing-identities/android-keystores#2-upload-android-keystore-file).
2. In the **Testing Distribution profile**, click the three dots **...** next to the binary.
3. Select **Re-sign Binary**.
4. Choose your uploaded keystore.
5. Enable **Convert AAB to APK**.
6. Click **Sign**. The binary will be re-signed and converted within a few minutes.
## 3.29.1 - 2025-08-15 Custom Script from Git Component, Account Module Improvements and IAM Upgrade
### 🆕 New Features
- The [Custom Script from Git component](/workflows/common-workflow-steps/custom-script#how-do-i-store-and-re-use-custom-scripts-from-a-git-repository) now lets you pull and run your scripts directly from any Git repository. Supported script types: Bash (`.sh`), Ruby (`.rb`), Python (`.py`), Perl (`.pl`), Node.js (`.js`), and Java (`.java`).
### :muscle: Improvements
- Upgraded IAM to the latest version to enhance security and reliability.
- Improved the Account page UI and added a remote disconnect option.
### :warning: Breaking Changes
- IAM upgrade in this release makes a **data migration that cannot be reverted**. For this reason, it's **strongly recommended** that the customers who have Docker/Podman Appcircle server deployments ([standalone](https://docs.appcircle.io/self-hosted-appcircle#dockerpodman-standalone-architecture) or [DMZ-supported](https://docs.appcircle.io/self-hosted-appcircle#dockerpodman-architecture-with-dmz-support) architecture) should **take a snapshot backup** of their systems before upgrading. There is no expected incident for the IAM data migration, but in case of an incident, you must restore the backup you took before for the downgrade.
## 3.29.0 - 2025-08-08 API Keys, Webhook Improvements, Bug Fixes and more
### 🆕 New Features
- [API keys](/account/my-organization/security/api-keys) can now be used for accessing and utilizing the Appcircle API. These tokens are generated and scoped to align with organizational requirements and specific role scopes. API Keys can be created and managed from Organization's module Security section.
- The binary comparison feature introduced in the Publish module can now also be used within the [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile#binary-comparison) and [Enterprise App Store](/enterprise-app-store/enterprise-app-store-profile#binary-comparison) modules.
### :muscle: Improvements
- Builds triggered in sub-organizations are now displayed in the root organization’s active processes section, with the sub-organization name also shown. Navigation to the sub-organization where the build is taking place is enabled by clicking on the running build.
- Webhook secret handling was improved when connecting to Git providers.
- Filtered notifications in the notification center are now displayed in the same location as the rest of the notifications, instead of opening on the left side.
- Date formats throughout Appcircle have been updated to be displayed in the MM-DD-YYYY format.
- The clear notifications option will now delete only filtered notifications when filters are selected in the notification center.
- Owner members of sub-organizations are now displayed in the organization’s team management list for users without the organization management role scope, to provide better clarity.
- Changed the organization selection behavior so that updates made on one device or session are not reflected on other devices or sessions, ensuring each session operates independently.
- Setting descriptions have been improved within the auto re-sign configuration options.
- Download options and paths can now be configured before the build starts using new flags for artifacts, logs, and custom directories, providing full control over build outputs.
### 🐞 Fixes
- An issue was fixed where the actual commit/tag author was not shown in the active processes and build history sections when a build was triggered via tags by another user.
- An issue was fixed where repositories with the same name caused incorrect build triggers within Appcircle.
- An issue was fixed where character limit rules were not enforced when editing existing connection PAT settings.
- An issue was fixed where the actual trigger user was not displayed in the build logs when a build was triggered via tags by another user.
- An issue was fixed where some users were unable to trigger builds by tags on SSH-connected profiles when using GitHub.
- An issue was fixed where concurrent builds could use an incorrect Xcode version due to the shared configuration being evaluated at execution time instead of trigger time. The selected Xcode version at the time of triggering is now reliably used for each build.
- An issue was fixed where the verify option in domain verification caused incorrect access error messages.
## 3.28.3 - 2025-07-21 Auto Re-sign for Publish, New Notification Window, UI Improvements and more
### 🆕 New Features
- The [Auto Re-sign](/publish-to-stores-module/publish-information/auto-resign-configuration) feature has been added in Appcircle’s Publish module allows users to automatically re-sign their iOS (.ipa) and Android (.apk/.aab) applications with a different keystore, provisioning profile, or certificate before distribution.
- The [Binary comparison](/publish-to-stores-module/publish-information/binary-information#binary-comparison) feature has been added to highlight differences between two binaries using color-coded indicators for easy identification.
- Introduced a redesigned Notification Center that provides advanced filtering options by Module, Date, Type, and Organization. The new interface allows users to easily track the total number of notifications and clear them in bulk for better management and visibility.
- Users can now manually delete caches from build workflows to optimize storage usage. Artifact storage remains unaffected when clearing Cache Pull/Cache Push data.
### :muscle: Improvements
- Character limit validation has been added to the connection setup fields for all Git provider options.
- Descriptions were added for versioning tab configurations within the Build Profile settings.
- The app icon will now be updated for Publish profiles if the marked release candidate version has a different icon.
- Auto Re-sign related actions were added to the Publish activity logs.
- Auto Re-sign credentials have been moved to the Auto Re-sign configuration, allowing the use of different credentials independent from the profile settings.
- Added character count validation under all input fields with character limits, including metadata input variables, to provide real-time feedback and prevent invalid entries.
- Added export functionality for reports and activity logs in the Signing Identity module to improve accessibility and auditing.
- Added new notification actions for manual cache clearing operations, including support for Teams, Slack, Email, and Webhook notifications.
- Added the ability to select the base build number and version code for Auto Re-sign from App Store, TestFlight, and Play Console by choosing a source for each.
- Added an Information tab to the Auto Re-sign settings to display key app details for Android and iOS.
- Added support for selecting Enterprise API Keys in the Auto Re-sign configuration to enable re-signing apps with in-house certificates.
### 🐞 Fixes
- An issue was fixed where the variable name was not displayed in some notifications when the action was shown.
- An issue was fixed where the updated release note on the Testing Distribution profile did not appear on the screen until the browser was refreshed.
- An issue was fixed where newly created Testing Distribution profiles had UI issues when attempting to distribute binaries to testers.
- An issue was fixed where Publish profiles with an existing release candidate–marked app version caused a UI issue when a second release candidate binary was uploaded with Auto Re-sign and Auto Publish enabled.
- An issue was fixed in the Publish and Resign modules where the Version fields could not be cleared properly, causing values to reappear and lock after multiple deletion attempts.
- An issue was fixed where deleting binaries via checkbox did not revert the delete button back to the file upload state, forcing users to refresh the window.
- An issue was fixed in the Publish module where the Change button remained active after a file was selected, now properly disabling to prevent accidental re-selection.
- An issue was fixed in Workflows where cloned workflows were not following the expected copy naming pattern, ensuring consistent naming behavior across modules.
- An issue was fixed where builds triggered by Git tags showed the commit author instead of the tag author as the trigger user.
- An issue was fixed where CodePush profiles could not be deleted successfully.
- An issue was fixed where navigating to the Security page in a starter organization incorrectly displayed a Plan Limit Exceeded error.
- An issue was fixed in Build Configuration where the Load More button in the Environment Variables list failed to fetch additional items.
- An issue was fixed where the last commit hash was not being retrieved correctly in some cases.
- An issue was fixed where AAB files were not being signed correctly when using Auto Re-sign, which could cause problems during distribution or installation.
## 3.28.2 - 2025-07-09 GitHub Enterprise Support, Manual Webhook Enhancements, SMTP Configuration, Bug Fixes and more
### 🆕 New Features
- Support for the [GitHub Enterprise](build/manage-the-connections/connection-guides/connecting-to-github) connection type has been added to allow build profiles to connect to repositories using a Fine-Grained Personal Access Token.
- Introduced dynamic [SMTP configuration](self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#email) for self-hosted environments, including live updates to mail server settings, and test email functionality.
- Introduced the [Appcircle Assistant GPT](/marketplace/open-ai), a custom AI assistant that provides answers about Appcircle, including step-by-step instructions and troubleshooting support.
### :muscle: Improvements
- The [bind](/build/build-process-management/build-manually-or-with-triggers#binding-existing-manual-webhooks-to-other-build-profiles) option can now be used by build profiles to reuse existing manual webhooks for accessing the same repository across other build profiles.
- Branch names that exactly match the search input are now displayed at the top of the search results within the build profile.
- The warning message on form validations has been improved for cases where the text input is too long.
- The app version icon will now be displayed in the binary information option within the publish profiles.
- The username option has been removed from the Bitbucket repository PAT-type connection settings.
- Upgraded NGINX dependency to `1.29.0` to ensure up-to-date security and stability in self-hosted environments.
- Upgraded PostgreSQL to `14.18` for standalone (Docker/Podman) deployments to ensure latest security and stability improvements.
- Added support for customizing container engine network subnets to avoid conflicts with existing network subnets in standalone self-hosted Appcircle installations.
- Upgraded NGINX to an unprivileged image, enabling it to run without root and enhancing security by adhering to the principle of least privilege on self-hosted Appcircle Servers.
### 🐞 Fixes
- An issue has been fixed where, on some occasions, the webhook URL was being updated during the configuration phase.
- An issue has been fixed where an existing manual webhook used by a build profile was not detected by other build profiles connected to the same repository.
- An issue has been fixed where, on some occasions, clicking the webhook icon on the build profile caused disruptions in the webhook connection.
- An issue has been fixed where refreshing the browser page caused UI problems on the iOS tab of the testing distribution profiles.
- Various UI issues related to testing distribution module that were experienced on Firefox browsers have been fixed.
- An issue has been fixed where the current organization was being reset after login for users with inherited access to sub-organizations.
- An issue has been fixed where using an HTTP proxy alongside service replicas in standalone self-hosted Appcircle Server deployments could lead to network connectivity problems.
- An issue has been fixed where new branches did not appear in the Appcircle branch list if webhooks were disabled in Azure DevOps 2020 repositories.
- An issue has been fixed where the Metadata Approval Publish Step settings were not accepting subdomain-type email addresses.
### :warning: Breaking Changes
- We’ve resolved an issue where sharing an Enterprise API Key with another organization would change the key type, leading to authentication errors during API requests. This fix is not backward compatible. If you have shared an Enterprise API Key across organizations, please delete and add again only those shared keys to ensure everything works properly.
## 3.28.1 - 2025-06-16 New Bitbucket Repository Connection Types, UI Enhancements, Improvements and more
### 🆕 New Features
- Root organization credentials, such as [App Store Connect](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key#sharing-app-store-connect-credentials) and [Google Play Developer](/account/my-organization/security/credentials/adding-google-play-service-account#sharing-google-play-developer-credentials) API keys, can now be shared with sub-organizations.
- The [“Hide from profile list on Testing”](/testing-distribution/create-or-select-a-distribution-profile#exclude-from-shared-application-list) toggle can now be used in Testing Distribution profile settings to prevent the selected profile from appearing in the shared profile list within the Testing Portal.
- [Bundle and Package Validation](/testing-distribution/create-or-select-a-distribution-profile#bundlepackage-identifier-validation) toggles can now be used to specify a bundle ID (for iOS) or package ID (for Android). When enabled, any app with a different bundle or package ID will be blocked from being uploaded to the Testing Distribution profile.
- The [“Hide Shared Application List”](/testing-distribution/create-or-select-a-distribution-profile#hide-shared-application-list) toggle can now be used under the Authentication tab in Testing Distribution profile settings to restrict access to the shared profile list within the Testing Portal.
### :muscle: Improvements
- Webhook distribution to profiles in Appcircle is now handled through a single repository-level webhook registration, streamlining integration across associated profiles.
- A Webhook Key Generation option has been added to the [manual webhook creation](/build/build-process-management/build-manually-or-with-triggers#setting-up-manual-webhooks-based-on-repository-connection-type) screen for build profiles with public and SSH repositories.
- [Repository-based](/build/manage-the-connections/connection-guides/connecting-to-bitbucket#connecting-to-bitbucket-cloud-repository) access support has been added for build profiles to be used with both Bitbucket Self-Hosted and Bitbucket Cloud.
- UI improvements have been made to the [connection](/build/manage-the-connections) list, where the used provider and connection type such as Personal Access Token (User)(Cloud) are now displayed as tags next to the saved PAT connections.
- Notification support has been added for CodePush actions across Email, Microsoft Teams, and Slack channels.
- Improved the error message returned when a specified deployment cannot be found during the appcircle-code-push release-react command. The message now clearly indicates that the deployment does not exist, replacing the previous generic “INTERNAL_ERROR” response.
- The date and time information will now be displayed alongside the latest commit message when starting builds.
- [Export as CSV](/testing-distribution/testing-groups#exporting-testing-group-members-as-csv) option has been added for Testing Groups to extract the tester email list as a CSV file for easier sharing and external management.
- The “Show only shared version to the tester” option can now be used in the Auto Send Configuration within the Testing Distribution profile settings.
- When the “Show only shared version to the tester” option is enabled, testers will be restricted from using the search bar and accessing other shared Testing Distribution profiles.
- Improvements have been made to the Testing Portal mobile view, where app details are now shown within the app list when selected, instead of opening at the top of the screen.
- Platform selection (iOS and macOS) has been added to the Apple Bundle Identifier creation settings.
- UTF-8 characters are now supported when naming a provisioning profile during its creation.
- The [Send to Testing Distribution](/publish-integrations/common-publish-integrations/send-to-testing-distribution) Publish step has been added, allowing users to directly send their apps from a Publish Profile to a selected Testing Distribution profile.
- Support has been added for using human-readable names instead of UUIDs across all [CLI](https://github.com/appcircleio/appcircle-cli/releases/tag/v2.7.0) parameters, and the `-o` JSON output formatting has been fixed.
### 🐞 Fixes
- An issue was fixed where an error was thrown by the API when attempting to create a new provisioning profile with both In-House and App Store Connect types.
- An issue was fixed where, with Auto Publish enabled, receiving an app with a different version resulted in a new app being created on Intune instead of updating the app previously marked as RC.
- A UI description issue for Android binary information on Publish Profiles has been fixed.
- An issue was fixed where UI inconsistencies were encountered after redirection when a different organization was accessed while viewing a CodePush app page.
- An issue was fixed where app icons were not displayed on the email sending screen of the Testing Distribution module.
- An issue was fixed where the help button for the Resign Binary feature was redirecting users to an invalid link within the Testing Distribution module.
- A texture issue on the Testing Portal has been fixed.
- An issue was fixed where Android binary icons were not displayed on the Testing Portal login screen for Testing Distribution profiles that did not include iOS binaries.
- An issue was fixed where navigating to a sub-organization from the Organization module resulted in incorrect access error messages.
- The `NOT_AUTHORIZED` error that occurred while publishing apps to the App Store using Xcode 16.0-16.2 versions on macOS Sequoia runners was fixed.
- The `error XA5300: The Android SDK directory could not be found` issue that occurred while building MAUI Android apps on macOS Sequoia runners was fixed.
- Fixed an issue in the Git Clone step where branch names containing special characters (e.g., (, )) caused shell syntax errors. Branch names are now properly wrapped in quotes to ensure safe execution.
## 3.28.0 - 2025-05-21 CodePush Integration, Send Email Publish Step, Improvements and more
### 🆕 New Features
- [CodePush](/code-push) has now been fully integrated with Appcircle, enabling over-the-air (OTA) updates with granular rollout control, rollback safety, and precise version targeting, thereby enhancing release agility and improving the user experience.
- The new Appcircle CodePush workflow step has been introduced to automate build-time deployment: selects the deployment, bundles the JavaScript assets, and uploads the package to the Appcircle CodePush server.
- The [Send Email](/publish-integrations/common-publish-integrations/send-email) publish step has been added to the Publish Flow options to send customized email notifications during your Appcircle Publish Flow for both iOS and Android publishes. This can be used to alert stakeholders, notify of publish statuses, or provide deployment-related information.
- The [Hide Certificate Details](/enterprise-app-store/enterprise-app-store-profile#hide-certificate-details) toggle can now be enabled from the Enterprise App Store profile settings to hide certificate details when app versions are published to the Enterprise Portal.
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest GA release of the [Xcode 16.3](https://developer.apple.com/documentation/xcode-release-notes/xcode-16_3-release-notes) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
### :muscle: Improvements
- The use of environment variables within the metadata detail fields, such as phone and email, in the publish module is now supported.
- The store status change option has been added to the notifications list. Users can now be automatically notified when the store status changes for a version within the publish module.
- The id key has been removed from the downloaded environment variable JSON file to simplify the structure and prevent potential conflicts during re-import or reuse.
- “Expired” and “Exists” tags have been added to Apple provisioning profiles to improve visibility during registering operations.
- An “Available” label is now shown for certificates already registered in Appcircle during provisioning profile registration.
- Binary search by name, bundle ID, and version is now supported within the Enterprise Portal. Additionally, versions can be sorted by version number and upload date.
- A new UI warning is now displayed when too many requests are sent within a short time frame.
- Help link buttons have been added across various module components where they were previously missing.
- Webhook notification channels now support events related to the Publish module.
- Improved the sorting of organization and sub-organization lists by applying alphabetical and numeric order where applicable.
- A name field has been added allowing users to assign a custom name to their webhook notification integration settings.
- Various typos have been corrected and text improvements have been made in the webhook notification integration settings.
- An exit icon has been added to the “Leave Organization” button to replace the previous delete icon.
### 🐞 Fixes
- An issue was fixed where the Custom Domain option could not be enabled by cloud users in the Enterprise App Store settings.
- Fixed an issue where users accessing Enterprise App Store profiles via direct channel links could not view the release notes of the binaries.
- An issue was fixed where branches deleted from the repository were not removed from the list until the screen was refreshed.
- An issue has been fixed where the “Select All” button was not functioning for the build item list within the Build module.
- An issue has been fixed where refreshing the branch list caused the selected branch to be deselected.
- Fixed an issue where users who were members of only a single sub-organization experienced problems related to license scope.
### :warning: Breaking Changes
- The reserved Publish environment variable `AC_PUBLISH_WORKFLOW_NAME` has been renamed to `AC_PUBLISH_FLOW_NAME`, and its value will now be set to “Default Publish Flow” instead of the step name.
## 3.27.2 - 2025-05-09 Upload Option for Variable Groups, Build Enhancements, Improvements and more
### 🆕 New Features
- Downloaded Variable Group JSON files can now be [uploaded](/build/build-environment-variables#uploading-environment-variables) to existing or newly created variable groups for easier transmission. Alternatively, users can create their own JSON files and upload them, provided they follow the correct format.
- The Binary Details sections of the [Enterprise App Store](/enterprise-app-store/enterprise-app-store-profile#binary-information) and [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile#binary-information) profiles will now display build metadata details, including trigger type, workflow name, source branch and more.
### :muscle: Improvements
- The search functionality for the Testing Distribution module has been improved by integrating a server-side component, enhancing performance and scalability.
- The Upload button has been moved to the upper section of the app version list for improved visibility on Testing Distribution profiles.
- A sidebar summary card has been added, displaying the organization name, license plan, and license expiry date along with a quick access link to Billing page for Enterprise licensed organizations.
- The Last Commit ID display has been updated to Last Commit Hash within the Build module.
- The latest Android and iOS OS versions have been added to the Send to Microsoft Intune settings within the Publish Step.
- Support has been added for executing custom scripts from Git repositories in the Custom Script step, enhancing reusability and version control.
### 🐞 Fixes
- An issue was fixed where having only an Enterprise-type API key caused UI issues in the Publish module.
- Typographical errors have been corrected in various areas of the Signing Identity module.
- An issue was fixed where using former commit hashes on new builds caused a UI problem.
- An issue was fixed where some users experienced problems during fetching operations on build profiles when connected to a Bitbucket repository.
## 3.27.1 - 2025-04-11 Metadata Approval and Domain Verification Improvements, Bug Fixes and more
### 🆕 New Features
- Binary Tags can now be configured from the [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile#binary-tags) and [Enterprise Portal](/enterprise-app-store/enterprise-app-store-profile#binary-tags) profile settings to be displayed on the Testing and Enterprise Portals. The data for these tags is provided by the Build module. These tags help testers identify the context, source, and purpose of each app version.
- Support has been added for downloading build logs using the `commitId` and `buildId` parameters, with optional path support.
- The **Select Java Version** step, commonly used in Android projects, has been added to the default workflows.
- The **Release Notes** component is now enriched with build Git metadata by default and added to the Default Workflow for all platforms.
### :muscle: Improvements
- The Domain Verification feature can now be used for the same domain across multiple organizations.
- Validation has been added for enabling SSO authorization to ensure that the configuration includes existing SSO groups, roles, and an enabled SSO authentication.
- A warning message will now be displayed instead of redirecting to the login screen if the user enters their SSO alias incorrectly.
- Users are now able to upload binaries up to 3 GB (previously 2 GB) across various modules.
- Improvements have been made to the display and calculation of usage numbers across various modules within the Billing page.
- The Publish module will now correctly display Timeout and Cancel statuses in applicable scenarios. The Publish timeout limit will align with the Build timeout limit, which can be found in the Billing area.
- The **Upload Certificate Signing Request** option has been removed from the **Create an Apple Certificate** process.
- Outdated commit IDs can now be used to start builds when connected to remote repositories.
- The error message displayed when attempting to save a trigger setting with an invalid configuration or workflow has been improved.
- The Testing Distribution profile cards will now display the upload dates of the iOS and Android app versions.
- Performance improvements have been made to the Testing Distribution module for sending app versions to a large number of email addresses.
### 🐞 Fixes
- An issue was fixed where registered LDAP Groups could not be fetched on sub-organizations for syncing with Testing Groups.
- An issue was fixed where SSO login via alias redirected users incorrectly in certain scenarios.
- Various issues have been resolved on the metadata information screen for Publish Profiles, where users were sometimes unable to see uploaded images or upload screenshots.
- An issue where metadata information could still be edited during the metadata approval process has been fixed.
- An issue was fixed where the metadata approval email did not redirect users to the correct organization if they were logged in to a different one.
- Typos have been fixed in various descriptions across multiple Publish steps.
- An issue was fixed where `.p12` files created from Apple certificates were missing the private key, resulting in Xcode build errors due to the key not being added to the keychain.
- An issue was fixed where accepted invitations were not updating the pending status in the Apple Devices section.
- An issue was fixed where users could not remove PAT connections from Sub-Organizations.
- An issue was fixed where the selected branch became deselected after switching to a different build profile and then navigating back to the original profile.
- An issue was fixed where, in some cases, the saved export method for the Automatic Code Signing option was changing incorrectly.
- An issue was fixed where case sensitivity in the Manage Access tab of the Enterprise App Store profile settings caused problems with access management for some users.
- An issue was fixed where the Update button was not visible on some macOS browsers in the Enterprise App Store Customization area.
- An issue was fixed where switching OS tabs while uploading an app version caused UI issues on Testing Distribution profiles.
- A Missing Help button has been added, and the Upload button is now disabled while a CSV file is being uploaded, as part of the Import from CSV feature in Testing Groups.
## 3.27.0 - 2025-04-04 Metadata Approval, Import Testing Group Members via CSV, Notification Improvements and more
### 🆕 New Features
- The ‘[Metadata Approval](/publish-integrations/common-publish-integrations/metadata-approval)’ Publish step can now be used for iOS and Android binaries, allowing email addresses of approvers to be added. Metadata updates for app versions can then be approved or rejected by the designated approvers.
- A “[Publish as Unlisted](/enterprise-app-store/enterprise-app-store-profile#publish-as-unlisted)” toggle option has been added to the Enterprise App Store profile’s publish-to-store process. When enabled, the app will be published without appearing in the Enterprise Portal and will only be accessible via Live or Beta channel links.
- A [CSV Import option](/testing-distribution/testing-groups#importing-testing-group-members-via-csv) has been added to Testing Groups, allowing users to add tester email addresses by uploading a CSV file.
- The user email list of an organization can now be exported as a CSV file.
### :muscle: Improvements
- A Cancel button has been added to the Active Processes section at the bottom for Resign Binary operations.
- Notification and error messages throughout Appcircle modules can now be viewed separately under the Notifications tab. They can also be deleted using a newly added delete confirmation prompt.
- Various text and UI improvements have been made to the Domain Verification feature.
- A warning message will now be displayed in Build Configurations, Workflows, and Triggers if any changes are made and the user attempts to close the relevant window without saving.
- Users can now access the Pull Request (PR) description during the build process by using the $AC_GIT_PR_DESCRIPTION environment variable.
- Performance optimizations have been made for the build branch search feature and the app version search in Testing Distribution.
- The warning message for reaching the download limit has been improved in the Testing Portal’s mobile view.
- The Share button has been removed from the app action list within the Enterprise App Store. Instead, users can now obtain the Beta or Live channel links from the profile settings’ “[Links](/enterprise-app-store/enterprise-app-store-profile#distribution-links)” section.
- Several UI and text improvements have been made to the Enterprise App Store module within Appcircle, as well as to the Enterprise Portal.
### 🐞 Fixes
- An issue was fixed where users were able to edit user permissions even when SSO Authorization was enabled.
- An issue was fixed where informative text was not displayed when deleting an SSO Group.
- An issue was fixed where certain URLs did not redirect the receiving user to the exact location if they were not already signed in, affecting pages such as profiles and specific configurations.
- An issue was fixed with various Help button links throughout Appcircle, and new links have been added to multiple areas, including the Enterprise App Store and Signing Identity modules.
## 3.26.2 - 2025-03-14 Generate And Download Certificate from Appstore, Domain Verification, License Limit Notifications, Improvements and more
### 🆕 New Features
- App Store certificates can now be [generated](/signing-identities/apple-certificates#creating-an-apple-certificate) with password encryption and downloaded within the signing identity module.
- Users can now verify their domains for Appcircle organizations within the Security section of the Organization module by using [Domain Verification](/account/my-organization/security/domain-verification). This allows inviting members who do not have inboxes for verifying email addresses as part of the organization joining process.
- In the Publish module, when a binary is rejected with a message, users will now receive a notification containing the reject message. Additionally, a new notification type has been added to the [Notification section](account/my-organization/notifications) specifically for these reject notifications.
- A separate tab system has been added for Android and iOS apps in the [Testing Portal](testing-distribution/testing-portal) for devices with unknown OS, such as desktops. If the detected OS is Linux, the default tab will be set to Android.
### :muscle: Improvements
- An additional column for Profile Name has been added to the Admin Panel.
- Information regarding LDAP SMS 2FA support has been added for both Cloud and Self-hosted Appcircle servers.
- Notifications are now sent when license limits are reached, with state management preventing duplicate alerts.
- Starter organizations can be deleted by users with an enterprise organization, except when SSO is enabled. In such cases, the starter organization cannot be deleted. After confirmation, the organization is deleted, the session is terminated, and the user is redirected to sign in via SSO.
- Permission requests have been updated for [GitHub OAuth](/build/manage-the-connections/connection-guides/connecting-to-github#oauth2-and-personal-access-token-permissions-for-github-integration) repository connections in Build Profiles within Appcircle.
- Android submission logs are now added to the [Publish Activity Log](publish-to-stores-module/publish-activity-log), including release submissions, status updates, and successfully completed transactions.
- A new option has been added to [Apple Devices](signing-identities/apple-devices) for users to view both active and inactive devices together.
- An improved preview screen has been added to the Apple Provision Profile Addition screen, allowing users to view Apple devices and certificates before proceeding.
- Users will now have the option to be redirected to the CSR creation screen during Apple certificate creation if no existing CSR is available.
- Performance improvements have been made to the commands used for uploading iOS and Android application binaries in Publish, Enterprise App Store, and Testing Distribution.
### 🐞 Fixes
- An issue was fixed where self-hosted Appcircle users encountered issues when using SMTP servers that do not support SSL or STARTTLS.
- An issue was fixed on self-hosted Appcircle servers where invitation emails were redirecting to an error page.
- An issue was fixed where the In-House provisioning profile type was not available when using an Enterprise API key for registration. This option is now properly provided only for the Enterprise API key, while "Ad-hoc" and "App Store Connect" remain available for the App Store Connect API key.
- An issue was fixed where registering a new profile would not work properly if no provisioning profile existed on Apple Developer. The UI now correctly handles the case when no profile is available.
- An issue was fixed where the provision type was incorrectly displayed when adding a development provision in the Signing Identity module.
- An issue was fixed where the Enterprise API Key was not filtered when creating a Publish profile from App Store Connect. It is now properly filtered as it doesn't support TestFlight or App Store Connect options.
- An issue was fixed where restarting the Android Publish Flow before retrieving metadata details would result in a timeout error.
- An issue was fixed where a failed publish step after a successful one with custom UI blocked the display of the successful step's UI. The button now correctly updates to end the live process and show the successful step's UI.
- An issue was fixed where the Display Name of the Resign property did not update after the resign process was completed.
- An issue was fixed where the 'Get help with build errors' link in the Build Log section was not working.
- An issue was fixed where [connections](build/manage-the-connections) (Azure, Bitbucket, GitLab, GitHub) were removed from the original organization after deleting a second root organization. The connections now remain intact in the original organization.
- An issue was fixed where [sharing an app version link](enterprise-app-store/enterprise-app-store-profile#distribution-links) for an Enterprise App Store configured with 'none' auth type would redirect users to the app version list instead of directly to the installation step.
- An issue was fixed in the Testing Distribution module where the [resign](testing-distribution/resigning-binaries) feature detected an empty target, preventing the binary from being resigned.
- An issue was fixed where the IdP-initiated SSO flow would not work if the alias contained capital letters.
- An issue was fixed where retrieving an access token from Swagger would return a load fail error.
## 3.26.1 - 2025-02-28 Distribute to Track Update for Android Publish Flow , SAML SSO Enhancement, Improvements and more
### 🚨 Announcements
:::warning New IP Block
Dear Appcircle Users,
As part of our ongoing efforts to enhance our infrastructure and improve service quality, we have added new machines to our data center.
With this update, a new IP block (77.92.102.192/28) has been assigned, and customers using Appcircle services through internal networks must update their firewall settings accordingly.
:warning: Critical: The machines associated with this new IP block has been operational since February 3rd, 2025.
To ensure uninterrupted access to Appcircle services, we kindly ask all customers to update their firewall settings. Failure to add the new IP block in advance may result in access disruptions.
To view the updated IP list and technical details, please visit the [Accessing Repositories Within Internal Networks](/build/manage-the-connections/accessing-repositories-in-internal-networks-firewalls) documentation.
If you have any questions or require assistance, feel free to contact our support team.
Thank you for your cooperation and support in ensuring uninterrupted service.
:::
### 🆕 New Features
- The [Distribute to Track](/publish-integrations/android-publish-integrations/distribute-to-track) publish flow step has been added for Android Publish, allowing users to distribute their binaries to the distribution track on Google Play Console.
- The [Auto Send for Review](/publish-to-stores-module/publish-information/google-play-information#auto-send-for-review) option has been added to the following publish flow steps: Distribute to Track, Send to Google Play, Update Metadata, and Update App Information.
- A toggle option has been added to enable or disable LDAP in the LDAP authentication settings for Appcircle, Enterprise Portal, and Testing Portal.
### :muscle: Improvements
- The Identity Provider Entity ID field has been added to the SAML-type SSO configurations.
- The Distribute to Track publish step actions have been added to the Publish Activity Log.
- Build reports will now display the self-hosted runner name, configuration profile, and workflow profile in the build list.
- An option has been added to [disable](/testing-distribution/testing-groups#disable-ldap-import-settings) active LDAP import settings for Testing Groups.
- The ‘@’ symbol was replaced with a mail icon for the email address text box in the Testing Groups section.
- Monitoring support has been added to the **Appcircle DMZ server**, allowing it to connect to the Appcircle server’s monitoring domain to forward container logs.
- A trusted CA certificates volume has been introduced for the **Nginx service** on the Appcircle DMZ server.
- Support for custom authentication domain SSL certificates has been added to the Appcircle DMZ server.
### 🐞 Fixes
- An issue was fixed where some users experienced an error when uploading the Apple Enterprise API Key in the security section.
- An issue was fixed where some users were unable to disable the two-factor authentication option in the Testing Portal LDAP settings.
- An issue was fixed where users could not generate a Personal Access Token without having the Manager role for the Organization module.
- An issue was fixed where the system displayed duplicate error messages when registering an invalid API key.
- An issue was fixed where changes to the App Store version release date could not be saved within metadata details.
- An issue was fixed where ‘Package ID’ was displayed as ‘Bundle ID’ for Android binaries in the Publish module.
- An issue was fixed where the calendar option for the Apple Version Release Date was unreadable in the White Appcircle Theme.
- An issue was fixed where the Update Metadata publish step caused errors if no existing version was available on App Store Connect.
- An issue was fixed where some users could see both Android and iOS binaries on the Testing Portal when using iPad devices.
- An issue was fixed where some users were unable to resign binaries in the Testing Distribution module.
- An issue was fixed where the App Store Connect option was visible for Enterprise-type Apple API keys during the provisioning profile creation step in the Signing Identities module.
- An issue in the Nginx configuration was fixed where `proxy_redirect` entries were duplicated when a custom authentication domain was enabled on the **Appcircle DMZ server**.
- A duplicate volume mount issue in the Nginx service of the Appcircle DMZ server has been resolved.
- Port mapping configurations on both the Appcircle server and the Appcircle DMZ server have been corrected.
- An issue was fixed where the custom authentication domain was not properly applied to certain environment variables.
## 3.26.0 - 2025-02-13 OpenShift Support, Artifact Storage Limit Insights, Streamlined Workflows & Stability Improvements and more
### 🆕 New Features
- We are thrilled to introduce our OpenShift [installation guide](/self-hosted-appcircle/install-server/helm-chart/installation/openshift) and support for deploying a self-hosted Appcircle server on [OpenShift](/self-hosted-appcircle/install-server/helm-chart/installation/openshift). You can install Appcircle [distributed architecture](/self-hosted-appcircle#kubernetesopenshift-architecture-using-helm-chart) on [Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift) application platform, which supports high availability, fault tolerance, and scalability, ensuring robust performance for production environments.
### :muscle: Improvements
- Artifact storage limits can now be viewed on the billing page for your organization.
- The onboarding screen will no longer be displayed to newly signed-up users with an Enterprise license.
- Error and warning messages have been improved across various modules for cases of expired licenses and full usage limits.
- When signing up to Appcircle via an organization invite, users will no longer generate a starter organization under their username.
- The Enterprise App Store custom domain settings have been disabled in the Dashboard for standalone self-hosted installations.
- The NGINX dependency in self-hosted Appcircle has been upgraded to enhance security and performance.
- The Grafana and Loki services in self-hosted Appcircle have been upgraded to their latest versions.
### 🐞 Fixes
- An issue was fixed where email addresses in a specific format could not be removed from organizations.
- An issue was fixed where users were unable to delete their starter-level organization despite being members of an enterprise-level organization.
- An issue was fixed where the Publish History screen could not be scrolled down when containing more data than the user could view.
- The description of the ‘Creating a Publish Profile’ step for Android profiles has been improved for better clarity.
- An issue was fixed where users were redirected to the Registered Devices tab of the Apple Devices section upon refreshing the page, despite having selected other tabs.
- Development type has been added for registering a new provisioning profile within the Signing Identities module.
- An issue was fixed where the highlighting blue background for newly manually uploaded provisioning profiles did not appear for fetched profiles from App Store Connect.
- An issue was fixed where the preview screen in the Enterprise App Store customization section did not display the correct colors for the store title.
- An issue was fixed where distributing a binary from Testing Distribution to the Enterprise App Store for duplicated app versions did not display an error message.
- An issue was fixed where some Publish, Testing Distribution, and Enterprise App Store profile icons were not displayed properly.
- An issue was fixed where deleted configuration and workflow profiles saved in trigger settings were not being removed.
- An issue was fixed where some test reports were not displayed properly within the Build module.
- An issue was fixed where some build configuration profiles could not be downloaded as YAML files.
- An issue was fixed where iOS workflow test report components caused a CORS error.
## 3.25.0 - 2024-12-19 Appcircle Deployment on Kubernetes, List View Type for Build and Testing Distribution, Improvements and more
### 🆕 New Features
- We are thrilled to introduce our enhanced Helm documentation for deploying Appcircle server on [Kubernetes](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes). This new [architecture](/self-hosted-appcircle#kubernetesopenshift-architecture-using-helm-chart) supports high availability, fault tolerance, and scalability, ensuring robust performance for production environments.
- Build and Testing Distribution profiles can now be viewed in both list and profile card formats, based on the selected view type.
- App versions uploaded to the Testing Portal can now be [filtered](/testing-distribution/testing-portal#search-by-branch) by their branch and binary list can be [sorted](/testing-distribution/testing-portal#sort-binaries-by-version--date) by app version or the upload date.
- Authentication settings can now be configured through the [Fastlane Marketplace Testing Distribution](/marketplace/fastlane/testing-distribution) plugin when creating new testing profiles.
- Testing groups for the auto-send feature can now be configured through the [Fastlane Marketplace Testing Distribution](/marketplace/fastlane/testing-distribution) plugin when creating new testing profiles.
- A new method has been added to sub-organization distributions through the [Fastlane Marketplace Testing Distribution](/marketplace/fastlane/testing-distribution) plugin. Versions can now be distributed using the Root Organization’s PAT and the sub-organization’s name when creating new testing profiles.
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has the latest (final) release of the [Xcode 16.2](https://developer.apple.com/documentation/xcode-release-notes/xcode-16_2-release-notes) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
- `AC_BUILD_BRANCH_ID` [reserved environment variable](/environment-variables/appcircle-specific-environment-variables#ios--android-common-environment-variables) has been added to display a unique ID for each branch.
- Existing messages for testers can now be edited by users to be updated for each binary on the testing portal side.
### :muscle: Improvements
- The billing page will now display a warning for licenses set to expire within a week and an error for licenses that have already expired.
- Screenshot previews have been enhanced to allow zooming for a better view of the metadata in the Publish module.
- The [Binary Details](/testing-distribution/create-or-select-a-distribution-profile#binary-information) option within the Testing Distribution module has been improved to include build and extended provisioning profile and certificate information
- The build logs of a binary deployed to the Publish module can now be accessed from the [Build History](/publish-to-stores-module/publish-information/history#accessing-build-history) tab, even if the build artifact has been deleted in the Build module.
- The usage of Testing Distribution for the license is now based on the application download count from the Testing Portal, rather than the number of emails shared via Testing Distribution.
- The redirection of Testing Distribution email URLs was improved for use in external browsers.
- HTML codes can no longer be injected into tester messages when sending applications to the testing portal due to security concerns.
- The Apple Devices option has been made visible for Apple Profiles without registered devices, with a relevant warning displayed when the option is selected by users.
- The application logo is now displayed when installing an application via the Enterprise Portal.
- The manual upload endpoints of the Testing Distribution, Publish and Enterprise App Store modules have been enhanced to provide a better experience for large file uploads.
- Notification updates have been made for various modules across all channels have been made, resolving discrepancies between notifications for different channel types.
- The dashboard page will now display a Publish Count card in place of the second Testing Distribution Count card.
- The Appcircle theme can now be easily changed from the bottom status bar’s right corner.
- My Details section has been removed from the Account page.
- App versions marked as live or beta-published now cannot be deleted by users without unpublishing them first.
- Starter Edition license users can no longer access Captcha settings within the Enterprise App Store settings.
- The Enterprise App Store Reports will now list all binaries for the organization within the binary filter, regardless of the selected date filter.
- Node.js 22 support has been added to the Appcircle CLI.
### 🐞 Fixes
- An issue was fixed where, in some cases, screenshots were being duplicated after using the Update Metadata workflow in the Publish module.
- An issue was fixed where some self-hosted users were unable to resign a binary within the Publish module.
- An issue causing errors for self-hosted users when running “Add for Review” on the App Store within their publish flow has been fixed.
- An issue was fixed for self hosted users when retrieving and attempting to update incorrect App Store app information (previously, the already deployed app was retrieved). The correct app in the “Ready for Submission” state is now retrieved and updated.
- An issue was fixed where the iOS certificate and provisioning profile could not be uploaded directly through the build configuration.
- An issue was fixed where cache pull and cache push workflows did not function correctly for some self-hosted users.
- A new environment variable, `ASPNETCORE_MAX_JAVA_MEMORY_SIZE`, has been created to address the issue where 4000M of heap memory was required in Java for locating the APK logo.
- An issue was fixed where the naming rules for build configurations were not consistent between manual creation and YAML upload.
- An issue was fixed where the Azure DevOps pull request merge commit message was missing due to a webhook event parsing bug in Appcircle.
- An issue preventing users from saving updated signing settings on certain build profiles has been fixed.
- An issue was fixed where deleted configuration and workflow profiles, which had already been saved in trigger settings, caused problems that were preventing the updating and deleting of existing triggers.
- An issue was fixed where configurations, such as the Xcode version and project paths, were being reset for iOS Flutter and React Native build profiles.
- An issue was fixed where long commit labels were causing problems with Bitbucket repositories.
- An issue was fixed where iOS certificates in use within build profiles could not be forcefully deleted by users.
- An issue was fixed where, when a synced API key was deleted, devices not registered under another API key within the organization were incorrectly listed as unregistered devices.
- An issue related to icon parsing for APK files has been fixed.
- An issue was fixed where the “Import from LDAP” option was disabled for the first row entry of testing groups, despite having the relevant configuration in place.
- An issue was fixed where app versions shared via distribution links were not appearing at the top of the list in the Testing Portal.
- A fix was applied for reverse proxy login form error occurring in certain self-hosted environments.
- An issue was fixed where some self-hosted users were unable to download iOS binaries from the Testing Portal after logging in with static authentication.
- An issue was fixed where data could not be retrieved when attempting to download reports through the API without specifying a date range.
- An issue was fixed where the Enterprise App Store report filters did not display the required data correctly.
- An issue was fixed where .ipa binaries without icons could not be downloaded.
- An issue was fixed where the binary list order on the Enterprise Portal was altered when specific binaries were selected.
- An issue was fixed where selecting certain filters removed app version graphs in the Enterprise App Store reports.
- An issue was fixed where the Manage Access settings were accessible to Enterprise App Store profiles without an authentication method.
- An issue was fixed where certain types of characters in passwords were being rewritten, leading to unsuccessful login attempts on iOS devices for LDAP logins within the Enterprise Portal.
- The incorrect user group retrieval strategy values causing LDAP user login issues have been updated.
- An issue was fixed where users were unable to disconnect their email settings from the notification settings.
- An issue was fixed where the license terms on the dashboard displayed incorrect dates for the license status.
- An issue where the sync interval for LDAP Mapping was not correctly displayed in the UI upon page load or reload has been fixed.
## 3.24.0 - 2024-12-06 Publish Priority Configuration, Download Module Reports Through API, Bug Fixes and more
### 🆕 New Features
- Monthly Publish usage can now be monitored separately through the [Billing](/account/my-organization/billing) screen in the Organization module. It is no longer combined with monthly Build usage.
- [The Apple Devices](/signing-identities/apple-profiles#adding-device-to-provision-profile) section under the Provision Profile Action now allows users to easily add device UDIDs to the corresponding provisioning profiles.
- [Publish priorities](/publish-to-stores-module/publish-settings#publish-priority) can now be configured as **High**, **Medium**, or **Low** to manage the start order of queued publish processes accordingly. Available for organizations with Enterprise License.
- The module reports can now be exported through API calls.
- Branch names that exceed the visible length in the branch list are now displayed in full via a tooltip pop-up.
### :muscle: Improvements
- An update was applied to the build history reports, where some columns were removed or re-ordered, and typographical errors were corrected.
- The cursor is now automatically focused on the first input field when navigating between modals in the Signing Identity module.
- Search functionality for build profiles has been improved to deliver results from all profiles, even in organizations with a large number of build profiles.
- Enhanced the Signing Identity Activity Log to ensure all signing identity actions are displayed accurately.
### 🐞 Fixes
- An issue was fixed where multiple LDAP group mappings for organizations were overriding each other instead of being merged during sync execution.
- An issue was fixed where notifications configured for activities in the Signing Identities module were not functioning properly.
- An issue where some publish flows were displayed as successful despite containing a failed step has been resolved.
- An issue was fixed where the build profile configurations for React Native projects had missing settings after being cloned.
- An issue was fixed where the InitiatedBy column displayed as N/A in build reports for automated or remote build triggers.
- An issue was fixed where the “Disconnect from Remote Repository” button did not appear in the build profiles on the latest versions of the Safari browser.
- An issue was fixed where users were unable to download the YAML configuration file from a build profile when navigating to the Versioning tab of the build configuration.
- An issue was fixed where users were unable to log in to the testing portal via shared distribution links when using the static authentication method.
- An issue was fixed where iOS app icons did not display properly during installation on Apple devices after being downloaded from the Testing Portal.
- An issue where registered testing groups were not visible in the auto-send settings after users logged into their organization or sub-organization has been resolved.
- An issue was fixed where the UI failed to display an error message when a duplicate Apple certificate was uploaded in the Signing Identity module.
- An issue was fixed where the icons of certain `.APK` binaries were not being displayed properly on the Enterprise Portal and the Testing Portal.
## 3.23.1 - 2024-11-13 Enable Captcha for Enterprise Portal, SSO Improvements, Bug Fixes and more
### 🆕 New Features
- A [captcha](/enterprise-app-store/portal-settings#enable-captcha) security method has been added for Enterprise Portal logins, which can be configured to appear after a set number of unsuccessful login attempts, eventually blocking further access. This feature is available to organizations with an enterprise license.
- TLS versions can now be configured by self-hosted Appcircle server users for security purposes.
### :muscle: Improvements
- A logout URL option was added to SSO configuration settings, enabling users to choose between seamless SSO login/logout and fully ending the session, which requires re-authentication on the Identity Provider.
- SAML configurations can no longer be utilized in the “Create From Existing” feature for creating new SSO configurations.
- "SAML Service Provider EntityID" can now be updated when creating or updating the SAML configuration.
- The documentation URLs linked to the Help buttons have been updated to direct users to the appropriate documentation for SSO and LDAP configurations.
- Configuration labels within the LDAP Connection settings have been updated for self-hosted users.
- The priority levels of running builds are now displayed on the Active Processes tab.
- The build priority configuration setting is no longer restricted to organizations with an enterprise license.
- The default cloud pool names have been updated as follows: The “**Default M1 Pool**” is now labeled as “Appcircle Standard macOS Pool (arm64).” The “**Default Intel Pool**” is now labeled as “Appcircle Linux Pool (x86_64).”
- The build status information is now displayed in the [Signing Reports](/signing-identities/signing-reports) section within the signing identity module.
- An option was added to the SMTP server configuration in `global.yaml` to allow SSL validation to be disabled for non-production environments.
### 🐞 Fixes
- An issue was fixed where downloaded .yaml configuration files could not be uploaded to the same or other profiles of the same type, resulting in an error.
- An issue was fixed where the emails and roles of sub-organization users were not displayed in the signing activity log.
- Several security issues related to the admin module API were resolved.
- An issue was fixed where the custom domain Enterprise Store URL was not displayed at times in the Safari browser for self-hosted users.
- An issue was fixed where the claim name for Enterprise Portal SSO configuration was not displayed at times in the Safari browser for self-hosted users.
- An issue was fixed where some data loss occurred in the configurations during the update of SAML settings for SSO.
## 3.23.0 - 2024-11-04 SSO & LDAP Improvements, Build Priority Configuration, Bug Fixes and more
### 🆕 New Features
- Existing SSO & LDAP settings can now be duplicated when creating a new SSO or LDAP configuration.
- [Build priorities](/build/build-process-management/configurations#build-priority) can now be configured as **High**, **Medium**, or **Low** to manage the start order of queued builds accordingly. Available for organizations with Enterprise License.
### :muscle: Improvements
- The **Integrations** section of the Organization module was divided into two separate sections: **Security** and **Notifications**. Related settings can now be accessed under these sections.
- SSO and LDAP configurations for Enterprise Portal and Testing Portal access have been separated and can now be found under Authentication Settings within the Security section of the Organization module.
- The login and user management settings for SSO and LDAP have been separated into dedicated sections for authentication and authorization, offering improved clarity and control over the management of these configurations.
- A version option has been added in the Tuist component to allow installation of a specific Tuist version.
- The [Tuist Commands](workflows/ios-specific-workflow-steps/tuist-commands) step has been added to the Appcircle iOS workflow to enable execution of specific Tuist commands.
- [React Native UI Test](continuous-testing/react-native-testing/react-native-ui-test-with-detox) and [React Native Unit Test](continuous-testing/react-native-testing/react-native-unit-test-with-jest) components have been added to Appcircle workflows to enable the execution of unit and UI tests for projects on the React Native platform.
- Actions in the Signing Identity module can now be monitored within the [Activity Log](/signing-identities/signing-identities-activity-log) section.
- Informative screens were added to provide users with guidance when switching authentication methods from Testing Distribution or Enterprise App Store settings.
- ZIP upload support has been removed from the UI in the Testing Distribution module.
- [App Store Header](enterprise-app-store/portal-customization) setting has been added to the Enterprise Portal Customization section.
### 🐞 Fixes
- A typo in the organization member invitation email titles has been corrected.
- An issue was fixed where access to SSO Group/Role Mapping data was falsely restricted for users with the Organization Management - Viewer role.
- An issue was fixed where errors were encountered when using PR triggers for GitHub repositories.
- The app extractor command has been updated to support ZIP versions above 4.5 for APK and AAB files.
- An issue with the date range filter in build reports has been fixed.
- An issue has been resolved where the defined connections did not appear when attempting to reconnect after disconnection.
- An issue has been fixed where an unclear error message was displayed on Appcircle when the user of the connected GitLab repository had been deleted.
- An issue has been fixed where binaries marked as rejected within the publish module still had access to various binary actions.
- An issue has been fixed where the client ID in Enterprise App Store reports was displayed in a complex format; it is now shown in a clearer format.
- The user search filter will now be based on the selected filter items above, whereas it was previously independent.
- An issue has been fixed where icons for certain Android binaries were not displayed in the Enterprise App Store module for self-hosted users.
## 3.22.1 - 2024-10-18 Editing Environment Variables, Self Hosted Updates, Enterprise Portal Login Improvement, Bug Fixes and more
### 🆕 New Features
- Unhidden text and file-formatted environment variables within the build and publish modules can now be edited by users after registration.
- The Appcircle server version is now displayed in the blue bar at the bottom right corner of any page for self-hosted Appcircle server users.
- [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has [Xcode 16.2 Beta 1](https://developer.apple.com/documentation/xcode-release-notes/xcode-16_2-release-notes) installed on runners. Since this is a beta release, workflows should be tested extensively.
### :muscle: Improvements
- A password hide/show toggle was added to the Enterprise Portal login page for both static and LDAP authentication methods.
- The credentials for the Enterprise App Store static authentication channel will now be displayed accordingly if a password has been previously entered by the user.
### 🐞 Fixes
- An issue was fixed where publish environment variables did not function when created through a new variable group.
- An issue was fixed where using the `"` character in review notes or descriptions within metadata details caused errors when attempting to update the connected metadata details through the Publish module.
- An issue was fixed where multiline environment variables were causing errors during the “Send to TestFlight” publish step.
- An issue was fixed where empty metadata fields on Appcircle were being displayed as `null` on the App Store Connect side after updates.
- An issue was fixed where users with a ‘+’ in their email addresses could not be invited, re-invited to or deleted from an organization.
- An issue was fixed where users were granted access to incorrect organizations when using SSO authentication for Appcircle login.
- API request checks for Enterprise and Testing Portal logins were improved to display more accurate responses for security reasons.
- An issue was fixed where branches deleted from Azure repositories were not being removed from the Appcircle build profile.
- Security improvements have been made regarding cookies, including enhanced attributes, stronger encryption, and support for updated TLS versions.
- A bug that prevented configuring the IAM user decision strategy for self-hosted Appcircle server users has been fixed.
- An issue with LDAP authentication in the testing portal, effecting some users, has been fixed.
## 3.22.0 - 2024-10-04 Apple Devices, Build Report Improvement, Auto Cancel Redundant Pipelines, Bug Fixes and more
### 🆕 New Features
- Users will now be able to view [Apple devices](/signing-identities/apple-devices) registered in various stores, enable or disable selected devices, and save device information through email invitations within the Apple Devices section of Signing Identity module.
- Failed build steps are now visible within the build CSV reports, which can be downloaded from the Build History section.
- The "Auto Cancel Redundant Pipelines" option has been added to Build configurations, allowing users to automatically cancel redundant pipelines which was started or queued by triggers.
- [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has [Xcode 16.1 Beta 3](https://developer.apple.com/documentation/xcode-release-notes/xcode-16_1-release-notes) final release installed on runners. Since this is a beta release, workflows should be tested extensively.
- Self-hosted Appcircle users utilizing the DMZ structure can now configure the `auth` subdomain used for internet requests with a custom domain.
### :muscle: Improvements
- The LDAP role mapping configuration page now supports role search functionality.
- A warning message display was added for Inherited Sub-organization users during Personal Access Token generation.
- The SSO creation screen has been updated to ensure that the switch buttons reflect the actual backend status (on) after an SSO is created, preventing confusion for users.
- `Tolerant` user [lookup decision strategy](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings#editing-user-lookup-decision-strategy) has been added to the LDAP settings for self-hosted configurations.
- Store submit events were removed from the notification settings for Slack, MS Teams, and Email. Additionally, the module names within the configurations were updated.
- The Build Profile Search feature has been enhanced through integration with our backend systems.
- Builds that have completed with a successful output but contain a failed step will now be displayed with a warning status in the build lists and build profile cards.
- The logout option has been removed from the Enterprise Portal for non-authentication type logins.
- The Enterprise Portal will no longer display empty channels as selectable tabs if they do not have any active app versions.
- The self-hosted Appcircle server logs have been optimized.
### 🐞 Fixes
- An issue was fixed where, when pushing a tag for an old commit to GitLab, Appcircle incorrectly triggered a build for the latest/head commit on the same branch.
- An issue was fixed in the Appcircle UI where users received two separate notifications for the same tag creation when a tag webhook was received from the Git provider.
- An issue was fixed where, if the `AC_COMMIT_MESSAGE` variable contained more than two lines, the commit message was not displaying to the components.
- An issue was fixed where workflow and configuration files could not be downloaded by users through the admin module.
- An issue was fixed where the selected pool was not properly displayed in a cloned iOS build profile configuration.
- An issue was fixed where the help links for build workflow steps were not directing users to the relevant documentation.
- An issue was fixed where the link for build logs received via notification email was changing to an incorrect format upon being used.
- An issue was fixed where platform names, such as Android or iOS, were being displayed in lowercase within the Publish Activity Log area.
- An issue was fixed where the UI displayed a false error when users navigated to a sub-organization from a root organization with SSO configuration.
- An issue was fixed where the selected organization name was changing format when selected again within the SSO mapping configuration page.
- The warning message for invalid Google API Key uploads has been improved.
- An issue has been fixed where the add button remained active even without selecting any LDAP group within LDAP Mapping settings.
- The bug causing excessive CPU resource usage by the self-hosted Appcircle server after a deep health endpoint response has been resolved.
- A bug in `compose.yaml` file causing an error due to localization and decimal separator has been fixed.
- A bug that prevented labels from appearing in the self-hosted Appcircle server log monitoring UI has been fixed.
- An issue preventing the `auth` module page from being displayed in Swagger UI for self-hosted installations using self-signed certificates has been fixed.
### :warning: Breaking Changes
- Certain [role permissions](/account/my-organization/profile-and-team/role-management#signing-and-identity-permissions) from the Testing Distribution module related to the Apple Devices section have been migrated to the Signing Identities module.
- The Apple Devices section in the Testing Distribution module has been relocated to the Signing Identities module on the UI, along with its new capabilities.
## 3.21.0 - 2024-09-12 Publish Log Monitoring, SSO Mapping and Enterprise App Store Improvements, Xcode 16.0, Bug Fixes, and more
### 🆕 New Features
- Detailed logs can now be accessed and monitored in real-time as tasks are being published within the Publish module. This enhancement allows for improved tracking of progress, quick identification of issues, and ensures that tasks are processed as expected.
- A counter has been added to track the duration of each step when there is log activity in the Publish Details.
- A "None" authentication type has been added to the Enterprise App Store settings for logging into the Enterprise Store.
- The Notify action has been removed from the Enterprise App Store module.
- `.AAB` files can now be uploaded to profiles in the Enterprise App Store.
- The `.zip` file icon and description have been removed from the app version file type on the Testing Distribution page.
- [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has [Xcode 16.0](https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes) final release installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release.
### :muscle: Improvements
- The Authentications section is now hidden for sub-organizations.
- Deleted SSO mapping settings will no longer appear in new configurations, ensuring data integrity.
- The **Order** tab has been added to the LDAP creation settings.
- [The Android Increment Build and Version Number](/workflows/android-specific-workflow-steps/increment-build-and-version-number) workflow step is now compatible with Kotlin DSL projects, so that you can manage your app versioning within the Appcircle pipeline seamlessly.
### 🐞 Fixes
- An issue was fixed where foreign characters in `.IPA` files were preventing user artifact downloads within the Build module.
- An issue was resolved that prevented users from navigating between build steps while logs were being processed.
- An issue was fixed that could cause builds to be canceled due to a timeout on runners, particularly on self-hosted installations using a custom timezone in the runner.
- An issue was resolved where the custom domain toggle remained enabled in the UI after being disabled.
- An issue with the search filter on Enterprise App Store reports has been fixed.
- An issue was resolved where the organization filter did not have a default value on Enterprise App Store reports section.
- An issue was resolved where users were able to upload Android keystores with the same name.
- An issue was fixed where new users could be invited despite the Single Sign-On (SSO) mapping feature being enabled.
- An issue was fixed where owner users could be deleted while handling SSO mapping.
- An issue was fixed where SSO mapping skipped users with the manager role, leaving their memberships and roles unchanged.
- An issue was fixed that affected access to other sub-organizations when SSO mapping was enabled.
- Resolved an issue where shared apps are now displayed at the top of the list with the Testing Portal.
## 3.20.5 - 2024-09-02 Android Publish Improvements, In-app Updates and more
### 🆕 New Features
- [In-app updates](/enterprise-app-store/in-app-updates) can now be checked and downloaded via a profile-specific In-App Update Secret using your store URL.
- In-App Update Secrets can now be created specifically for each Enterprise App Store profile within the profile settings.
- [Google Play Console App Information](/publish-to-stores-module/publish-information/google-play-information), such as primary language and contact info, can now be retrieved and updated for Android via Publish Module.
- [Google Play Console Metadata](/publish-to-stores-module/publish-information/meta-data-information#android-metadata-information) can now be managed and imported on AppCircle, including the editing of localizations and screenshots.
### :muscle: Improvements
- Testing Distribution profiles with public access enabled are now accessible to all users with active authentication within the Testing Portal.
- Testing Group members can now be [imported](/testing-distribution/testing-groups#importing-testing-group-members-via-ldap) through registered LDAP groups.
- Help documentation and guides are now accessible based on the app and certificate type after downloading apps from the Testing Portal.
- [Android profile creation](/publish-to-stores-module/creating-publish-profiles#android-publish-profiles) has been separated into two options: you can either create a profile manually by typing the package ID, or select it from the Google Play Console using API credentials.
### 🐞 Fixes
- A UI issue where one of the provisioning files on the build configuration list disappeared when adding a new one has been fixed.
- The issue where the order of self-hosted runners changed after each refresh has been fixed.
- The issue where the admin module's build details failed to display logs properly for resign activities within the publish module has been resolved.
## 3.20.4 - 2024-08-20 Role Management Updates, Testing Distribution & Enterprise App Store Improvements, Xcode 16.1 Beta 1, Bug Fixes, and more
### 🆕 New Features
- Default roles are now shown when inviting users to an organization, both in the UI and through the [CLI](appcircle-api-and-cli/cli-authentication). This enhancement ensures clarity and ease of role assignment during the user invitation process.
- The ability to assign multiple module roles to users has been introduced, allowing for greater flexibility and more refined [role management](/account/my-organization/profile-and-team/team-management#advanced-role-management) within the system.
- A new [Membership](/account/my-organization/profile-and-team/team-management#advanced-role-management) column has been added, displaying values as `Member` or `Inherit`, and the `Assigned` label has been removed as it is no longer necessary.
- A new sub-organization filter has been added to the user list, allowing for more precise filtering and [user management](/account/my-organization/profile-and-team/team-management) within sub-organizations.
- Support for [downloading](/testing-distribution/create-or-select-a-distribution-profile#download-binary) binary in the Testing Distribution module has been added. New or updated endpoints have been documented in Swagger, enabling easy integration and automation for customers.
- A new feature has been added that allows profiles marked as `Show on Top` in the Enterprise App Store to have all their shared app versions appear at the top of the store.
- The email provider used for email notifications can now be configured via `global.yaml`, which aids in troubleshooting some SMTP issues.
- [Xcode 16.1 Beta 1](https://developer.apple.com/documentation/xcode-release-notes/xcode-16_1-release-notes) has been installed on runners in the [Appcircle Standard macOS Pool (arm64)](infrastructure/ios-build-infrastructure). Since this is a beta release, workflows should be tested extensively.
### :muscle: Improvements
- To prevent confusion during LDAP integration for Appcircle Login in Self-Hosted environments, the `Username` field and associated information text on the LDAP configuration page have been updated.
- The visibility of user roles has been updated to ensure that roles are viewable even when organization permissions are not granted. This change allows users to see their roles regardless of their organizational access levels.
- Users with `Login` status will now appear at the top of the user list for easier identification.
- The user list has been updated to sort users alphabetically in [Team Management](account/my-organization), following the order: Own, Pending, Accepted, and Members.
- Password values in the UI for [Testing Distribution Settings](testing-distribution/create-or-select-a-distribution-profile#authentication) authentication are now hidden. This enhancement improves security by preventing sensitive information from being displayed, thereby protecting user credentials from unauthorized access.
- The performance of the [Testing Portal](testing-distribution/testing-portal) has been enhanced to achieve faster load times.
- An additional rule has been implemented to prevent the deletion of deployed versions marked as `Live` or `Beta` in the Enterprise App Store.
- An updated warning message will now be shown if the notify button is used without LDAP or SSO authentication. The message will also be tailored to cases where no emails are entered in the [***Manage Access***](enterprise-app-store/enterprise-app-store-profile#manage-access) settings, ensuring clearer notifications.
- A new rule set has been implemented in the Enterprise App Store to prevent the [deletion of versions](enterprise-app-store/enterprise-app-store-profile#delete) marked as `Live` or `Beta`. RC-marked versions cannot be deleted, the delete buttons for Live and Beta versions have been disabled. To delete these versions, they must first be unpublished
- The Build Module has been updated to enforce uniqueness for all [workflow](workflows) step names. This enhancement was implemented to prevent potential conflicts caused by duplicate names, thereby improving the clarity and reliability of build workflows.
- The ability to cancel the publishing process, as well as triggered and tagged builds, has been introduced.
- The Store Submit display has been removed from the Self-Hosted dashboard.
### 🐞 Fixes
- The issue where the Integration & Connection Viewer permission did not properly restrict access to connection-related actions has been fixed. Users with this permission can now view the Manage button but are correctly restricted from performing any connection actions, ensuring stricter control over connection management.
- The issue where the SSO mapping enable/disable button was not working properly has been fixed.
- The issue where users could not search with partial words in the email filter of the Team Activity Log has been fixed.
- The issue where users could not reassign the owner role in some cases has been fixed.
- The issue where the side window did not close properly after a Resign operation has been fixed. This update ensures that the side window now closes correctly, preventing any confusion about the successful completion of the operation.
- The issue where the distribution date in the Testing Portal displayed the previous version's distribution date when a version was resent to a tester has been fixed.
- The issue where metadata updates could not be made for app versions marked as Release Candidate (RC) has been fixed.
- The issue where the system did not automatically select an active and suitable pool from the company's self-hosted options when no pool was selected during the publish process has been fixed.
- The issue where the Redis connection was throwing a readonly error for replica write on self-hosted Appcircle servers has been fixed.
- The issue with incorrect URLs in short links has been fixed, allowing seamless sharing of short URLs using the Copy Shortlink feature in the self-hosted server [Monitoring](self-hosted-appcircle/install-server/linux-package/configure-server/monitoring#accessing-to-grafana-web-ui) UI.
- The issue that caused runner IP addresses to appear as 127.0.0.1 in the build logs and runner details on the self-hosted Appcircle server has been fixed.
- The issue that created a broken system configuration file during the installation of the self-hosted Appcircle server using the Podman container engine has been fixed.
## 3.20.1 - 2024-08-05 - Role Management Updates, Enterprise App Store and Publish Improvements, Xcode 16.0 Beta 5, Bug Fixes and more
### 🆕 New Features
- [The Publish Environment Variables](/account/my-organization/profile-and-team/role-management#publish-environment-variables) Module has been added within the role management with Manager and Viewer roles.
- [Integrations and Connection Management](/account/my-organization/profile-and-team/role-management#integrations-and-connection-managements) roles have been added within the role management with Manager and Viewer roles.
- The Viewer role has been added for [Organization Management](/account/my-organization/profile-and-team/role-management#organization-management-permissions).
- Hyperlink support has been added to the affected build profiles on the pop-up screen when a user attempts to delete a provisioning profile that is active in a build configuration.
- The self-hosted Appcircle server script now includes a new command ([**init**](/self-hosted-appcircle/install-server/linux-package/index.md#initialize-vault)) that should be used after the `export` step once while installing the server, ensuring seamless vault initialization.
### :muscle: Improvements
- The Credentials and Authentications sections have been separated within the Integrations area of the organization module.
- The rule feature has been added to the cards in the Publish flow editor.
- Multiple app version delete support has been added for Enterprise App Store and Publish modules.
- UI Improvements have been made for Enterprise App Store and Publish modules regarding overall texting and profile cards.
- The profile IDs of Enterprise App Store and Testing Distribution profiles can now be copied from their settings section.
- The notify button will no longer be disabled if the user has static authentication; instead, a warning message will be shown.
- The self-hosted Appcircle server configuration file validator now checks the integrity of [Enterprise App Store](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration.md#custom-domain) and [Testing Distribution](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration.md#custom-domain-1) ports defined in `global.yaml`.
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has [Xcode 16.0 Beta 5](https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes) installed on runners. Since this is a beta release, please test your workflows extensively.
### 🐞 Fixes
- The issue where the Runner Access Token did not display the warning text properly after generation has been fixed.
- An issue where SSO login redirect flows were causing access denied errors has been fixed.
- An issue where the metadata localization list was not alphabetical has been fixed.
- An issue where metadata screenshots were displayed in the wrong order on some occasions has been fixed.
- An overall improvement has been made to the request states of the UI, resolving issues such as un-centered status texts.
- An issue where removing a localization setting affected uploads on metadata within the publish module has been fixed.
- An issue where archived logs were not being shown in the Publish History has been fixed.
- An issue where the UI was not displaying an error message when the user uploaded a certificate that already existed or entered the wrong password has been fixed.
- A texting issue on the UI that occurred while manually uploading app versions within the Testing Distribution Profile has been fixed.
- A problem with routing when users do not have distribution settings in the configuration has been fixed.
## 3.20.0 - 2024-07-29 - Role Management Updates, Testing Distribution and Publish Improvements, Xcode 16.0 Beta 4, Bug Fixes and more
### 🆕 New Features
- Publisher and contact information, along with Privacy Policy and Terms of Service URLs, can now be viewed and updated under the [Info tab](/testing-distribution/create-or-select-a-distribution-profile#config) within the Testing Distribution profile settings. This information will be displayed on the Testing Portal.
- [Shared App Profiles](/testing-distribution/testing-portal#navigating-between-shared-app-profiles) will now be displayed within the Testing Portal. This will allow the users to view and navigate between different Testing Distribution Profiles that have shared app versions for the same user.
- For each app version, the file size and certificate version will now be shown within the [Testing Portal](/testing-distribution/testing-portal).
- A new [user menu](/testing-distribution/create-or-select-a-distribution-profile#config) has been added to the Testing Portal, where the testing distribution profile's publisher information, login method, and a logout button are displayed.
- When downloading app versions with an enterprise-type certificate within the Testing Portal, a [guidance message](/testing-distribution/testing-portal) will now be displayed.
- Submissions with "Waiting for Review" or "In Review" status can now be [cancelled](/publish-to-stores-module/publish-information/cancel-submission) on App Store Connect.
- App versions can now be [rejected](/publish-to-stores-module/publish-information/reject-binary) by users with Manager and Operator roles. Rejected app versions cannot be marked as RC (Release Candidate); they can only be deleted or viewed. The same version can also be re-uploaded for rejected items.
- [App Center Migration Tool](/appcircle-api-and-cli/appcenter-migration-tool), can now be used to assist organizations and individuals in migrating their Visual Studio App Center projects, including organizations, collaborators, app profiles, and test groups, to Appcircle effortlessly.
### :muscle: Improvements
- The role structure has been expanded, with new roles added and existing roles updated. For more details, please visit the [Role Management](/account/my-organization/profile-and-team/role-management) page.
- French language support has now been added to [The Testing Portal](/testing-distribution/testing-portal).
- [Default environment variable](/publish-to-stores-module/publish-variables#reserved-variables) names have been updated. The old naming convention should no longer be used, as all Appcircle-provided default values now starts with `AC_`.
- Environment variables can now be used in metadata, app info, and Intune metadata forms within the Publish Module.
- App versions that are published to the Beta and Live channels will now be displayed on Enterprise App Store profile headers with related tags, both within the profile and the Enterprise App Store profile list, for easier visibility.
- UI improvements have been made to the actions menu of Enterprise App Store profiles.
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has [Xcode 16.0 Beta 4](https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes) installed on runners. Since this is a beta release, please test your workflows extensively.
### 🐞 Fixes
- A UI issue has been fixed related to SSO Mapping toggle.
- An issue with the search by action filter in the Team Activity Log has been fixed, where the first available option was not displaying any results.
- A related message will now be received upon saving if deprecated components are present in the Publish Flow.
- An issue has been fixed regarding the what's the new component of metadata details within the Publish module.
- An issue has been fixed regarding renewing provisioning profile by adding hour and minute to the naming convention for Renewed Provisioning Profiles, allowing renewals on the same day.
- A UI problem affecting Safari browsers has been fixed for the App Detail preview screen in the Enterprise App Store customization section.
- An issue has been fixed where user color selections were not immediately displaying on the preview screen within the Enterprise App Store customization section.
- An issue has been fixed where colors could not be updated without also updating the store title within the Enterprise App Store customization section.
- An issue related to long texts affecting the Enterprise App Store display has been fixed by applying a character limit to the Summary and Release Notes sections of the Publish to Store feature within the Enterprise App Store module.
- A UI problem has been fixed where the save button for the static login configuration of the Enterprise App Store module remained enabled even without any changes.
- An issue has been fixed regarding binary upload process by adding status checks and failing the task if the binary could not be processed.
### :warning: Breaking Changes
- New Ext. Operator Role has been added to Enterprise App Store, Testing Distribution and Publish modules.
- The Uploader role has been removed from the Enterprise App Store module and migrated to the Operator role. Additionally, the previous Operator role has been migrated to the Ext. Operator role.
## 3.19.1 - 2024-07-04 - Publish and Signing Identity Module Improvements, Xcode 16.0 Beta 3, Bug Fixes and more
### 🆕 New Features
- The store status of Release Candidates in the Publish profiles can now be manually checked using [Check Release Status](/publish-to-stores-module/publish-information/check-release-status) feature.
- The self-hosted Appcircle server now supports a new [DMZ architecture](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz), allowing you to separate [Enterprise App Store](/enterprise-app-store) and [Testing Distribution](/testing-distribution) modules from the core and install them in a DMZ [(Demilitarized Zone)](https://en.wikipedia.org/wiki/DMZ_(computing)). This securely exposes these external-facing modules to internet users.
### :muscle: Improvements
- The [Appcircle Standard macOS Pool (arm64)](/infrastructure/ios-build-infrastructure) has [Xcode 16.0 Beta 3](https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes) installed on runners. Since this is a beta release, please test your workflows extensively.
- To ensure the validity of the Microsoft Intune remote app connection, the binary will be unmarked as a Release Candidate after switching from other credentials to Microsoft Intune. Additionally, .aab format binaries will display a warning message when using Microsoft Intune credentials, as they are not supported.
- Help documentation for [Update Metadata on Microsoft Intune](/publish-integrations/common-publish-integrations/update-metadata-on-microsoft-intune) feature has been updated.
- Microsoft Intune metadata and App Info updates are now included in the Activity Report.
- App Store Connect App Info & Metadata and Microsoft Intune Metadata are now available through [Open API](https://api.appcircle.io/openapi/index.html?urls.primaryName=publish).
- Multiple Bundle IDs can now be selected when importing from App Store Connect.
- All Publish artifacts including the binary, metadata details, screenshots, App Store Connect information, and more can now be downloaded a zip file.
- When [inviting a new user to an organization](/account/my-organization/profile-and-team/team-management), a warning message will now be displayed if an invalid or already in-use email address is entered.
- Existing and newly invited organization members can now be [searched by e-mail filter](/account/my-organization/profile-and-team/team-management) within the Team Management area.
- When attempting to delete a provisioning profile that is already in use for a build profile, a warning message will now display. This allows you to see the affected profiles and navigate directly to their configuration. Alternatively, you can force delete the provisioning profile.
- When a Provisioning Profile within the Apple Profiles section has a mismatched Apple Certificate, a tool tip warning message will display.
- Upload multiple files at once with the new [Apple Provisioning Profile](/signing-identities/apple-profiles#upload-a-provisioning-profiles) file upload improvement.
- Multiple Provisioning Profiles can now be [force deleted](/signing-identities/apple-profiles#deleting-provisioning-profiles) by the users.
### 🐞 Fixes
- A behaviour difference between Appcircle UI and App Store Connect while registering Bundle IDs has been fixed.
- An issue causing indicator truncation while retrieving provisioning profiles in the Publish Module has been fixed.
- An issue has been fixed where, if no images are present in the metadata screenshot section for different localization settings, images from the primary language were not being displayed for guidance and explanatory purposes.
- The Publish profile header will no longer display the latest store status if the binary is unmarked as a release candidate.
- The errors that occurred on some types of projects during [Android versioning](https://docs.appcircle.io/versioning#understanding-android-versioning) were fixed, and several improvements were made to check for invalid versioning.
- An issue has been resolved where the [Increment Version and Build Number for Android](/versioning/android-version) step caused formatting errors in Gradle files that use dynamic logic for versioning.
- An issue has been fixed where build profile cards displayed some build results as text instead of an icon.
- An issue has been fixed where users with specific profiles encountered access problems when navigating between organizations.
- Improved and fixed help documentation links within the Signing Identities module for [Apple Profiles](signing-identities/apple-profiles), [Apple Certificates](signing-identities/apple-certificates) and [Apple Identifiers](signing-identities/apple-identifiers).
## 3.19.0 - 2024-06-27 - Publish Apps to Microsoft Intune, App Store Connect Integration, Publish and Signing Identity Enhancements, Xcode 16.0 Beta 2, Bug Fixes and more
### 🆕 New Features
- Apps can now be sent to [Microsoft Intune](/publish-integrations/common-publish-integrations/send-to-microsoft-intune) and their metadata can be updated within the Publish module.
- Saved [Microsoft Intune](/publish-integrations/common-publish-integrations/send-to-microsoft-intune) credentials can now be used with the Publish Profiles by integration.
- Profiles can now be directly listed and imported from App Store Connect within the Publish module.
- [Bundle Identifiers](/signing-identities/apple-identifiers#edit-bundleid) in Apple Appstore can now be directly managed through the Appcircle interface.
- A Publish Profile can now be created for existing apps from [App Store Connect integration](/publish-to-stores-module/creating-publish-profiles#create-from-app-store-connect).
- [App Store Connect Information](/publish-to-stores-module/publish-information/app-information) has been added within the Publish module where users can update the required information for binary submission.
- A new Provisioning Profile can now be created by selecting [Apple Profiles](/signing-identities/apple-profiles) (Formerly known as Provisioning Profiles) within the Signing Identities module.
- Provisioning Profiles can now be [renewed](/signing-identities/apple-profiles#profile-actions) within the Signing Identities module.
- An [Apple Identifiers](/signing-identities/apple-identifiers) section has been added within the Signing Identities module.
- A new value display and filter have been added to the LDAP Mapping table.
- Group and role management can now be automated with [SSO](/account/my-organization/security/authentications/sso-authentication) for Appcircle Login.
- Efficiently distribute your apps using Appcircle’s Testing Distribution and Enterprise Store plugins, available on [GitHub](/marketplace/github-marketplace), [Fastlane](/marketplace/fastlane), and the [Visual Studio Marketplace](/marketplace/visual-studio-marketplace).
### :muscle: Improvements
- [Xcode 16.0 Beta 2](https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes) has been installed on the [Appcircle Standard macOS Pool (arm64)](https://docs.appcircle.io/infrastructure/ios-build-infrastructure) runners. As this is a beta release, workflows should be tested extensively.
- iOS binaries can now be resigned via the UI by directly providing the entitlements, without needing to upload an XML file.
- Any [Bundle ID](/publish-to-stores-module/binary-management) can now be uploaded inside a publish profile for resign purposes. However, marking it as RC (Release Candidate) will not be possible if the app version's Bundle ID does not match the profile's main Bundle ID.
- Store connections will be displayed on the Publish profile cards to indicate if the profile is connected to a store such as Microsoft Intune or App Store Connect.
- Latest Metadata will now be cloned to newly uploaded app versions by default.
- The ["Add for Review"](/publish-integrations/ios-publish-integrations/add-for-review-on-app-store) step has been added to the Appstore Publish Flow within the Publish module.
- The ["Send to Enterprise App Store"](/publish-integrations/common-publish-integrations/send-to-enterprise-app-store) step has been added to the Appstore Publish Flow within the Publish module.
- Publish profile updates can now be viewed on the main dashboard.
### 🐞 Fixes
- An issue where users were unable to save the Xcode version on React Native build profiles without providing the optional Node.js version has been fixed.
- An issue has been fixed where a remotely triggered build via GitLab connection showed an incorrect branch name in the Appcircle UI during the build process.
- An issue has been fixed where multiple remotely triggered builds via GitLab, affecting a single pipeline, was showing incorrect build status in the Appcircle UI.
- An issue where localization settings caused duplicated screenshots in the Metadata Information section has been fixed.
## 3.18.0 - 2024-05-31 - Build Enhancements, Appcircle CLI v2.2.0, Publish Improvements and more
### 🆕 New Features
- We have significantly enhanced the performance of the build log stream feature, ensuring faster and more efficient logging processes.
- We are releasing [Appcircle CLI v2.2.0.](https://github.com/appcircleio/appcircle-cli/releases/tag/v2.2.0)
- Users can now change the order of screenshots and previews by drag and drop in [Metadata Information](https://docs.appcircle.io/publish-to-stores-module/publish-information/meta-data-information) within the Publish Module.
- The Testing Distribution profiles now include the signed or unsigned status information for app versions.
### :muscle: Improvements
- Resign History and Publish History components have been unified under a new History component within the Publish module.
- Users will now be able to see which version was used to resign the app after resigning an app version within the Publish module.
- The default build workflows have been updated to enhance functionality and improve the user experience. Therefore, it can be assured that the steps in the default workflows are also up-to-date.
### 🐞 Fixes
- We have resolved issues that could cause crashes when running multiple builds simultaneously, enhancing the overall stability and reliability of the build process.
- We have enhanced security for remote repository connections in the Build module.
- Fixed an issue where build logs were being saved prematurely due to a time synchronization problem, causing logs to be saved before the end of the process.
- Fixed an issue where API returned incorrect response code for requests with invalid commitId or buildId.
- Fixed an issue where the Admin Build Details section showed incorrect build status for cancelled builds.
- Fixed an issue in Jira comments where new lines were not rendered when using [Jira REST API v2](https://docs.appcircle.io/workflows/common-workflow-steps/jira-comment#jira-rest-api-version-reference), as the payload was previously received as plain text.
- Fixed an issue where users couldn't send release notes for binaries via 'Send to Google Play'.
- Fixed an issue where the Publish Flow did not display the final step after successfully completing the process.
## 3.17.1 - 2024-05-23 - Publish Activity Log Enhancement, Send to Microsoft Intune, Publish Module Bug Fixes
### 🆕 New Features
- We have added the [Send to Microsoft Intune](https://docs.appcircle.io/publish-integrations/common-publish-integrations/send-to-microsoft-intune) Component to our available [Publish Flow](https://docs.appcircle.io/publish-to-stores-module/publish-flow) steps for Intune Store publishing.
### :muscle: Improvements
- You can now monitor [Resign Binary](https://docs.appcircle.io/publish-to-stores-module/publish-information/resign-binary) activities in Publish Activity Logs.
- We have added minimum and maximum e-mail format validations for the [Get Approval via E-mail](https://docs.appcircle.io/publish-integrations/common-publish-integrations/get-approval-via-email) Publish Flow step.
- The [auto-update](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/configure-server/auto-updating) helper tool has been improved to detect the upgrade in a more efficient way, which reduces the network payload and speeds up the process.
### 🐞 Fixes
- Fixed an issue where the restart flow rule failed in certain cases, causing invalid flow validations within the Publish Module.
- Fixed issues where the API allowed requests with duplicate and blank [Publish variable](https://docs.appcircle.io/publish-to-stores-module/publish-variables) and group names.
- Fixed an issue where [Store Status](https://docs.appcircle.io/publish-to-stores-module/binary-management#store-status) received from the Get Approval from Test Flight or Get Approval from App Store steps was not being displayed on the AppVersion's and Profile's Store Status.
- Fixed a bug at the [Jira Comment](https://docs.appcircle.io/workflows/common-workflow-steps/jira-comment) step that was throwing an unexpected JSON parse error when using [Jira REST API v3](https://docs.appcircle.io/workflows/common-workflow-steps/jira-comment#jira-rest-api-version-reference) and ensured the integrity of the payload for commit messages containing line breaks.
- Fixed a bug that was affecting Appcircle UI notifications such as build success, failure, etc.
- Fixed a problem that caused the self-hosted Appcircle server logging service to not start and work correctly when using the root user.
## 3.17.0 - 2024-05-17 - LDAP Mapping Improvements, Publish Module Bug Fixes, and more
### 🆕 New Features
- Users can now automate [Group](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings#managing-ldap-groups-and-mappings) and [Role](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings#ldap-role-mapping) Management using LDAP Authentication for Appcircle Login in Self-Hosted environments.
- We have introduced the [Team Activity Log](https://docs.appcircle.io/account/my-organization/profile-and-team/team-activity-log) feature within the Organization settings. This feature enables users to monitor team management actions within their organization if they are the organization owner or have the Organization Management role.
- The self-hosted Appcircle server now has a new configuration at `global.yaml` that helps you [enable or disable](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/configure-server/monitoring#disable-the-monitoring-services) the log monitoring feature on demand.
### :muscle: Improvements
- The ["Get Approval via Email"](https://docs.appcircle.io/publish-integrations/common-publish-integrations/get-approval-via-email) component now allows you to view the statuses of all users in its logs.
- We have added an activity log for updates to Release Notes on the [Metadata Information](https://docs.appcircle.io/publish-to-stores-module/publish-information/meta-data-information) page within the Publish Module.
- Self-hosted users can now choose to hide the Change Password option in the account settings page by disabling the Forgot Password option in Self-Hosted Settings.
- We have added the ability for Jira Enterprise users to choose the API version.The [Jira Comment](https://docs.appcircle.io/workflows/common-workflow-steps/jira-comment) workflow step now supports both Jira Cloud and On-Prem use cases for both Jira API v2 and v3, which makes the integration more flexible.
- We have updated the documentation links on the workflow steps to enable users to access the most current and detailed documents for integration purposes.
### 🐞 Fixes
- Performance improvements have been made on the [Testing Distribution Portal](testing-distribution/testing-portal).
- If the **Auto-Register** feature is disabled on the [Testing Distribution Profile](https://docs.appcircle.io/distribute/create-or-select-a-distribution-profile), the **Register Device** button will now be hidden on the [Testing Distribution Portal](https://docs.appcircle.io/distribute/downloading-binaries). Additionally, various typos and UI issues on the [Testing Distribution Portal](https://docs.appcircle.io/distribute/downloading-binaries) have been fixed.
- Deleting a [Release Candidate](https://docs.appcircle.io/publish-to-stores-module/publish-information/marking-release-candidates) app version is now prevented; users must unmark it from being a [Release Candidate](https://docs.appcircle.io/publish-to-stores-module/publish-information/marking-release-candidates) before deletion.
- Release Notes can now only be changed for [Release Candidate](https://docs.appcircle.io/publish-to-stores-module/publish-information/marking-release-candidates) app versions.
- Fixed an issue requiring a refresh for event-based logs in the Get Approval via Email component.
- A bug was fixed where deleting an app version that leaves no app versions in the Publish Profile, resulted in incorrect information being displayed in the header.
- Fixed an issue where a refresh was causing a problem in the Publish Flow log panel.
- A bug was fixed where test submissions with missing compliance did not display a warning message about resolving the compliance issue before test submission to internal or external groups.
- Fixed a bug on UI where an app version name was cut short due to Release Candidate badge , also affected the other app version names within Publish Profile.
- An issue was fixed where, during the resigning of an .IPA binary, the sign button was enabled despite no Provision Profile being selected.
- An issue regarding the positioning of the Provisioning Profile and Read-Only Bundle ID options within Resign Binary feature has been fixed.
- The broken Jira transitions that the [Jira Comment](https://docs.appcircle.io/workflows/common-workflow-steps/jira-comment) step is making are now fixed so that you can update the status of Jira issues in the build pipeline.
- Android apps with special characters in their names now proceed without errors during signing and other steps.
- A bug fix has been applied to the auto distribution and publish features to address issues with non-existing Testing Distribution and Publish Profiles.
- Fixed the incorrect versioning of the [Gradle Runner](https://docs.appcircle.io/workflows/android-specific-workflow-steps/gradle-runner) step, which was breaking current workflows because of incompatible changes.
- [Testinium](https://docs.appcircle.io/workflows/common-workflow-steps/testinium-steps/testinium) step dependencies are defined for the workflow editor so that the user can easily include the integration in the correct order.
- [Maestro Cloud Upload](https://docs.appcircle.io/workflows/common-workflow-steps/maestro-cloud-upload) step dependencies are defined for the workflow editor so that the user can easily include the integration in the correct order.
- Fixed a bug that caused the [no-proxy](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration#edit-no_proxy-for-internal-container-network) helper tool to throw an error when the CIDR notation was used in the `no_proxy` environment variable.
- Fixed a bug that prevented the self-hosted Appcircle server logging service from being healthy when a proxy is used for network access.
- Fixed a bug that causes the wrong self-hosted server package to [download](https://docs.appcircle.io/self-hosted-appcircle/update#1-download-latest) when a specific version is preferred instead of the latest.
## 3.16.0 - 2024-05-10 - New features in Publish Module, Resigning Binary, Xcode 15.4, and more
### 🆕 New Features
- The [Resign Binary](/publish-to-stores-module/publish-information/resign-binary) feature is now available for both iOS and Android applications within the Publish module.
- Users can now upload application screenshots and update [Metadata Information](https://docs.appcircle.io/publish-to-stores-module/publish-information/meta-data-information) within the Publish module, including promotional text and descriptions, via Appcircle, without the need for the App Store Connect interface.
- Within the Publish profile card, App Store Status will be displayed for Enterprise users, while Flow Status will be observed for non-enterprise users. Similarly, in the app version view, Enterprise users will have access to both Flow and App Store Status, whereas non-Enterprise users will only see Flow Status displayed.
- A new component named "Update Metadata on App Store" has been integrated to the Publish Steps section, facilitating the display of metadata information.
- On the Metadata Information page, metadata for profiles designated as Release Candidates is retrieved directly from the store. For more information, refer to the [Metadata Information](/publish-to-stores-module/publish-information/meta-data-information) documentation.
- Users uploading .AAB files can now share the app version with testers within the [Distribution](/testing-distribution) module.
- The install certificate tool bundled in the runner package now supports proxies when connecting to remote URLs on macOS.
- The [Signing Identities](/signing-identities) module features are now accessible via the command-line interface. Learn more.
- You can now manage [Testing Groups](testing-distribution/testing-groups) within the [Distribution](/testing-distribution) module via the command-line interface.
- Users can configure [Distribution](/testing-distribution) settings to [automatically send builds to testers](/testing-distribution/create-or-select-a-distribution-profile#manual-binary-upload) using the command-line interface.
- The "Default M1 pool" and "macOS VM image" now include [Xcode 15.4](https://docs.appcircle.io/infrastructure/ios-build-infrastructure#available-xcode-versions) installed on runners. We strongly recommend extensive testing of your workflows to ensure compatibility and stability with this release candidate.
- This release introduces [a log viewing and delivery system](https://docs.appcircle.io/self-hosted-appcircle/configure-server/monitoring) for the self-hosted Appcircle server.
- Self-hosted customers can now [download](https://docs.appcircle.io/self-hosted-appcircle/configure-server/auto-updating) the Appcircle server package seamlessly and [update](https://docs.appcircle.io/self-hosted-appcircle/configure-server/auto-updating) the Appcircle server fully automated.
### :muscle: Improvements
- Users now have the capability to download comprehensive data associated with the app version, encompassing publish logs, metadata, screenshots, and build logs.
- Users can now prepare and transmit screenshots and metadata to the App Store through the newly integrated metadata component.
- Users can now seamlessly import metadata and screenshots from App Store Connect to establish the initial state on the Update Metadata screen.
- The Appcircle runner package now includes a diagnostic tool that helps to identify, analyze, and troubleshoot system issues.
- Self-hosted Appcircle clients can now [download and extract](https://docs.appcircle.io/self-hosted-appcircle/self-hosted-runner/runner-vm-setup#download-the-macos-vm-and-xcode-images-automatically) the runner macOS VM in the background more robustly, particularly in cases of network connection faults.
- The install certificate tool included in the runner package, which trusts CA certificates, now extends support to Java 8, 17, and 21.
- We have added an App Store Status field within Publish Profiles and App Versions lists, providing regular updates at 30-minute intervals. For further details, please refer to the [App Store Status](/publish-to-stores-module/binary-management#store-status) documentation.
:::caution
To ensure the App Store status remains current, the following conditions must be met:
- The current profile necessitates valid store credentials defined within the Signing Identity module and must be selected.
- Alignment of the published app's identifier, version, and build number with the Appcircle app version records is essential.
- Identification of one of the app version records as the designated release candidate is required.
- The service will continue updating the app status until it reaches the 'READY_TO_SALE' or 'READY_TO_DISTRIBUTE' states.
- Initially, the service checks the App Store status; in the event of no matching records, it subsequently conducts a search within TestFlight.
:::
### 🐞 Fixes
- The self-hosted runner macOS installation now detects Homebrew anomalies that can occur after macOS upgrades and reinstalls Homebrew with package upgrades.
- Fixed various bugs that occurred during the installation of the self-hosted runner on GNU/Linux.
- Made improvements and fixed various bugs in the install certificate tool bundled in the runner package.
- Fixed a bug in the self-hosted version that prevented listing the Xcode version for the selected pool.
- Fixed a bug that caused errors during the parsing of large AAB files.
- Fixed a bug that caused the last build time within the build profile appearing as null when a user deleted old builds.
## 3.15.0 - 2024-04-24 - AAB to APK, Improved Testing Distribution, Publish Event Enhancement
### 🆕 New Features
- [The distribution link](testing-distribution/create-or-select-a-distribution-profile#distribution-link) in the distribution settings has been transformed into a QR code to simplify access and sharing.
- Users can now filter the app version list on [the testing portal](testing-distribution/testing-portal) by app name, version, release notes, or build number for enhanced navigation and search capabilities.
- The system now automatically converts uploaded or built AAB files to a universal format. It also discreetly saves the newly created APK file with the second app's resource id.
- A new command, ["build active-list"](https://docs.appcircle.io/appcircle-api-and-cli/) has been added, allowing users to view active builds in the queue directly from their command line interface.
- A new command, ["build view"](https://docs.appcircle.io/appcircle-api-and-cli/) has been added, enabling users to access and view detailed information about builds directly from the command line interface.
- The "Appcircle Standard macOS Pool (arm64)" now includes [Xcode 15.4 beta-1](https://docs.appcircle.io/infrastructure/ios-build-infrastructure#available-xcode-versions) installed on runners. As this is a beta release, we strongly recommend testing your workflows extensively to ensure compatibility and stability.
### :muscle: Improvements
- We have introduced new [Publish Events](https://docs.appcircle.io/publish-to-stores-module/) like Publish Profile Created, Publish Profile Deleted, App Version Uploaded, App Version Created, and App Version Deleted to enrich the activity report.
- We have fine-tuned branch search and filter operations for faster performance and smoother functionality.
- We have introduced the capability for active users to store profile pins (Enterprise store profile, Distribution profile, Build Profile, and Publish Profile) individually. Previously, profile pins were stored solely on an organization-wide level. Now, each active user can set and manage their own pin independently, providing greater flexibility and customization options.
- Added [Okta](/account/my-organization/security/authentications/sso-authentication#4-specific-provider-configuration) tile based login so users can log in to the Appcircle dashboard by clicking the Appcircle app icon on Okta side.
### 🐞 Fixes
- We have fixed a bug that caused the report to update only once due to discrepancies between canceling after the build starts and canceling before it starts.
- Fixed an issue where manual distribution resulted in errors when attempting to install an already existing version. Now, a pop-up warning is displayed in such cases.
- Fixed the issue of undefined workflow name in the 'listBuildProfileWorkflows' command.
- Fixed "workflowName" parameter in the "build start" command.
- Fixed a bug that caused fullchain certificates installed by users to not work properly.
## 3.14.0 - 2024-04-04 - Improved Workflow Editor, Publish Module Enhancement, Deprecated Store Submit Module
### 🆕 New Features
- In the [Publish module](https://docs.appcircle.io/publish-to-stores-module), within the app information section, users can now redirect to the relevant build and profile if the publish originated from a build.
- Release notes are now displayed in the [app information](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/app-information-app-store) section within the Publish module.
- The ["Get approval from Test Flight"](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/approval-test-flight) step has been enhanced to provide additional information and actions, such as managing beta testers and addressing compliance errors.
- Added the ability to distribute to both internal and external groups within the ["Get approval from Test Flight"](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/approval-test-flight) section.
- The compliance status is now displayed in the ["Get approval from Test Flight"](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/approval-test-flight) component on the new UI page.
- Support for obtaining multiple email approvals, with required/optional options and a minimum approval count, has been added to the [Publish Flow](https://docs.appcircle.io/publish-to-stores-module/publish-flow/).
- Added filtering support for Publish Profile list based on latest statuses.
- You can now update the default release note of the app version provided by the Build Module. This will be sent as the "What to Test" area in [TestFlight](https://docs.appcircle.io/publish-integrations/ios-publish-integrations/sent-to-testflight).
- Submit Store redirects have been eliminated from the site.
- Incorporated a "Type" field into the data table within the [Environment Variable](https://docs.appcircle.io/environment-variables) sections, offering additional context regarding the type of each variable.
- [PAT (Personal Access Token) connections](/build/manage-the-connections/reconnect-change-provider#managing-pat-connections) listed on the build connection page are now deletable, providing users with the flexibility to manage their connections more efficiently.
- Branches are now filtered based on their status, enabling users to easily identify and navigate through branches based on their current state.
- Users now have the capability to be redirected to their desired locations upon clicking on [Okta applications](/account/my-organization/security/authentications), enhancing navigation efficiency and user experience within the system.
- When a build is [manually initiated](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers#manual-build), the system retrieves information about the user from the initiating organization. Conversely, if the build is [not initiated manually](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers#automatic-build), it displays the details of the user who made the commit, ensuring accurate attribution of actions within the system.
- The self-hosted Appcircle server now supports using a custom domain for the [Testing Distribution Portal](/testing-distribution/testing-portal). Follow the instructions in the [Testing Distribution](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration#testing-distribution) section of the SSL configuration.
- The self-hosted Appcircle server now adopts single-node single drive MinIO instead of multi-node single drive MinIO in the default configuration, which decreases disk consumption significantly.
:::caution
/account/my-organization/notifications/email-connection
Upgrading from older versions to `v3.14.0` or later, requires MinIO migration that should be done interactively while upgrading.
In order to migrate to single-node single drive MinIO configuration or stay with the deprecated multi-node single drive MinIO configuration, **you must follow the instructions** that are defined in the [MinIO Migration](/self-hosted-appcircle/install-server/linux-package/configure-server/minio-migration) document.
:::
:::tip
Fresh self-hosted server installations do not require any manual intervention for the MinIO configuration.
The single-node single drive [MinIO configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/minio-migration) is applied by default on fresh installations.
:::
### :muscle: Improvements
- Users can now update the default release notes for app versions directly on the [Binary Information](https://docs.appcircle.io/publish-to-stores-module/publish-information/binary-information) page.
- In the [Publish module](https://docs.appcircle.io/publish-to-stores-module), the names "App Info" and "Details" have been updated to prevent misunderstanding. "App Information" has been changed to "Binary Information," and "Details" has been changed to "Publish Details" for clarity.
- In the Publish module, the [Release Candidate](https://docs.appcircle.io/publish-to-stores-module/publish-information/marking-release-candidates) version is now the exclusive source for the Profile App Version, Build Number, and Icon.
- Post-upload control for [Google Play](https://docs.appcircle.io/publish-integrations/android-publish-integrations/publish-to-google-play) and [Huawei AppGallery](https://docs.appcircle.io/publish-integrations/android-publish-integrations/publish-to-huawei-appgallery) Credential Validation against API files has been implemented.
- Improvements have been made to the text on the download and install buttons in the Enterprise app store.
- The user interface has been updated for disabled states, with the opacity of the corresponding switch object being reduced to improve visual clarity and indicate its disabled status more effectively.
- The invitation link has been updated to be a clickable link instead of plain text, allowing users to easily access the invitation page with a single click for a smoother onboarding experience.
### 🐞 Fixes
- Fixed a bug that allowed app versions with different bundle IDs to be uploaded.
- Fixed a bug where self-hosted runners, when the only available runner systems were present, were unable to detect changes or default values of Xcode versions for App Store steps.
- Fixed a bug where the data was not updated when an app version Release Candidate (RC) was selected.
- Fixed a bug in the pool table where, if agent information was missing, the pool was erroneously reset as if no records were present.
- Fixed a bug that occurred when re-uploading a file with the same name.
- Fixed a crash that occurred on the add new user screen when encountering an invited user.
- Resolved a 404 issue that users encountered when attempting to connect to PAT (Personal Access Token).
- Fixed a problem where versioning was being reset erroneously.
- Fixed a bug where form validation was broken after uploading YAML files.
- Fixed an issue where there was a problem with keystore selection on the Resign binary page
## 3.13.0 - 2024-03-04 - Improved Publish Module, Xcode 15.3, Build Infrastructure Updates
### 🆕 New Feature
- The new "App Information" tab has been added into the Publish Detail page for the new "App Information from App Store" step.
- Within the new "App Information" section, users can now find the Publish icon displayed for both TestFlight and App Store, offering convenient access to essential information regarding the app's publication status across these platforms.
- The pool selection feature has been added to the [Publish Module Settings](https://docs.appcircle.io/publish-to-stores-module/#publish-settings).
- In the Publish Module, users now have the capability to upload YAML files for their flows, enabling easier management and customization. Additionally, they can download their existing flows for offline reference or modification.
- Within the Publish Module, customers now have the capability to designate their desired app version as a Release Candidate, streamlining the process of identifying and managing versions prior to official release.
- The "Appcircle Standard macOS Pool (arm64)" and [self-hosted macOS VM image](https://docs.appcircle.io/self-hosted-appcircle/self-hosted-runner/runner-vm-setup/) have been updated to include the latest [Xcode 15.3](https://developer.apple.com/documentation/xcode-release-notes/xcode-15_3-release-notes) release.
- The "Appcircle Standard macOS Pool (arm64)" has been transitioned to [macOS Sonoma](https://docs.appcircle.io/infrastructure/ios-build-infrastructure), now featuring the latest Xcode and stack updates.
- The "Appcircle Standard macOS Pool (arm64)" and the self-hosted runner environment now feature the latest [JDK 21](/workflows/common-workflow-steps/select-java-version), along with patch version upgrades for JDK 8, 11, and 17, ensuring compatibility and providing users with access to the most up-to-date Java development environment.
### :muscle: Improvement
- Certain email templates have been upgraded to incorporate icons in build notifications, enhancing visual clarity and the user experience.
- Self-hosted installations now have the ability to customize the "distribution not found" logo by specifying a custom SVG logo path within the tester web container.
- A scheduled task has been implemented to enhance performance by optimizing the cleaning process of outdated information-level job and job log records.
- The login, registration, forgot password, and single sign-on (SSO) login pages have all been updated with a fresh new user interface.
- Registration now restricts the use of common and disposable email domains for user sign-up.
- Social login functionality is deprecated. Users attempting to log in via social platforms will now be redirected to the registration page for initial setup. However, those who have previously utilized social logins can still access this feature without interruption.
- After logging into the application, users now have the ability to provide onboarding information.
- Dynamic title changes based on the selected language have been implemented to elevate the user experience, ensuring that users receive content in their preferred language seamlessly.
- A new "Provision Profile Type" section has been incorporated into the "App Information" section within the App version, providing users with essential details regarding provisioning profile types associated with the application.
- A validation has been introduced to the Email field within the "Approval via Email" section, ensuring that accurate and properly formatted email addresses are provided for submission.
- In the "select repository" section while connecting to [Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket), [GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab), [GitHub](/build/manage-the-connections/connection-guides/connecting-to-github), or [Azure DevOps](/build/manage-the-connections/connection-guides/connecting-to-azure), teams are now listed in alphabetical order, streamlining the process of selecting repositories and enhancing user navigation within the system.
- A new "Connection Pool" field has been introduced in the LDAP Configuration settings, providing users with the ability to configure connection pooling for LDAP connections.
- An "Order" field has been incorporated into the LDAP Configuration settings, enabling users to specify the order of LDAP configurations.
- Sub-organizations can now access and manage the connection settings, allowing for more comprehensive control and customization within the system.
- A new status has been introduced for builds. Moving forward, the "running" status will also be displayed, providing users with real-time updates on the progress of ongoing builds.
- During self-hosted runner installation, the system now conducts checks on the host configuration. If nested virtualization is supported, the installation process includes the setup of the [Android emulator](https://docs.appcircle.io/self-hosted-appcircle/self-hosted-runner/configure-runner/android-emulator/), enhancing compatibility and enabling seamless Android development workflows.
- The "Appcircle Standard macOS Pool (arm64)" and the self-hosted runner environment have been updated to include Node.js 18 LTS as the default version, providing users with the latest features and improvements in Node.js for [Android](https://docs.appcircle.io/infrastructure/android-build-infrastructure) and [iOS](https://docs.appcircle.io/infrastructure/ios-build-infrastructure).
### 🐞 Fixed
- Fixed a bug that prevented the display of the active publish status in the App version table field.
- Fixed a bug that caused errors when attempting to download app versions during the publish process.
- Fixed a bug that retained the behavior of the export build artifact step for problematic metadata exports.
- Fixed a bug where, if the commit message was empty and there was no custom release note component, the release note wasn't being transmitted to the distribution server.
- Fixed a bug in the Appcircle CLI config trust command that caused it to fail to locate the script.
- Fixed a bug causing multiple requests to be sent erroneously.
- Fixed a bug where validation problems in the form were occurring.
## 3.12.0 - 2024-01-25 - Comprehensive Revision on Permissions, Improvements for Notifications, Migrating to the Publish Module, and Appcircle CLI Updates
### 🆕 New Feature
- Permission (role) naming has been changed in [advanced role management](/account/my-organization/profile-and-team/team-management#advanced-role-management). Also, there are some new roles added for better scope management in your organization.
- [Share with Testers](testing-distribution/create-or-select-a-distribution-profile#share-your-application-with-the-test-groups-manually) in Testing Distribution now has a new toggle option that enables you to display only the shared app version instead of all app versions.
- Appcircle Notifications now has improvements on [Slack](/account/my-organization/notifications/slack-notifications), [Microsoft Teams](https://docs.appcircle.io/account/teams-notifications), [Email](https://docs.appcircle.io/account/email-connection), and [Webhook](https://docs.appcircle.io/account/webhooks) channels that allows you to share release notes, build logs, and test reports via notifications.
- The Store Submit module has been deprecated and it will be replaced by the brand-new [Publish](https://docs.appcircle.io/publish-to-stores-module) module. You should transfer your apps to the [Publish](https://docs.appcircle.io/publish-to-stores-module) module in order to submit your apps to the stores.
- The Appcircle CLI has undergone a complete revision to make it compatible with the latest Appcircle API. Now it also supports self-hosted Appcircle servers. You can see all the recent changes made in the [changelog](https://github.com/appcircleio/appcircle-cli/blob/main/CHANGELOG.md) and follow [configuration instructions](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/appcircle-cli) to use the CLI with a self-hosted Appcircle server.
### :muscle: Improvement
- You can now [download](https://docs.appcircle.io/publish-to-stores-module/#version-download) app version artifacts (`ipa`, `aab`, or `apk`) in the Publish module.
- The blue status bar at the bottom has been changed to **Active Processes**. Now, not only the builds but also the active store submit and publish jobs will be seen there.
- Enterprise users can customize their [publish flows](https://docs.appcircle.io/publish-to-stores-module/#publish-flow) using the **Manage Flow** button so that they can deploy their apps to multiple targets, get approvals from different stakeholders, execute custom scripts, and even more.
- Administrators can now enable or disable the "Edit Username" feature from **Login Settings** on the self-hosted Appcircle server.
- `Manager`, `Operator`, and `Viewer` build profile roles have view permission for the [self-hosted runners](https://docs.appcircle.io/self-hosted-appcircle/self-hosted-runner/configure-runner/manage-runners) list but cannot enable or disable any runner on the list.
- License limits for monthly tester emails and artifact storage size were removed from "Organization > Billing > Usages". Keep in mind that for fair usage, the limits exist but are higher when compared to previous plan limits.
- Now only the underscore character ("\_") can be used in [environment variable](https://docs.appcircle.io/environment-variables/managing-variables) group naming. Appcircle will not allow other special characters in group names.
- [Enterprise App Store](https://docs.appcircle.io/account/my-organization#enterprise-app-store-permissions) permissions have undergone revision with new roles that enable users to configure authorization in detail.
- [User invitation](/account/my-organization/profile-and-team/team-management) and membership update notification emails have been improved and now include additional information, such as sub-organizations.
- User redirection when invited to the organization was improved according to several different cases, like registered, not registered, or SSO login.
- Now you can enhance the SSO login experience by eliminating the "SSO Alias" requirement on the login screen. For this, you should create an Appcircle-compatible login URL so that users can pass through the "SSO Alias" step when they access Appcircle using your custom login URL.
- Publish flow step statuses, and the last step status in the [version list](https://docs.appcircle.io/publish-to-stores-module/#publish-versions) will be in `waiting` status unless the runner executes them.
- The contact button at the bottom right of the page has been removed. You can reach us through the [Contact](https://appcircle.io/contact) or [Slack](https://slack.appcircle.io/) channels.
- The duration and results of internal scheduled tasks can now be tracked by the schedule manager in the infrastructure.
- You can see the Git URL under the repository name while selecting the repository on a new connection, which avoids confusion when the team has the same repository name in different locations.
- Queue waiting records with a waiting time of 0 min will no longer appear in the queue waiting reports for better experience.
- Supported Xcode versions that you see in the "starting workflow" step in build logs are ordered descending (latest first) for better readability.
- Testing Distribution [distribution profile](/account/my-organization/profile-and-team/role-management#testing-distribution-permissions) permissions have undergone revision with new `Operator` role and other role naming changes.
- The self-hosted runner macOS image is the same VM image as in the cloud Appcircle, which will keep you always up-to-date with the latest without waiting for special self-hosted updates.
### 🐞 Fixed
- The time to check the active status of self-hosted runners has been increased from 2 hours to 3 days, which also fixes self-hosted pool availability in the build profile configuration.
- Fixed a typo and a broken re-login redirection when an invalid OTP attempt was made in custom authentication.
- Fixed a bug that prevents sub-organizations from seeing their own enterprise app store download reports.
- Fixed a bug that throws an "branch and commit are not active" toast error when a new branch is added to the repository and not refreshed on the Appcircle side.
- Fixed cache invalidation issues on the login screen.
- Fixed a bug that prevents users from manually uploading `aab` files in the Publish module.
- Fixed a bug for correct step listing in Build module workflow and Publish module flow steps.
- Fixed a bug that prevents user to click on "disconnect" but at Slack integration.
- Fixed bugs that occur while deleting the store API keys in integrations.
- Fixed a bug that enables users to distribute apps to the Enterprise App Store, although they do not have sufficient permission in the Enterprise App Store.
- Fixed unnecessary toast errors when the user has relevant permission in Distribution Profile and opens the build profile configuration.
- Fixed a bug that throws toast errors messages when the user opens the build configuration signing tab.
- Fixed a bug that prevents the correct display of the "Published At" in Enterprise App Store profiles.
- Fixed a bug where the user can enter invalid values into license limits at license details.
- Fixed a bug that prevents manage profiles and app versions in the Enterprise App Store when they have the `Uploader` role.
- Fixed a bug that makes browser crash while viewing build logs.
- Fixed a bug that prints the incorrect remaining limit when the license is expired.
- Fixed a bug that threw an error while renaming the publish profile.
- Fixed the missing default values for [Appdome Build-2Secure for Android](/workflows/android-specific-workflow-steps/appdome-build-to-secure-for-android) workflow step output.
- Fixed the [JaCoCo](https://www.eclemma.org/jacoco/) code coverage "NilObject" error by improving the parser algorithm at the [test report](https://docs.appcircle.io/continuous-testing/android-testing/running-android-unit-tests#generating-test-report) workflow step.
- Fixed the format of values in the publish flow step settings so that they're more user-friendly instead of "key|value" style.
- Fixed the value of the `AC_PULL_NUMBER` environment variable in the build pipeline, which should be the merge request `iid` value for the GitLab connection.
## 3.11.0 - 2023-12-27 - Publish Module, Change Build Profile Owner, Custom Authentication Integration
### 🆕 New Feature
- A new module called [Publish](/publish-to-stores-module) is introduced in beta, which helps manage App Store, Google Play, and Huawei AppGallery deployments with more efficiency. You can now modify publishing flows, add custom scripts, and control flow logic.
- Members in the same [organization](/account/my-organization) can take ownership of previously added build profiles.
- The user can now add a new PAT (Personal Access Token) via the [Connections](/build/manage-the-connections/reconnect-change-provider#managing-pat-connections) page without creating a new build profile.
- Enterprise customers can integrate their own authentication and OTP services and use them in conjunction with LDAP configuration on self-hosted installations.
- The configuration file [global.yaml](../self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) now has a validator that helps users configure the settings correctly on export and prevents them from starting the server with broken settings.
- The [certificate installer](../self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) tool now supports extracting proxy server certificates, which enable the runner to connect through a proxy without any SSL certificate error.
### :muscle: Improvement
- The starting workflow step in the build log shows the email address of the user who triggered the current build.
- Users who have reached the build limit on their licenses will no longer be able to use Autofill while adding a new profile.
- The motto on the login and sign-up pages has been changed to reflect our up-to-date vision.
- The "Appcircle Standard macOS Pool (arm64)" has the latest stable [Xcode 15.1](https://developer.apple.com/documentation/xcode-release-notes/xcode-15_1-release-notes) update available on runners and can be used for iOS builds.
- The "Appcircle Standard macOS Pool (arm64)" has [Xcode 15.2](https://developer.apple.com/documentation/xcode-release-notes/xcode-15_2-release-notes) beta-1 installed on runners. Since this is a beta release, please test your workflows extensively.
- The LDAP configuration section in settings has a help button that redirects to the relevant documentation page for configuration details.
- A new type of role **Operator** has been added to the build profile roles that can also trigger builds.
- You can change the [Enterprise App Store](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration#enterprise-app-store) settings (domain, etc.) after installation without any `reset` action.
### 🐞 Fixed
- Fixed an issue where a connected build profile would appear as if it had not been connected before.
- Fixed an issue that caused the user to completely restrict their own [privileges](/account/my-organization/profile-and-team/team-management) when alone in an organization.
- Fixed the case where the build pipeline was executed on a non-selected wrong pool, which was affecting the Appcircle Linux Pool (x86_64) and the Appcircle Standard macOS Pool (arm64).
- Fixed an issue that was affecting the first-time [connections to the GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab) provider.
- The bug was fixed in the re-creation of a connection that had been disconnected and had its [token revoked](/build/manage-the-connections/reconnect-change-provider#revoke-oauth-connections).
- Fixed a redirect issue when the user tried to connect to any Git provider without an active connection.
- Fixed an issue with the [Unit and UI test](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests) screenshots in the test reports.
- Fixed an issue that occurred in the branch list and commits after [changing the git provider](/build/manage-the-connections/reconnect-change-provider#change-git-provider-and-reconnect) connection at the build profile.
- Fixed an issue that caused environment variables to be created with the same name in the same [environment variable](/build/build-environment-variables) group on the API.
- An error that occurred after closing the repository list while trying to change the Git provider of a build profile connected to a repository has been fixed.
- Fixed an issue that caused the [invited user](/account/my-organization/profile-and-team/team-management) not to be redirected to the sign up page if they were not registered.
- Fixed an issue where the authentication logs section was not visible.
- The error with the email hint text falling into the email field on the login and sign up pages has been fixed.
- Fixed the [Xcodebuild for Unit and UI Tests](/workflows/ios-specific-workflow-steps/#xcodebuild-for-unit-and-ui-tests) workflow step, which was stuck in the build pipeline until timeout in some cases.
- Fixed the crash in the [Export Build Artifacts](/workflows/common-workflow-steps#export-build-artifacts) workflow step that occurs while uploading files in the artifacts that have 0 bytes of length or no content.
- The bundler version bug has been fixed in the [Fastlane](/workflows/common-workflow-steps/fastlane) workflow step by pinning the last bundler version compatible with the ruby version that's included in build runners.
- The permission error that occurred while using the [Authenticate with Netrc](/workflows/common-workflow-steps#authenticate-with-netrc) workflow step was fixed.
- The command line parameter order has been changed to fetch provisioning profiles for signing first, which fixes the broken auto-sign feature in the [Xcodebuild for Devices](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) workflow step.
- Fixed the errors thrown while using the [Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket) connection in build profiles.
- In the [Azure DevOps Server 2020](/build/manage-the-connections/connection-guides/connecting-to-azure#connecting-to-azure-devops-server-repository) version, the trigger was malfunctioning due to the different JSON format received after a merge operation following a PR (Pull Request). It was fixed.
- The bug that prevents users from changing their emails was fixed.
- Fixed a bug about [`no_proxy`](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration#2-configure-proxy-for-the-server) environment variables that broke the network connection of the self-hosted Appcircle server.
- Fixed bug that causes version output to be incorrect when [artifact registry](../self-hosted-appcircle/install-server/linux-package/installation/docker#using-3rd-party-or-self-hosted-artifact-registry) has port in URL.
- Fixed corrupted `check` command output in Ubuntu-based Linux [distributions](../self-hosted-appcircle/install-server/linux-package/installation/docker#supported-linux-distributions).
## 3.10.0 - 2023-12-01 - Connections Page, Disconnect Profile and Change Provider
### 🆕 New Feature
- Added [Connections](/build/manage-the-connections) to the Build module, where all connections (OAuth, PAT) can be viewed and edited. From here, you can disconnect, reconnect, and view the build profiles affected by the connections.
- You can now [disconnect and reconnect](/build/manage-the-connections/reconnect-change-provider#change-git-provider-and-reconnect) to another repository or Git provider without deleting the link to an added profile. You can also change PATs for connections made with PAT.
- The [Testinium](/workflows/common-workflow-steps/#testinium) workflow component now tries several times in case of an error from the Testinium APIs.
- The [Appdome-Build-2Secure](/workflows/ios-specific-workflow-steps/#appdome-build-2secure-for-ios) for iOS component was added, which is the integration that allows activating security and app protection features.
### :muscle: Improvement
- Now builds that result in a warning will also appear as a warning in the branch list.
- Appcircle builds can now be displayed as “Appcircle/BuildProfileId” in pipelines on Git providers.
- The URL format validation used when adding Git provider [instances](/build/manage-the-connections/connection-guides/connecting-multiple-instance) has been removed for self-hosted environments.
- The [Testinium](/workflows/common-workflow-steps/#testinium) workflow component parses result summary and outputs in seperate environment variables.
- A user-friendly format has been introduced in the [testing distribution](/testing-distribution/create-or-select-a-distribution-profile) emails.
- [Brute-force protection](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/ldap-brutefore) and the ability to configure it have been added when logging into the Enterprise App Store and Testing Distribution via the LDAP method in self-hosted use.
- The caching mechanism used when choosing between Testing Distribution [authentication](/testing-distribution/create-or-select-a-distribution-profile#authentication) options has been disabled for the sake of quick response.
- You can no longer add or build Smartface projects to Appcircle. Smartface support has been removed.
- Appcircle no longer supports purchases via Appsumo, and there is no Appsumo featured license supported on Appcircle.
- Appcircle online documentation got several updates and improvements, including search, screenshots, and content that provides a better user experience.
### 🐞 Fixed
- The loader did not appear when loading the [Enterprise App Store](/enterprise-app-store/enterprise-app-store-profile) page, the confusion caused by this has been fixed by adding the loader.
- Fixed a bug when adding profiles using the [SSH connection](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) method.
- Fixed a bug during the configuration cloning process.
- Page redirection issues were occurring on plan upgrade, this problem has been fixed.
- Fixed an issue with the [Xcodebuild for Devices](../build/platform-build-guides/building-ios-applications) workflow step getting stuck in the build pipeline until timing out in some cases.
- Fixed an issue that caused a build to be started in Appcircle when one of the _Approve_, _Approve with Recommendations_, _Wait for Author_, or _Reject_ activities was selected on pull requests when using the [Azure DevOps](/build/build-process-management/build-manually-or-with-triggers#managing-triggers-for-builds) Git provider.
- Fixed a bug that prevented screenshots from being displayed as a result of the [Unit and UI Tests](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests) in the test results section.
- Fixed the issue that caused multiple builds to be launched when only one trigger was set on Appcircle and a trigger was triggered.
- The incorrect "Configuration" information in the [e-mail notification](/account/my-organization/notifications/email-connection) sent as a result of the build in simultaneous build triggers has been corrected.
- When the [Environment Variables](/build/build-environment-variables) file was created from scratch and values were entered and downloaded, the downloaded file appeared empty. This error has been fixed.
## 3.9.0 - 2023-11-01 - LDAP Support for User Authentication, Change the PAT by Build Profile, Download Environment Variables
### 🆕 New Feature
- "Self-hosted Settings" has been introduced on the admin page for self-hosted Appcircle server. It includes [LDAP Login](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings#appcircle-login-with-ldap) for configuring LDAP user authentication and [Login Settings](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/login-configuration#login-settings) for other login configuration options.
- Users are now allowed to manage their connections to private repositories after connecting their profiles.
- Now users are able to download the [environment variables](/build/build-environment-variables) in JSON format.
- Added a new environment variable called [AC_TRIGGER_REASON](/environment-variables/appcircle-specific-environment-variables#ios--android-common-environment-variables) that specifies the trigger that causes the build to start.
- The "Appcircle Standard macOS Pool (arm64)" runners have [Xcode 15.1 beta-1](../build/platform-build-guides/building-ios-applications) installed. As this is a beta release, please test your workflows thoroughly.
- A new filter has been added for filtering reports. Users will now be able to filter by organization and sub organization.
- New commands `download` and `load` were introduced to the self-hosted Appcircle server in order to support [offline installation and upgrade](../self-hosted-appcircle/install-server/linux-package/configure-server/offline-installation) scenarios.
- The self-hosted Appcircle server now supports Secure LDAP, aka LDAPS, that encrypts the authentication process for enhanced security.
### :muscle: Improvement
- A parent organization can access its children's "Build History", "Signing History", "App Sharing Report", "Enterprise App Store Reports", and "Queue Waiting Reports".
- Improvements have been made to the [email notification](/account/my-organization/notifications/email-connection) format for build events.
- The "Appcircle Standard macOS Pool (arm64)" has the latest stable [Xcode 15.0.1](https://developer.apple.com/documentation/xcode-release-notes/xcode-15_0_1-release-notes) update available on runners.
- We now support Azure DevOps Server 2020 connection while adding a [build profile](/build/manage-the-connections/connection-guides/connecting-to-azure).
- The [distribution link](/testing-distribution/create-or-select-a-distribution-profile#distribution-link) in the test deployment area will now be available regardless of authentication type.
- A bug that prevented failed builds from sending notifications to the MS Teams application has been fixed.
- Previously, you could only select one profile for test deployment. Now you can select [multiple profiles in the distribution](/build/build-process-management/configurations#distribution-configuration) profile settings.
- Removed the obsolete icon from the Commit ID redirect link in the build profile details.
- The cache size was bumped to 4 GB while using the [cache push](/workflows/common-workflow-steps/#cache-push) in the build pipeline.
- We made improvements to the self-hosted server [SSL configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration) for enhanced security.
- The [Testinium](/workflows/common-workflow-steps/#testinium) workflow step has the latest improvements from customer feedback and enhanced stability.
### 🐞 Fixed
- Builds that took longer than an hour showed the wrong time on the left side of the screen. This has been fixed.
- While reviewing the build logs in the admin panel, if there is no build log, we were not showing the user an error. Now it is shown as a toast message.
- The bug that occurred if there were no screenshots in the test project has been fixed.
- A problem related to component caching in the runner has been resolved.
- Without user [permission](/account/my-organization/profile-and-team/team-management#advanced-role-management), requests on the relevant screens are no longer sent to the service, so no warnings are displayed.
- We were not showing the status of the request with the loader when a request was sent for workflows; this problem has been fixed.
- Some spelling errors at the beginning of the workflow have been fixed, and a user-friendly appearance has been provided.
- Fixed a bug that prevented logging in to the Enterprise App Store.
- Fixed the error that occurred when test users emails were written in capital letters.
- In the general profile tab in the [distribution profile](/testing-distribution/create-or-select-a-distribution-profile), the incorrect screen movement that occurred when the switch was disabled and reactivated was fixed.
- Fixed unnecessary requests that go on report screens in the case of being a [sub organization](/account/my-organization/profile-and-team/organization-management#working-with-multiple-organizations).
- Fixed missing versioning for the [HashiCorp Vault](https://blog.appcircle.io/article/security-in-appcircle) container image on the self-hosted server.
## 3.8.0 - 2023-10-02 - Multiple Git Providers Support, Config Clone, Pool-Based Xcode Version Selection
### 🆕 New Feature
- The user can add [multiple instances](/build/manage-the-connections/connection-guides/connecting-multiple-instance) of the Git providers and select any of them to connect to. So the user can bind and build the repositories.
- The [Xcode version](/self-hosted-appcircle/self-hosted-runner/configure-runner/manage-pools/#pool-based-xcode-version-selection) list of runners is integrated into the custom pool selection. It can be displayed dynamically in the build configuration, and the user can choose which Xcode version to build with.
- You can now quickly copy a configuration and create a new one from that configuration.
### :muscle: Improvement
- Waiting times in Queue Waiting Reports are now shown in minutes instead of seconds.
- If the user selects any step that has the "Continue with the next step even if this step fails" option and gets a failure during the build on that step, this build's status is displayed as Warning.
- Fixed the case that users belonging to more than one organization on [Azure DevOps](/build/manage-the-connections/connection-guides/connecting-to-azure) could not bind repository.
- Improved suborganization experience in the Enterprise App Store by hiding the "Customize" and "Settings" sections, providing a more focused interface for suborganization administrators.
- The latest stable version of [Xcode 15.0](../build/platform-build-guides/building-ios-applications) is available on both cloud and self-hosted runners.
- The self-hosted Appcircle server now supports proxies with a [self-signed certificate.](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration)
- Users can more easily switch to the self-hosted version of their choice by only [downloading](../self-hosted-appcircle/install-server/linux-package/update#1-download-latest) the server package.
- Added the [NTP configuration](../self-hosted-appcircle/self-hosted-runner/runner-vm-setup#2-configure-base-runners-ntp-settings) helper tool to the self-hosted runner package.
- Added self-signed certificate management for Node.JS to the [certificate installer](../self-hosted-appcircle/self-hosted-runner/configure-runner/custom-certificates#adding-certificates) tool.
- Now you can analyze your [SwiftLint](/workflows/ios-specific-workflow-steps/azure-bot-for-swiftlint) and [Detekt](/workflows/android-specific-workflow-steps/) reports and post the report details under the opened PR on Azure DevOps.
### 🐞 Fixed
- Fixed the "Waiting Duration" title in the Queue Waiting Reports header.
- The role management error in the [Apple Devices](/signing-identities/apple-devices) section in the Testing Distribution module has been fixed.
- Fixed the issue of not being able to distribute to the selected configuration in the [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile) module.
- Fixed the issue where the branch list could not be refreshed when the user [permission](/account/my-organization) for the Build module was set to "Read Only Access".
- Fixed the issue where the build does not appear in the list when the build starts.
- Fixed the bug that users without permission were sending requests to the service when browsing pages.
- In the Store Submit module, the "Huawei App ID" field in the Huawei AppGallery section was disabled. It's been fixed.
- Flickering on the screen due to line overlap in the build module has been fixed.
- When an invalid email was entered in the [email integration](/account/my-organization/notifications/email-connection) module, other options were reset. It's been fixed.
- The wrong dialog modal was opening in the "never delete" option selected for the deletion of an artifact. It's been fixed, and an extra description has been added.
- When there was a workflow step of the same name, there was a confusion of names. It's has been fixed.
- An error message is now displayed to the user when an invalid workflow name is entered.
- Fixed the data refresh error when the version is deleted in the [Apple Devices](/signing-identities/apple-devices) section of the Testing Distribution module.
- Fixed the page crash problem when the user clicks on the [Triggers](/build/build-process-management/build-manually-or-with-triggers).
- Added a toast message that is shown when the user tries to download the deleted configuration in the admin panel.
- The case that selection of the adhoc [auto device register](/signing-identities/apple-devices) on the distribution profile settings has been fixed.
## 3.7.0 - 2023-09-05 - Email Notification, Queue Waiting Reports
### 🆕 New Feature
- We added a new admin report for the queue waiting report. Now self-hosted enterprise customers can see the queue status and waiting durations of each build, fetch, store submit, and resign process.
- You can now send [email notifications](/account/my-organization/notifications/email-connection) for most actions taken within Appcircle (build start, store submit, etc.).
- Self-hosted [runner](/self-hosted-appcircle/self-hosted-runner/installation) now supports installation of the latest [Xcode 15.0](/infrastructure/ios-build-infrastructure) release with all its simulator runtimes. Since this is a beta release, please test your workflows extensively.
### :muscle: Improvement
- Removed profile names will now appear as "Deleted" in corporate store reports.
- The active build section now shows the email address that started the build, not the email address of the user who created the profile.
- If there is a space character in the [variable group](/build/build-environment-variables) name, it can be used within double quotes while connecting the repository.
- `$"Variable Group:Key"`
- Self-hosted enterprise customers can download the [configurations](/build/build-process-management/configurations) of previous builds with the `.yaml` extension in "Build Details" section of the admin panel.
- Unsubscribe and resubscribe features are enabled for email notifications, distribution, and the enterprise app store.
### 🐞 Fixed
- The confusion regarding the use of foreign characters when creating [workflows](/workflows) and [configurations](/build/build-process-management/configurations) has been resolved. foreign characters and some special characters can no longer be used in this section.
- The error in [permission management](/account/my-organization) in the environment variables section has been fixed.
- The problem with the build transaction texts above the branch name in the "Branch" section being mixed up has been fixed.
- The error in permission management in the [Enterprise App Store](/enterprise-app-store/enterprise-app-store-profile) section has been fixed.
- The incorrect display of the inactive steps at the beginning of the build pipeline has been fixed. It was affecting the workflow steps section in the build logs while the build was running.
- The problem of creating groups without a group name and with an existing name on the API's side has been fixed.
- Optional steps won't affect build status anymore. If "Continue with the next step even if this step fails" is selected, your build status will not turn failed.
## 3.6.0 - 2023-08-03 - Azure DevOps Integration, Using Environment Variables On Git Integrations
### 🆕 New Feature
- Now you can connect repositories from [Azure DevOps Services](/build/manage-the-connections/connection-guides/connecting-to-azure) and Azure DevOps Server for your builds.
- Added support for using [webhook](/account/my-organization/notifications/webhooks) with OAuth 2.0 and the Personal Access Token on Azure DevOps.
- The quick add feature has been added to the new project screen for both Azure DevOps Services and Azure DevOps Server.
- LDAP, user lookup decision strategy can be configured in global.yaml. See [LDAP settings](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings) for details.
### :muscle: Improvement
- The ability to use information such as [SSH and PAT](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh), that is required for adding new projects with SSH has been added with environment variables.
- The [Tag Model](/build/build-process-management/build-manually-or-with-triggers) now includes the name and email of the user who created the tag.
- The self-hosted script can now be called from anywhere in the OS.
### 🐞 Fixed
- Fixed a bug that users were experiencing when adding to the provisioning profile.
- Fixed a bug that caused [endpoints](/appcircle-api-and-cli/api-authentication) to not appear in the webhook module on Swagger.
- When an event matches the trigger rules, all satisfied triggers will be executed.
- The user is redirected to the "invitation expired" page when the [invitation](/account/my-organization) link is timed out.
- The health check command was fixed, and it now reports the correct state both for Podman and Docker.
- The missing service on the Podman installation was fixed.
## 3.5.0 - 2023-07-13 - Configuration, Workflow Improvements, New Autofill Feature
### 🆕 New Feature
- Added the "Autofill" option when creating a new build profile and connecting it with the service.
- [Xcode 15.0 Beta-4](/infrastructure/ios-build-infrastructure) added to build agents. Since this is a beta release, please test your workflows extensively.
### :muscle: Improvement
- Added the feature that [LDAP](/account/my-organization/security/authentications) and [SSO](/account/my-organization/security/authentications) settings can be made once and all sub-organizations can use this setting.
- Previous [Configuration and Workflow](/build/manage-the-connections/connection-guides) files can be downloaded in the Configuration and Workflow sections. The ability to create configuration and workflow by re-uploading downloaded `.yaml` files has been improved.
- On the [self-hosted](../self-hosted-appcircle/self-hosted-runner) side, the feature of adding priority has been developed for online and offline runners.
- Sequential numbering improvement was made in the naming while creating the new configuration and workflow.
- The ability to send files from the Testing Distribution module to the Enterprise App Store added.
- Made an improvement to prevent the subordinate from accessing the details on the 'corporate settings' page.
- Appcircle Standard macOS Pool (arm64) is automatically selected in case of [Xcode](/infrastructure/ios-build-infrastructure) version 14.3.x and above.
- Improved the display of device name if there is an available device on the [IOS provisioning](/signing-identities/apple-devices) profile side.
- Subtitle would also have to be searched for components. This development has been done.
### 🐞 Fixed
- Fixed an issue where the user could not create a [sub-organization](/account/my-organization) even though they had the required permission.
- Fixed issue with file permissions when exporting a project for self-hosted uses.
- Fixed the problem of adding the same name while uploading the [configuration](/build/manage-the-connections/connection-guides).
- The permissions of the applications in the Huawei AppGallery that depend on the permission to view the applications in the store submit section has been fixed.
- The problem that the save button is not active after the changes made in the organization pool has been fixed.
- Fixed a double slash (`//`) bug on the webhook link that caused the triggers to not work.
- The error that the change indicator appears even though there is no change in some tabs in the config modal has been fixed.
- Apple Devices improved, not sending device enrollment link if auto enrollment is disabled.
- Fixed configuration creation error without giving any name.
- Fixing UI bugs in search field in [Testing Distribution](/testing-distribution/create-or-select-a-distribution-profile) module.
- Fixed a bug that caused triggers to be deleted.
- The error that the save button is not active when I change the [offset](../versioning/ios-version) part of the build number has been fixed.
- Fixed unsigned owners error on files that are not resigned in test deployment part.
- Fixed some icons appearing properly in dark mode.
## 3.4.0 - 2023-06-09 - Build Profile Improvements, Azure Boards
### 🆕 New Feature
- [Xcode 15.0 Beta](/infrastructure/ios-build-infrastructure) added to build agents. Since this is a beta release, please test your workflows extensively.
- [Java 17](../infrastructure/android-build-infrastructure) added to build agents.
- [Build Profile](/build/manage-the-connections/connection-guides) configurations are separated from branchs. It is now easier to see and manage configs from a single location.
- [SSO](/account/my-organization/security/authentications) and [LDAP](/account/my-organization/security/authentications) Login added to Testing Distribution.
- [Azure Boards](/workflows/common-workflow-steps/azure-board) workflow step added.
- [Repeato](/workflows/common-workflow-steps/#repeato-mobile-test-automation) workflow step added.
- [Snyk Secure Scan](/workflows/common-workflow-steps/#snyk-scan-security) workflow step added.
### :muscle: Improvement
- [Xcode Build for Simulator](/workflows/ios-specific-workflow-steps/#xcodebuild-for-ios-simulator) workflow step updated. The new version allows you to create both x86_64 and arm64 simulator builds. This step can optionally install the simulator builds to run UI tests on the simulator.
- [Test Report](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests) step tries to parse JUnit files if it can't find .xctestresult files. This can be useful if your testing framework(BrowserStack, Repeato, etc.) is producing JUnit reports.
- [Wait for Android Emulator](/workflows/android-specific-workflow-steps/#wait-for-android-emulator) step updated to install optional APK after the emulator boots.
- The default Xcode version is bumped to 14.2 for new projects.
- Sub-organizations can see their download reports.
- Build configuration screen is improved. Changing the tabs no longer resets the configuration.
- Build trigger screen is improved.
- [Self-hosted Runer](/self-hosted-appcircle/self-hosted-runner/installation) installation script updated for new Xcode versions and other tools.
- The default configuration file that contains [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) settings is simplified.
- The [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) package has a text file that contains a list of container services.
- [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) Podman support added.
- [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) installation script `version` command updated to fix Podman compatibility.
- New script added [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) installation package. This script allows users to add and trust their custom self-signed certificates.
- New script added [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) installation package. This script allows users to add and trust their custom self-signed certificates.
### 🐞 Fixed
- Strict URL check is removed when users try to add Azure repositories.
- An error that was occurring when you tried to add a sub-org on self-hosted Appcircle is fixed.
- Some minor cases that were occurring on the [Self-hosted Server](../self-hosted-appcircle/install-server/linux-package/installation/docker) boot process are fixed.
## 3.3.2 - 2023-05-10 - Xcode 14.3,FTP Upload
### 🆕 New Feature
- [Xcode 14.3](/infrastructure/ios-build-infrastructure) added to build agents. Since Xcode 14.3 only runs on Ventura, Appcircle Standard macOS Pool (arm64) infrastructure is also updated. Please test your workflows extensively.
- [FTP Upload](/workflows/common-workflow-steps/#ftp-upload) workflow step added.
### :muscle: Improvement
- [Data Theorem Mobile Secure](/workflows/common-workflow-steps/#data-theorem-mobile-secure) workflow step updated.
- New options added to [Android Resign](/testing-distribution/resigning-binaries).
- Sub-organizations can see their download reports.
- Build configuration screen is improved. Changing the tabs no longer resets the configuration.
- Build trigger screen is improved.
### 🐞 Fixed
- Fixed a bug that makes users unable to add their GitHub repositories.
## 3.3.0 - 2023-04-27 - Data Theorem Mobile Secure, App Center CodePush
### 🆕 New Feature
- [Data Theorem Mobile Secure](/workflows/common-workflow-steps/#data-theorem-mobile-secure) workflow step added.
- [App Center CodePush](/workflows/react-native-specific-workflow-steps/appcircle-codepush) workflow step added.
- Latest five build status added to build profile.
- Slack Bot added.
### :muscle: Improvement
- SVG images are updated
- Build profile card design is improved.
- Color scheme and icons are updated for dark themes.
- Lots of UI and text improvements were made for better UX.
### 🐞 Fixed
- Huawei AppGallery submission bug fixed.
- [Enterprise App Store](/enterprise-app-store/portal-customization) The background image bug was fixed on the login page.
- Fixed a bug that makes users unable to login to the enterprise app store in some cases.
- Fixed a bug that gives an unexpected error on project `export` on self-hosted server installations.
- Fixed a bug that gives an unexpected error on project `up` when there is no vault image in the system.
- The default license duration for the self-hosted package is updated to 3 months for demo use cases.
- Fixed broken tag triggers which was missing to start build on some cases.
- Store submit workflows are updated for the latest Fastlane version.
## 3.2.0 - 2023-04-07 - Resign, Sub Organizations
### 🆕 New Feature
- [Resigning](/testing-distribution/resigning-binaries) iOS and Android binaries added to Test Distribution module.
- Enterprise customers can create [sub organizations](/account/my-organization) to manage their users.
- [App Center iOS Distribution](/workflows/ios-specific-workflow-steps#app-center-ios-distribution) workflow step added.
- [App Center Android Distribution](/workflows/android-specific-workflow-steps#app-center-android-distribution) workflow step added.
### :muscle: Improvement
- Build profile list UI is improved
- Extra notes added to [SSH](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) key generation for Windows users.
- User's default branch is listed at the top.
### 🐞 Fixed
- GitLab double trigger bug fixed.
- GitLab Self-Hosted access token now longer shows inside build logs.
- [Enterprise App Store](/enterprise-app-store/portal-customization) 2FA Safari bug fixed.
- [Enterprise App Store](/enterprise-app-store/portal-customization) localization bug fixed.
- [Enterprise App Store](/enterprise-app-store/portal-customization) Download bug is fixed for slow networks.
## 3.1.0 - 2023-03-17 - StoreSubmit, Self-hosted Improvements
### 🆕 New Feature
- Submissions to Google Play Console and Huawei AppGallery will now begin from the build agents.
- It is now possible to localize some login form texts on the [Enterprise App Store](/enterprise-app-store/portal-customization) when LDAP login is activated.
### :muscle: Improvement
- [Enterprise App Store](/enterprise-app-store/portal-customization) language selection page is improved.
- `AC_COMMIT_AUTHOR_EMAIL`, `AC_COMMIT_SUBJECT`, and `AC_COMMIT_MESSAGE` [Environment Variables](/environment-variables/appcircle-specific-environment-variables) added to build agents.
- Unauthenticated internal SMTP server support added for Self-Hosted Appcircle.
- `global.yaml` content is improved with new configuration options.
- Confusing initial `user-secret` file generation is removed.
- New command line parameters added for Self-Hosted Appcircle CLI.
### 🐞 Fixed
- Huawei AppGallery App ID saving bug fixed.
- [Enterprise App Store](/enterprise-app-store/portal-customization) 2FA login bug fixed.
- Appcircle now shows a warning if it can't reach your repository due to network problems.
- Fixed broken downloads on Enterprise App Store when an app has a name in non-ASCII characters.
- Minor localization fixes were done on Enterprise App Store for the Turkish language.
- Minor fixes were done on SSH key format and SSH repo connections.
- Enterprise App Store settings' broken UI fixed when the custom domain is disabled.
- Dashboard no longer shows builds started for store submission.
- Dashboard no longer shows builds from deleted build profiles.
## 3.0.1 - 2023-02-28 - AppSweep, Self-hosted Improvements
### 🆕 New Feature
- [AppSweep Mobile Security Testing](/workflows/android-specific-workflow-steps/#appsweep-mobile-security-testing) component added.
- [Self-signed certificate](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration) support added for Testing Distribution.
- [Enterprise App Store](/enterprise-app-store/portal-customization) is now available in German and Turkish languages in addition to English. To switch to your preferred language, simply navigate to the language settings on your store homepage and select either German or Turkish.
- [New APIs](https://api.appcircle.io/openapi/index.html?urls.primaryName=store) are added to directly download IPA or APK files from Enterprise App Store by using a PAT.
### :muscle: Improvement
- New line is added to SSH private key if it doesn't exist.
- API key selection is now mandatory for all app submissions on Google Play.
- Autofill button respects the selected pool.
- Self-hosted GitLab onboarding screen is improved.
- Default pools are removed from Self-hosted instances.
### 🐞 Fixed
- Email address parse error fixed for Distribution profiles.
- Test reports are correctly created for branches even if they don't have any configuration.
- Dashboard no longer shows builds started with autofill.
- Cache pull and Cache Pull components are fixed.
- [Enterprise App Store](/enterprise-app-store/portal-customization) live and beta channels access managament bug fixed
- Store Submit permission bug fixed.
## 3.0.0 - 2023-02-14 - LDAP, Self-hosted Improvements
### 🆕 New Feature
- [Multiple LDAP](/enterprise-app-store/portal-settings#ldap-login) support added for Enterprise App Store.
- [Self-signed certificate](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration) support added for Appcircle server.
- [Self-signed certificate](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration) support added for external services such as Git providers (GitLab, Bitbucket etc.)
### :muscle: Improvement
- Onboarding of React Native Android project is improved.
- Flutter iOS build component improved.
- [Feedback form](https://my.appcircle.io/help) added to help section.
- CSS and icon handling is updated to improve the performance of the Enterprise App Store.
- Self-hosted instances can be installed from a single Docker registry.
- Self-hosted instances can start without an active internet connection.
- Public and SSH repository options are added to default profile options.
- Improvements were made to the logging system to prevent big log files.
### 🐞 Fixed
- Enterprise app store cache related bugs were fixed.
- SMTP bugs were fixed for server notifications.
## 2.9.23 - 2023-02-02 - LDAP, Jira, Microsoft Teams
### 🆕 New Feature
- [LDAP Login](/enterprise-app-store/portal-settings#ldap-login) added to Enterprise App Store.
- [Jira](/workflows/common-workflow-steps/jira-comment) component added.
- [Microsoft Teams](/account/my-organization/notifications/teams-notifications) integration added.
- [Gradle Runner](/workflows/android-specific-workflow-steps/#gradle-runner) component added.
- [Maestro Cloud Upload](/workflows/common-workflow-steps/#maestro-cloud-upload) component added.
### :muscle: Improvement
- UI improvements for the
- Build profile based device registration added to Ad Hoc provisioning profiles.
### 🐞 Fixed
- [iOS Version and Build Number Increment](../versioning/ios-version) component gracefully exits if it can't update the project.
## 2.9.22 - 2023-01-16 - Adhoc Improvements
### 🆕 New Feature
- [Apple Devices](/signing-identities/apple-devices) section will allow you to easily register new devices and add them to Ad Hoc provisioning profiles.
- [Firebase Deployment ]/workflows/flutter-specific-workflow-steps/firebase-deployment) component added.
### :muscle: Improvement
- [Firebase App Distribution](/workflows/common-workflow-steps/#firebase-app-distribution) component support service account.
- UI improvements for the custom script editor.
### 🐞 Fixed
- If you revert a commit and force push it, Appcircle will correctly handle this situation.
## 2.9.21 - 2022-12-28 - BrowserStack App Automate
### 🆕 New Feature
- [BrowserStack App Automate - Espresso](/workflows/android-specific-workflow-steps/#browserstack-app-automate---espresso) component added
- [BrowserStack App Automate - XCUI](/workflows/ios-specific-workflow-steps/#browserstack-app-automate---xcui) component added
### :muscle: Improvement
- Component YAML structure is improved. YAML files support markdown.
- UI improvements for the custom script editor.
### 🐞 Fixed
- `[retry]` comment now works on BitBucket. If your workflow failed, writing `[retry]` as a comment will start your workflow again.
- If the owner of the repository changes, you will see a new authentication dialog. After authentication, Appcircle will correctly refresh the token on behalf of the new user.
- Slack connection bug fixed.
## 2.9.20 - 2022-12-22 - Xcode 14.2, Google Play Draft Submission
### 🆕 New Feature
- Xcode 14.2 added to both Appcircle Linux Pool (x86_64) and Appcircle Standard macOS Pool (arm64).
- Submit Release as Draft. If your app has no presence on Google Play you may send it as a draft.
### :muscle: Improvement
- Repository connection errors are shown properly.
- UI improvements for Environment Variables and Testing groups.
- [Flutter Test Component](https://github.com/appcircleio/appcircle-flutter-test-component) creates a JUnit report which can be consumed by the [Test Report Component](https://github.com/appcircleio/appcircle-test-report-component).
### 🐞 Fixed
- `[skip ci]` commit message also works on Pull/Merge Requests. If you have open PR, sending a commit with `[ci skip]` or `[ci skip]` message will not trigger a workflow.
- [Test Report Component](https://github.com/appcircleio/appcircle-test-report-component) now handles multiple reports in the same folder.
## 2.9.19 - 2022-12-14 - Testinium and Firebase dSYM Upload components
### 🆕 New Feature
- [Testinium](/workflows/common-workflow-steps/#testinium) component added. This component allows you to run your test plans on [Testinium](https://testinium.com)
- [Firebase dSYM Upload](/workflows/ios-specific-workflow-steps/firebase-upload-dsym) component added. You may use this component to upload Debug Symbols to Firebase.
### :muscle: Improvement
- Help document links added to SSO section.
### 🐞 Fixed
- Github authentication issue is solved.
- Account delete bug fixed.
- Refresh button refreshes correctly and shows forced pushes as well.
## 2.9.18 - 2022-12-06 - M1 Machines
### 🆕 New Feature
- We have a big announcement today :tada: We have added an M1 Mac mini machines to our infrastructure and enabled them for every account. Both Android and iOS builds will benefit from the blazing fast M1 machines. We expect this change to be smooth for most of the users. Please be aware of the following issues.
**Firewall**:
If you’re using self hosted services and allowed Appcircle IPs in your firewall, you need to update your allowed IP list. Please check the following document.
Accessing Repositories in Internal Networks (Firewalls)
**Appcircle Linux Pool (x86_64)l**:
If your builds fail on Appcircle Standard macOS Pool (arm64) or if you’re not ready for the M1 migration, please go to your branch’s config screen and choose Default Appcircle Linux Pool (x86_64) from the dropdown menu.
## 2.9.17 - 2022-12-01 - Test Reports
### 🆕 New Feature
- Test Reports added for [iOS](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests) and [Android](/continuous-testing/android-testing/running-android-unit-tests). Please check their documentation to learn how to set up your workflows.
- [Danger](/workflows/common-workflow-steps/#code-reviews-with-danger) component added. Danger runs during your CI process and gives teams the chance to automate common code review chores
- The emulator feature is removed.
### :muscle: Improvement
- Performance improvements for the Dashboard
- Announcement button ⚡️ added to Dashboard. You can check that section for product announcements.
- Wildcard Provisioning Profile support for manual code signing
- Setting environment variables via the `AC_ENV_FILE_PATH` environment variable now works on failed steps as well.
- Xcode versions older than 12.5 removed.
## 2.9.16 - 2022-10-07 - Triggers fallback config, Netrc, Bundlletool and Detekt components
### 🆕 New Feature
- [Fallback config](/build/build-process-management/build-manually-or-with-triggers) added for Pull/Merge Requests and Tag triggers.
- [Netrc component](/workflows/common-workflow-steps) You can use this component to add credentials for hosts such as your repositories or external hosts.
- [Bundletool Component](/workflows/android-specific-workflow-steps) You can use this component to create universal apk from the aab.
- [Detekt](/workflows/android-specific-workflow-steps) You can use this component to run your detekt gradle task.
### :muscle: Improvement
- [Added FAQs](/build/platform-build-guides/building-ios-applications#faq) related to Xcode 14 and code signing errors.
## 2.9.15 - 2022-09-30 - Fortify On Demand and Firebase App Distribution components
### 🆕 New Feature
- [Fortify On Demand Component](/workflows/common-workflow-steps) You can use Fortify On Demand uploader for all your projects.
- [Firebase App Distribution Component](/workflows/common-workflow-steps) You can use Firebase App Distribution to distribute your builds.
- [Wait for Android Emulator](/workflows/android-specific-workflow-steps) You must use this step before your UI tests to wait for the Android emulator to start.
### :muscle: Improvement
- Navigation and repository refresh speed improved.,
- Linux agents are more powerful now. They also support nested virtualizations therefore you may use Android emulators.
- Xcode default version number is changed to 13.4.x
- Android Emulator added to agents. The added emulator is based on Android 9.0 image. You may install additional emulators by using `sdkmanager`. Please check [Android Infrastructure](../infrastructure/android-build-infrastructure) to learn more. In order to use the emulator, you need to add the Wait for Android Emulator step to your workflow.
### 🐞 Fixed
- Bitbucket commit messages now show properly.
- `AC_PULL_NUMBER` environment variable added for Pull/Merge Requests.
- Changing assignee no longer triggers a build for GitLab Merge Request.
- Build statuses correctly shows on the main dashboard.
## 2.9.14 - 2022-08-18 - New Dashboard, Appium Server and SwiftLint components
### 🆕 New Feature
- [New Dashboard](https://my.appcircle.io) Appcircle has a brand new dashboard that shows an overview of your account.
- [Artifacts Management](/account/my-organization/artifacts) You can set the retention period for your build artifacts.
- [Appium Server Component](/workflows/common-workflow-steps) You can use Appium Server for iOS and Android projects.
- [SwiftLint Component](/workflows/ios-specific-workflow-steps) You can use Swiftlint for iOS projects.
### :muscle: Improvement
- Empty states are added for all modules.
- [Self-Hosted Runners](../self-hosted-appcircle/self-hosted-runner) Self hosted documentation updated.
- Docs updated to Docusaurus v2.0.1
### 🐞 Fixed
- Sharing Simulator URL fixed.
## 2.9.13 - 2022-07-27 - Self-hosted Runners, Artifacts Management, Automatic iOS Code Signing
### 🆕 New Feature
- [Self-Hosted Runners](../self-hosted-appcircle/self-hosted-runner) Self-hosted runner enables you to use your own systems and infrastructure for running Appcircle build pipelines.
- [Automatic iOS Code Signing](/signing-identities/apple-profiles#automatic-signing) If you're using Xcode 13 or later, you can now use the automatic code signing option to automatically sign your iOS apps.
- [Artifacts Management](/account/my-organization/artifacts) You can set the retention period for your build artifacts.
- [SonarQube Component](/workflows/common-workflow-steps) You can use SonarQube for iOS and Android projects.
### :muscle: Improvement
- Slack messages updated to include store name and distribution links.
- Android v2 signing support improved.
### 🐞 Fixed
- `Get help with build errors` link fixed.
- Renaming build profiles fixed.
## 2.9.12 - 2022-07-07 - Android Version Management, Enterprise App Store Improvements
### 🆕 New Feature
- [Android Versioning](../versioning/android-version) You can manage version code and version name directly with UI.
- [Enterprise App Store](/enterprise-app-store/portal-customization) You can change the display picture of your apps.
### :muscle: Improvement
- Added Open menu to actions list on build profiles.
- [Enterprise App Store](../enterprise-app-store/enterprise-reports) App usage reports update more frequently.
- [My Organization](/account/my-organization) Access Management document updated.
### 🐞 Fixed
- Creating a new branch without a commit was not triggering a build. This is fixed.
- SSO UI issues fixed
- Android Build Tools 31.0.0 corrupted error message fixed.
## 2.9.11 - 2022-06-20 - Release Notes Component, Enterprise App Store Improvements
### 🆕 New Feature
- [Release Notes Component](/workflows/common-workflow-steps/publish-release-notes) You can create release notes with Publish Release Notes component.
- [Enterprise App Store](/enterprise-app-store/portal-settings) Certificate Details added to Enterprise App Store.
- [Enterprise App Store](../enterprise-app-store/enterprise-reports) Detailed reports are added to Enterprise App Store.
- [Open API](https://api.appcircle.io/openapi/index.html?urls.primaryName=signing-identity) New API endpoints added to Certificate and Provisioning profiles upload.
- [Open API](https://api.appcircle.io/openapi/index.html?urls.primaryName=build) New API endpoint added to start a build with provided environment variables.
### :muscle: Improvement
- [iOS Stack](/infrastructure/ios-build-infrastructure) Monterey is upgraded to 12.4 for macOS agents.
- Log window is improved. It is more performant and stable.
- Added [FAQ section](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh#issues-in-connecting-to-the-repositories-with-ssh) for multiple SSH keys.
### 🐞 Fixed
- Store Submit logs show properly.
## 2.9.10 - 2022-05-31 - iOS Version Management, Enterprise App Store Customizations
### 🆕 New Feature
- [Enterprise App Store Customizations](/enterprise-app-store/portal-settings). You can connect your subdomain as Enterprise App Store.
- [NodeJS Version Selection](https://docs.appcircle.io/build/building-react-native-applications#build-configuration-for-react-native-ios-applications) You can now directly set the NodeJS version on config screen.
- [Flutter Version Selection](https://docs.appcircle.io/build/building-flutter-applications#how-to-set-a-specific-flutter-version-for-the-build) You can now directly set the Flutter version on the config screen.
- [iOS Versioning](https://docs.appcircle.io/versioning/ios-version) You can manage build and version numbers directly with UI.
### :muscle: Improvement
- [Android Stack](https://docs.appcircle.io/infrastructure/android-build-infrastructure) Android Build Infrastructure updated. Now the default JAVA version is 11.
- [iOS Stack](https://docs.appcircle.io/infrastructure/ios-build-infrastructure) iOS Build Infrastructure updated. Xcode 13.4 added to iOS agents.
- [Workflow Management](https://docs.appcircle.io/workflows/#setting-up-workflows) You can now import or export your workflows as a YAML file.
- [Appcircle CLI Update](https://www.npmjs.com/package/@appcircle/cli) Getting Live and Beta versions added to CLI.
- When you download the logs, the profile and branch names will be added to the file name.
### 🐞 Fixed
- Browser UI issues fixed
## 2.9.2 - 2022-03-16 - SSO Login for Enterprise, Cached Builds
### 🆕 New Feature
- [SSO Login](https://docs.appcircle.io/account/sso/single-sign-on) is now available for all Enterprise accounts. You can connect your SAML and OpenID Provider right now!
- [Cached Builds](https://docs.appcircle.io/workflows/common-workflow-steps/#cache-push) are available to all. You can now use the Cache Push and Cache Pull components on your workflows to cache your dependencies and speed up your builds.
### 🐞 Fixed
- Browser UI issues fixed
## 2.9.1 - 2022-02-07 - Huawei AppGallery, New Components, Improved Triggers
### 🆕 New Feature
- Huawei AppGallery support added. You can submit your apk or aab files to Huawei AppGallery.
- Java 11 added to iOS agents
- [Slather](https://docs.appcircle.io/workflows/ios-specific-workflow-steps#slather),[Tuist](https://docs.appcircle.io/workflows/ios-specific-workflow-steps#tuist) and Badge components added
- You can now see all your running builds from the status bar and cancel them.
- [Skip the Workflow](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers/#skipping-a-workflow) if the commit message includes `[skip ci]` or `[ci skip]`
- [Retry Merge/Pull Request workflow](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers/#retrying-a-workflow) if the comment includes `[retry]`
### :muscle: Improvement
- [Triggers updated](https://docs.appcircle.io/build/build-process-management/build-manually-or-with-triggers/#auto-build-on-every-push). You can use a default config for new branches. You no longer need to configure every branch.
- [New environment variables](https://docs.appcircle.io/environment-variables/appcircle-specific-environment-variables/) added for commit message, build number, PR number, time stamp.
- You can now download build logs directly from the menu.
- [Node Install](https://docs.appcircle.io/workflows/react-native-specific-workflow-steps#install-node) step uses `lts` version as default.
- Error messages are clarified for build permissions.
### 🐞 Fixed
- GitLab Merge Request Webhook fixed
- Browser UI issues fixed
- Sometimes progress bar was showing on the wrong branch. Fixed.
### 📑 Documentation
- Added Huawei AppGallery section for sending your apps to Huawei AppGallery.
- Added [Huawei AppGallery](https://docs.appcircle.io/account/adding-huawei-api-key) section for creating Huawei AppGallery API Key.
- Added [FAQ section](/build/platform-build-guides/building-ios-applications#cocoapods-errros-due-to-version-mismatch) for Cocoapods version.
- Added [FAQ section](/build/platform-build-guides/building-ios-applications#provisioning-profile-error) for Provisioning Profiles.
- Added [FAQ section](/build/platform-build-guides/building-android-applications#gradle-build-after-bintray-shutdown) for Bintray deprecation
- Added [FAQ section](/build/platform-build-guides/building-flutter-applications#faq) for Flutter build errors
- Added [FAQ section](/build/platform-build-guides/building-flutter-applications#faq) for Flutter file naming errors
- Added [FAQ section](/build/platform-build-guides/building-flutter-applications#faq) for Flutter Firebase version
- Added [FAQ section](/build/platform-build-guides/building-react-native-applications#faq) for React native apps
## 2.9.0 - New Build Profile Detail UI, Better Artifact Upload Times
### 🆕 New Feature
- We have a brand new build profile detail UI! This new UI aims ease the access to workflows and triggers. It also has some improvements on onboarding.
### :muscle: Improvement
- Improved typography throughout the app. Working on more improvements and UI changes.
- We've improved artifact upload times drastically.
### 🐞 Fixed
- Fixed an issue where build logs were cut in half when multiple browser tabs were displaying the same build logs.
## 2.8.0 - 2021-10-25 - Improved Build Logging, Refresh Repository Connection, Persistent Notifications
### 🆕 New Feature
- A branch or a commit is missing? You can refresh repository connections for GitLab, GitHub, and Bitbucket repositories. Just look for the refresh icon on top of the branch list.
### :muscle: Improvement
- Build Notifications will sync between browsers and devices now.
- Removed unnecessary version texts from build steps on log panels.
- Build logging is improved for larger projects that have half a million lines of build logs.
### 🐞 Fixed
- Sometimes recent build logs were not displaying properly. Fixed.
- Branch pinning was not syncing between browsers.
- Some users weren't able to display the build artifacts after a successful build. It happened on way old builds too. Now they are accessible.
- Slack Distribution notifications didn't include platform info. Now they do and they won't look like double notifications for builds that have multiple distribution configs.
- Some large builds were uploading their artifacts very slowly. Now they are much faster.
## 2.7.0 - 2021-09-29 - Xcode 13.0 Support, Carthage on Workflows, Renaming Workflow Steps
### 🆕 New Feature
- You can now rename workflow steps.
- Carthage Dependency Manager for iOS is available as a workflow step
- Xcode 13.0 Public release is available.
### :muscle: Improvement
- We've added build number next to version number on artifacts distributed to testers.
- Improved commit and build listing for very large projects.
- Added iPhone 12 to emulator module.
- Improved iOS certificate and provisioning profile matching algorithm.
- Workflow name added as the title of the build logs detail screen.
- Small UI improvements
### 🐞 Fixed
- Fixed a bug where pasting SSH private key would add newlines to the key.;
- Fetch details on branch config defaults to Xcode 12.5.x instead of 12.0.
- Custom script workflow step didn't select any language initially. It selects bash now.
- Fixed some merge commits not triggering auto-build issue.
- Fixed an issue where workflow starting time was different from the user's local time.
## 2.6.0 - 2021-09-14 - Easier iOS Certificate and Provisioning Profile Management, Flutter 2.5.0 Support
With this release, we're adding the ability to connect to Apple for easier iOS Certificate and Provisioning Profile management. You can now add an App Store Connect API Key to your account and with it, Appcircle will list all the certificates and provisioning profiles you have on your Apple Developer account.
To set up an API Key, check this guide:
Adding an App Store Connect API Key
After adding an API Key, you can add new signing identities from the Signing Identities section. For more information on how to add identities and use them, check out [Signing Identities guide](/signing-identities).
### 🆕 New Feature
- Flutter version `2.5.0` is released in their stable channel. You can now use this latest stable version on Appcircle.
## 2.5.0 - 2021-08-27 - Two Factor Authentication, Self Hosted GitLab and Bitbucket, Xcode 13 Beta 5
Within this release, we bring fully built-in Appcircle support for your Self Hosted (Enterprise) for:
- [Bitbucket Self Hosted](/build/manage-the-connections/connection-guides/connecting-to-bitbucket#connecting-to-bitbucket-server-self-hosted-repository)
- [GitLab Self Hosted](/build/manage-the-connections/connection-guides/connecting-to-gitlab#connecting-to-gitlab-self-hosted-repository)
solutions. Click on them to see how to connect your self hosted repository within Appcircle!
:::info
### Notice about GitHub OAuth
Appcircle removed GitHub OAuth connection support in the new connections. Starting from this release, the new connections will only be using GitHub App.
Your current GitHub OAuth connection will stay as is. However, Appcircle recommends you to switch to GitHub app for better support.
:::
:::caution
### Disclaimer for React Native Users
The default Node version which Appcircle uses to build React Native apps are upgraded from v13 to v16. If your app relies on v13 or another specific version of Node, [refer to this documentation](https://docs.appcircle.io/workflows/react-native-specific-workflow-steps#install-node) to configure your node version. You can change your node version on your workflow settings at **Install Node** step.
:::
If your app targets Android 11, please read the following documentation to enable V2 Signing in your Build Profile:
https://docs.appcircle.io/build/building-android-applications/android-signing-for-google-play#enable-v2-sign-in-appcircle
### 🆕 New Feature
- iOS builds will be using Xcode 13 Beta 5 if 13.0.x is selected as Xcode version.
- Appcircle is now more secure with Two Factor Authentication 🔒 Refer to [this documentation](https://docs.appcircle.io/account/my-account/authenticator-two-factor-authentication) to secure your account 🔑
- Appcircle now supports Android V2 Signature Scheme out of the box.;
### :muscle:Improvement
- Repository Connection now has a new look and feel! Refer to [this documentation](/build/manage-the-connections/connection-guides) to see the new connection screens or dive right into the connection module to check our new simplified experience!
### 📑 Documentation
- If you use a single profile to produce multiple apps, we have written a [new documentation](https://docs.appcircle.io/building-multiple-apps-in-one-profile) about how to utilize your Product Variants(Android) or Multiple Targets(iOS) within Appcircle!
## 2.4.0 - 2021-07-30 - Xcode 13 Beta 4 & Manual Build Workflow Select;
This release focuses on stability with optimizing the logging of the builds.
Within this release as prior to the previous release, Appcircle also supports [Xcode 13 Beta 4](https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes). When 13.0.x from the Xcode Version is selected, the Xcode version will be Xcode 13 Beta 4.
### 🆕 New Feature
- iOS builds will be using Xcode 13 Beta 4 if 13.0.x is selected as Xcode version.
- Added metadata (Organization ID, OS version etc.) at the beginning of the Build Logs
- While manually building the workflow, Appcircle now lets you choose which workflow to trigger:
### :muscle:Improvement
- Commit Status on PR/CR is more detailed than before, you can track your progress(not only fail/success) as well, integrated with CI/CD progresses of the repository providers. More info is located at [Sending the build status to repository providers](https://docs.appcircle.io/build/building-ios-applications#sending-the-build-status-to-the-repository-providers) documentation
### 🐞 Fixed
- Fixed a bug that on **Save **button not being activated while chaning config values on Store Submit;
- Fixed a bug that the build tab was showing an empty column when the branch is deleted
- \[UI] Fixed the style of Delete button on the version list of Testing Distribution
### ; 📑 Documentation
- Added [FAQ section](/build/build-process-management/binary-actions#artifact-storage-is-full) of how to delete old artifacts.
- Improved [Sending the build status to repository providers](https://docs.appcircle.io/build/building-ios-applications#sending-the-build-status-to-the-repository-providers) section for better CI/CD pipeline tracking.
## 2.3.0 - 2021-06-28 - Xcode Version Updates
Within this release, Appcircle now supports [Xcode 13 Beta 2](https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes). When 13.0.x from the Xcode Version is selected, it will be using Xcode 13 Beta 2.
### 🆕 New Feature
- iOS builds will be using Xcode 13 Beta 2 if 13.0.x is selected as Xcode version.
- iOS builds will be using Xcode 12.5.1 if 12.5.x is selected as Xcode version.
- Google Play Store submit now supports internal channel uploads.
### :muscle:Improvement
- New profiles with Flutter iOS will have `--no-codesign`\*\* \*\*and `--verbose` parameters as default for easier debugging.;
- Increased allocated size over each build, now you can build bigger projects on Appcircle 🎉
- Further optimizations towards Android side of builds. Build times are considerably faster on Android 🎉
- The Date\&Time which Appcircle uses on their logs now will show the local time instead of the server time.
- Code gloss-over for [Appcircle CLI](https://www.npmjs.com/package/@appcircle/cli).
- If you are using an internal network, check the IP addresses you need whitelist through the document below:
Accessing Repositories in Internal Networks (Firewalls)
### 🐞 Fixed
- Fixed a bug that **Config **section appearing disabled when connected to the repository for the first time
- Fixed a bug that causes Store Submit modules to not show correct progress while the upload is in progress.
### 📑 Documentation
- Added [React Native Specific FAQ](/build/platform-build-guides/building-react-native-applications#faq) section
## 2.2.0 - 2021-06-16 - Xcode Version and CLI Improvements
This release includes the new Xcode 13.0, a new CLI look\&feel and marketplace to peek workflows as a bulk.
:::caution
### Important Update for iOS Developers
Since April 26, Apple removed the support of Store Submission for pre Xcode 12.0 and iOS SDK 14.0 compiled apps. Make sure that your Xcode version is greater or equal to Xcode 12.0 under your repository config.
More info is located under: [https://developer.apple.com/news/?id=ib31uj1j](https://developer.apple.com/news/?id=ib31uj1j);
:::
### 🆕 New Feature
- You can specify which Xcode version to use on your builds. This can also be specified on the repository and will be seamlessly fetched from the relevant repository during the **Fetch Details** Process. Available versions: 13.0, 12.5, 12.4, 12.3, 12.2, 12.1, 12.0, 11.7, 11.6, 11.5, 11.4, 11.3, 11.2, 11.1 and 11.0
- Latest Xcode 13 beta is used on 13.0.x
- [Appcircle CLI ](https://www.npmjs.com/package/@appcircle/cli)has a fresh look\&feel and lots of new features along with it.
- [Export Build Artifacts](https://docs.appcircle.io/workflows/common-workflow-steps#export-build-artifacts) has been added for a separate step. You can remove this step and upload your files elsewhere if your artifacts have a need to be on-premise.
- [Setting build status](https://docs.appcircle.io/build/building-ios-applications#sending-the-build-status-to-the-repository-providers) updates to the repository providers - You can now send updates about a commit to the repository providers for a complete CI/CD experience.
- A new workflow setting, **Always run this step even if the previous steps fail** has been added. The steps which have this enabled will always run.
- [Appcircle Marketplace](https://www.appcircle.io/integrations/) has been released. Checking which features are supported built-in has never been easier!
### :muscle:Improvement
- iOS Build Servers are optimized to reduce the queue time & better performance.
- Added better icons for Git providers when connecting to the repository.
- Whitelist IPs are under update process, you can follow the process under [Accessing Repositories in Internal Networks](https://docs.appcircle.io/build/manage-the-connections/accessing-repositories-in-internal-networks-firewalls/) document.
### 🐞 Fixed
- Fixed a bug that the same commit not appearing on multiple branches.
- Fixed a bug that new SSH connections being unable to fetch config.;
## 2.1.5 - 2021-05-10 - GitHub App for Repository Connections
This release includes the release of Appcircle GitHub app and the share app previews along with feature improvements.
### 🆕 New Feature
- [Appcircle GitHub App](/build/manage-the-connections/connection-guides/connecting-to-github) - You can now connect to GitHub with the Appcircle GitHub app as an alternative to the oAuth connection.
- [Share App Preview Links](/testing-distribution/create-or-select-a-distribution-profile#manual-binary-upload) - You can now share in-browser app preview links automatically with the testers as an alternative to app binaries. No physical device needed for testing.
### :muscle:Improvement
- Improved new workflow addition;
- New status bar for live build tracking and quick team switching
- Workflow and trigger user interface improvements
### 🐞 Fixed
- Workflow and trigger fixes
- User interface fixes
- Entity deletion fixes
## 2.1.0 - 2021-04-23 - Repo-Level Workflows and PR/MR Triggers
This is a major release with the complete revamp of the build workflows and autobuild triggers for repository-level workflows and triggers along with the new PR/MR trigger option.
### 🆕 New Feature
- [Repository-level workflows](/workflows) - You can now define multiple workflows in a build profile and assign them to multiple branches or assign multiple workflows to the same branch. You can also clone workflows for easier management.
- [Repository-level triggers](/build/build-process-management/build-manually-or-with-triggers) - You can now specify triggers in the build profile level with wildcards for branch names and workflow selection for each trigger for higher flexibility and manageability of the build profiles.
- [Pull request/merge request triggers](/build/build-process-management/build-manually-or-with-triggers#auto-build-pullmerge-requests) - You can now trigger builds whenever you initiate a pull request or merge request from a source branch to the target branch. The build will be done with the pull/merge result. This allows testing the PR/MR result before the actual approval of the request.
### :muscle:Improvement
- Under-the-hood improvements for logging and user authentication
- User interface improvements
- Performance improvements
### 🐞 Fixed
- License management fixes
- User interface fixes
## 2.0.0 - 2021-03-21 - Appcircle CLI and the New Customer Portal
This major release introduces the Appcircle CLI and a new customer portal for billing and plan management along with the Appcircle distribute API.
### 🆕 New Feature
- Appcircle CLI - You can now access the Appcircle platform from the command line for custom pipelines or advanced automation use cases. [Appcircle CLI is available on npm](https://www.npmjs.com/package/@appcircle/cli).
- Appcircle Distribute API - On top of the previously released build APIs, the Testing Distribution APIs are now available for programmatic access.
- New Customer Portal - Billing and plan management is now easier and more flexible with the new customer portal.
### :muscle:Improvement
- Account and organization deletion improvements
- Plan upgrade and downgrade improvements
### 🐞 Fixed
- Webhook trigger fixes
- Emulator/simulator issue reporting fixes
- API and API portal fixes
## 1.7.0 - 2021-03-07 - Appcircle Build API and Experience Improvements
This release introduces the Appcircle API with the build module and all around experience features in various areas.
### 🆕 New Feature
- Appcircle API - You can now utilize the Appcircle API for programmatic access to the platform features. This release includes the build module APIs.
- Personal API Token - You can generate a token to access the Appcircle API
- Webhook support for AWS CodeCommit and Azure DevOps git repositories
- In-browser emulator/simulator rotation and restart features
- In-browser emulator/simulator issue reporting - You can now share screenshots and notes over email while running an app preview.
- System message trace ID - You can now get the trace ID for each system message for easier troubleshooting.;
### :muscle:Improvement
- Flutter 2.0 support
- Organization ID management improvements
- Webhook URL management improvements
- Logging and reporting optimizations
### 🐞 Fixed
- Webhook support fixes
- SSH connection fixes
- Failed plan upgrade payment fix
## 1.6.0 - 2021-02-09 - Replicate Configuration, Git Webhooks and Advanced Role Management
This release introduces the two most requested features along with the enterprise-grade role management.
### 🆕 New Feature
- Copy/Set Branch Configuration - You can now copy the configuration from a branch to other branches in the same build profile for easy replication of the same configuration.;
- Webhooks for Git - With the webhook support for the compatible git providers, you can enable build triggers through SSH connections without the need for app authorization
- Advanced Role Management - You can now set submodule based access;
### :muscle:Improvement
- Branch list viewing improvements
- SSH connection improvements
- User interface optimizations
### 🐞 Fixed
- Slack notification fixes
- Environment variable management fixes
- User interface fixes
- License limit and access fixes
## 1.5.0 - 2021-01-22 - Slack Notifications for All Modules
This release includes support for Slack notifications for the major events in all modules along with minor features and fixes.
### 🆕 New Feature
- Slack Notifications for All Modules - You can now get notified for Signing Identity, Distribute and Store Submit module events through Slack (in addition to the Build module).;
- Storage Management - You can now delete build artifacts and app versions in select plans.
- Branch Pinning in Build Profiles - You can pin the primarily used branches in build profiles for easy access.
### :muscle:Improvement
- Artifact and binary management improvements
- Slack notification improvements
- Third-party connections management improvements
- Improved FAQ and troubleshooting
- User interface improvements towards better guidance
### 🐞 Fixed
- User interface issues in Safari
- Repository connection issues
- App preview sharing fixes
## 1.4.0 - 2020-12-08 - Auto Store Deployments and Emulator Starter Plan;
This release includes the automatic public store deployment feature and the introduction of a new Starter-based upgrade plan for higher Emulator/Simulator minutes.
### 🆕 New Feature
- Auto deployment to the Store Submit Module - You can now deploy your builds automatically to the Store Submit Module by enabling the setting in the build configuration
- Auto upload to Public Stores - You can now upload deployed apps automatically to Google Play Console and App Store Connect
- New Emulator Plan - This plan provides additional emulator minutes over the Starter plan, mainly for the standalone emulator/simulator users.
### :muscle:Improvement
- Store Submit Module improvements
- Under-the-hood Standalone Emulator/Simulator improvements
- Billing and plan info view improvements
### 🐞 Fixed
- Public store credential management fixes
- Various user interface fixes
- Standalone Emulator/Simulator fixes
## 1.3.0 - 2020-11-16 - Maintenance Update
This release is a maintenance update with all around improvements.
### 🆕 New Feature
- Direct signing identity uploads in the build module - You can add signing identities directly from the build configuration if the signing identities module is empty.
### :muscle:Improvement
- Reporting improvements
- Standalone Emulator interface improvements
- App sharing interface improvements
- File size display and upload dialog improvements
- Various user interface improvements
### 🐞 Fixed
- Repository connection fixes
- Preview on device report update period fix
- Emulator share link error state fix
- Emulator share expiry duration fix
- Plan limit update fixes
- Various user interface fixes
## 1.2.0 - 2020-10-27 - Standalone Emulator/Simulator
This release includes the new in-Browser Emulator/Simulator module and Amazon Device Farm Support.
### ;🆕 New Feature
- Standalone Emulator for web sites and app uploads - You can now use the "Preview on Device" feature as a standalone module with support for direct uploads and web site previews.
- Device preview share - Just like sending apps to the testers, you can now share in-browser app preview links with the testers.
- AWS Device Farm Support - AWS Device Farm is now available as a workflow step. You can deploy apps to AWS Device Farm and run tests as a part of your pipeline.
### :muscle:Improvement
- Billing-related improvements
- Preview on device fixes in line with the Standalone Emulator
- Android 11 and iOS 14 support in device previews
### 🐞 Fixed
- GitLab branch listing fix
- Large file upload fix
- Further environment variables module fixes
## 1.1.0 - 2020-10-12
This release includes experience improvements along with support for Flutter Web builds.
### ;🆕 New Feature
- Flutter Web Support - You can now build your Flutter Web apps along with Flutter iOS and Android apps.
- Centralized Credentials for Store Uploads - for Google Play and App Store Connect uploads, the credentials can now be saved for reuse.
- Apple ID with App-specific password support for App Store Connect uploads.;
### :muscle:Improvement
- Improved multi-provisioning profile support (e.g. for Apple Watch builds) in iOS builds
- User experience improvements in the Store Submit module
- User experience improvements in the Environment Variables Module
### 🐞 Fixed
- Theme-related UI fixes
- Store upload fixes
- Environment variables module fixes
- Further state preservation fixes
## 1.0.0 - 2020-09-23 - Initial Release
We are excited to announce that Appcircle beta is complete and it is fully released with version 1.0. You can now use Appcircle with full set of features.
This is of course just a start of a long journey. Follow us on Twitter [@appcircleio](https://twitter.com/appcircleio) for updates.
For any questions, feedback or feature requests, just drop us a message using the in-app messaging or raise an issue in Appcircle GitHub: [https://github.com/appcircleio](https://github.com/appcircleio)
### ;🆕 New Feature
- Send apps to Public Stores - You can now send your apps to App Store Connect through the App Store Connect API.;
- Theme support with Dark Mode - There is an Appcircle for everyone. You can now select between Light, Dark and the Darker modes.
- Upload to Amazon S3 step - You can now deploy any file or folder to an Amazon S3 bucket with the new workflow step.
### :muscle:Improvement
- Xcode 12 GM support;
- User experience improvements in line with the theme support
### 🐞 Fixed
- Multimodule support fix
- Billing plan fixes
- State preservation fixes
---
## Overview & Concepts
Self-hosted Appcircle enables you to use your own systems and infrastructure for all cloud features.
By this way, you can build and test your apps on your choice of architectures. You have full control over the build environment. You can also customize your Appcircle installation with various options.
With the help of self-hosted runners as connected agents, you can have whole Appcircle in your own infrastructure and use all Appcircle features in your private cloud without any limitations.
Self-hosted Appcircle section in here, gives you detailed information about only server-side components installation and other related operations. For details about self-hosted runner concept, see [Self-hosted Runner](/self-hosted-appcircle/self-hosted-runner) section in docs.
:::caution
The only requirement for using self-hosted Appcircle is to be in `enterprise` plan.
See [pricing](https://appcircle.io/pricing) and feature comparison table for details.
:::
## Docker/Podman Standalone Architecture
We generally recommend a standalone approach by deploying a single node environment for the Appcircle server to reduce the complexity a little further.
When we look at self-hosted Appcircle deployment as a whole, we will see below architecture in execution for a basic installation.
To see the topology diagram in greater detail, click [here](https://cdn.appcircle.io/docs/assets/be-3008-appcircle-topology.png). It will open the diagram in new browser tab.
:::tip
You can see all external network access details on the [Network Access](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access) page.
:::
## Docker/Podman Architecture With DMZ Support
If you plan to use the Enterprise App Store and Testing Distribution modules isolated from the internal network in which these modules are only exposed to the external networks, you can use Docker/Podman Architecture in DMZ formation.
For more information about the Appcircle DMZ architecture, you can check the [Enterprise App Store and Testing Distribution in DMZ](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz) document.
## Kubernetes/OpenShift Architecture Using Helm Chart
In addition to the standalone and DMZ architectures, you can deploy Appcircle using the Helm chart for Kubernetes/OpenShift environments. This method allows for greater scalability and management flexibility.
For detailed instructions on installing and configuring Appcircle using the Helm chart, refer to the relevant Helm chart installation documentation for [Kubernetes](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes) or [OpenShift](/self-hosted-appcircle/install-server/helm-chart/installation/openshift). These documentation pages include steps for setting up Helm, configuring `values.yaml`, and deploying the Appcircle server.
### Advantages
- **High Availability:** Deploying on Kubernetes/OpenShift ensures high availability through automated failover and load balancing.
- **Scalability:** Supports high traffic and large-scale applications with horizontal scaling based on load, ensuring optimal performance. Easily scale your deployment by adding or removing nodes in the Kubernetes/OpenShift cluster.
- **Fault Tolerance:** Kubernetes/OpenShift can handle node failures and automatically reschedule workloads to maintain application uptime.
### Disadvantages
- **Complexity:** Requires familiarity with Kubernetes/OpenShift and Helm, which can be complex to learn and manage.
- **Resource Requirements:** May require more resources compared to a single-node deployment, including more compute power and storage.
- **Operational Overhead:** Maintaining and monitoring a Kubernetes/OpenShift cluster can add operational overhead.
---
## Helm Advanced Configuration
For advanced configuration options, open the `values.yaml` file with your preferred text editor and modify the settings as needed.
Once you have updated the `values.yaml` file, please proceed to the [Upgrade Appcircle Server](/self-hosted-appcircle/install-server/helm-chart/upgrades) section to apply the changes.
## Custom Testing Distribution Domain
To configure a custom domain for the Appcircle Testing Distribution, update your `values.yaml` file with the custom domain settings. Below is an example configuration for a custom Testing Distribution domain usage:
```yaml
global:
distribution:
distribution-testerweb:
url: https://dist.spacetech.com
distribution:
distribution-testerweb:
ingress:
extraHosts:
- name: dist.spacetech.com
path: /
extraTls:
- secretName: k8s-dist-spacetech-com-tls
hosts:
- dist.spacetech.com
```
:::caution
The emails related to the Testing Distribution will now include the new domain in the links. Please note that old links associated with the previous domain will no longer work.
:::
After updating the `values.yaml` file, create a TLS secret for the custom domain using the following command:
:::info
- The certificate (`cert`) should be in **PEM format** and it's recommended to include the leaf (app), intermediate, and root (CA) certificates to form a **full-chain** certificate.
- The private key (`key`) **should not be password-protected**.
:::
```bash
kubectl create secret tls k8s-dist-spacetech-com-tls \
--cert=fullchain.crt \
--key=private.key
```
## Increase the Replica Counts
With the default Helm values, the Appcircle server services being deployed with one replica. If you want to increase this number for high availability, you can do so by updating your `values.yaml` file:
:::caution
Some keys might already exists in your `values.yaml` file, make sure to update the existing keys instead of adding new ones.
:::
```yaml
agentcache:
replicaCount: 2
auth:
auth-keycloak:
replicas: 2
apigateway:
replicaCount: 2
appparser:
replicaCount: 2
build:
replicaCount: 2
distribution:
distribution-server:
replicaCount: 2
distribution-testeradmin:
replicaCount: 2
distribution-testerapi:
replicaCount: 2
distribution-testerweb:
replicaCount: 2
distribution-web:
replicaCount: 2
license:
replicaCount: 2
notification:
replicaCount: 2
otp:
replicaCount: 2
publish:
replicaCount: 2
reporting:
replicaCount: 2
resign:
replicaCount: 2
resource:
replicaCount: 2
schedulemanager:
replicaCount: 2
signingidentity:
replicaCount: 2
store:
store-web:
replicaCount: 2
store-admin:
replicaCount: 2
store-api:
replicaCount: 2
store-profile:
replicaCount: 2
store-report:
replicaCount: 2
storesubmit:
replicaCount: 2
taskserver:
replicaCount: 2
web:
web-app:
replicaCount: 2
web-event:
replicaCount: 2
webhook:
replicaCount: 2
```
## Applying Configuration Changes
## Values Table
To deploy the Appcircle server with customized parameters, refer to the basic `values.yaml` configuration table below.
### Parameters
| Parameter | Description | Default Value |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------- |
| `global.appEnvironment` | Specifies the application environment (e.g., Development, Production). | 'Production' |
| `global.imageRegistry` | The Docker registry where container images are stored. | 'europe-west1-docker.pkg.dev' |
| `global.imageRepositoryPath` | The path within the Docker registry for the application's images. | 'appcircle/docker-registry' |
| `global.imageTag` | The specific tag of the Docker image to use. | 'v3.23.2' |
| `global.imagePullSecrets` | Secrets used to authenticate with private container registries. | [ 'containerregistry' ] |
| `global.ingressClassName` | Specifies the ingress class name used for all application ingresses. | 'appcircle' |
| `global.defaultStorageClass` | The default storage class used for persistent volumes in the application. | - |
| `global.urls.domainName` | The domain name used for the application (e.g., .example.com). | - |
| `global.urls.scheme` | The URL scheme used for the application (e.g., http or https). | 'http' |
| `global.urls.auth.subdomain` | Subdomain used for the authentication service. | 'auth' |
| `global.urls.privateApi.subdomain` | Subdomain used for the private API service. | 'api' |
| `global.urls.webApp.subdomain` | Subdomain used for the web application. | 'my' |
| `global.urls.webEvent.subdomain` | Subdomain used for the web event service. | 'hook' |
| `global.urls.distributionTesterWeb.subdomain` | Subdomain used for the distribution tester web. | 'dist' |
| `global.urls.store.subdomain` | Subdomain used for the store service. | 'store' |
| `global.urls.webEventRedis.subdomain` | Subdomain used for the web event Redis service. | 'kvs' |
| `global.urls.resource.subdomain` | Subdomain used for the resource service. | 'resource' |
| `global.mail.provider` | Mail provider to use (e.g., MailKitSMTP, SMTP ). | 'MailKitSMTP' |
| `global.mail.smtp` | SMTP configuration details. | - |
| `global.mail.smtp.host` | SMTP server hostname. | - |
| `global.mail.smtp.username` | SMTP username. | - |
| `global.mail.smtp.from` | The "From" address used for emails. | - |
| `global.mail.smtp.fromDisplayName` | The display name for the sender of emails. | - |
| `global.mail.smtp.port` | Port number for the SMTP server. | - |
| `global.mail.smtp.password` | Password for the SMTP account. | - |
| `global.mail.smtp.ssl` | Whether SSL is enabled for SMTP. | 'false' |
| `global.mail.smtp.auth` | Whether authentication is enabled for SMTP. | 'true' |
| `global.mail.smtp.starttls` | Whether STARTTLS is enabled for SMTP. | 'true' |
| `global.distribution.distribution-testerweb.url` | The external URL for the distribution tester web module. | - |
| `global.tlsWildcard.cert` | The wildcard TLS certificate. | - |
| `global.tlsWildcard.caCert` | The Certificate Authority (CA) for the wildcard certificate. | - |
| `global.tlsWildcard.key` | The private key for the wildcard certificate. | - |
| `global.trustedCerts` | List of trusted certificates. | [] |
| `global.minio.url` | External MinIO URL. | - |
| `global.minio.region` | The region for MinIO. | `local` |
| `global.minio.bucketPrefix` | Prefix for MinIO buckets. | `appcircle-local-resource-` |
| `global.containerRegistrySecret` | Secret used for accessing the container registry. | - |
| `global.redis.enabled` | Whether a common Redis instance is enabled for all modules. | `false` |
| `global.redis.everyModule` | Whether separate Redis instances are enabled for each module. | `true` |
| `global.vault.url` | External URL for Vault. | - |
| `auth.auth-keycloak.adminUsername` | Admin username for Keycloak. | 'admin' |
| `auth.auth-keycloak.initialUsername` | Initial username for the default user. | 'admin@myappcircle.io' |
| `auth.auth-keycloak.organizationName` | Initial organization name in Keycloak. | 'myappcircle' |
| `auth.auth-keycloak.allowDisposableEmails` | Determines whether disposable emails are allowed for registration. | false |
| `auth.auth-keycloak.bruteForce.bruteForceProtected` | Enables brute force protection for Keycloak. | 'true' |
| `auth.auth-keycloak.bruteForce.failureFactor` | Number of failed login attempts before action is taken. | '30' |
| `auth.auth-keycloak.bruteForce.maxDeltaTimeSeconds` | Maximum time in seconds to consider failed login attempts. | '43200' |
| `auth.auth-keycloak.bruteForce.maxFailureWaitSeconds` | Maximum wait time in seconds after consecutive failures. | '900' |
| `auth.auth-keycloak.bruteForce.minimumQuickLoginWaitSeconds` | Minimum wait time in seconds for quick login attempts. | '60' |
| `auth.auth-keycloak.bruteForce.permanentLockout` | Enables permanent account lockout after repeated failures. | 'false' |
| `auth.auth-keycloak.bruteForce.quickLoginCheckMilliSeconds` | Time in milliseconds to check quick login attempts. | '1000' |
| `auth.auth-keycloak.bruteForce.waitIncrementSeconds` | Time increment in seconds for wait periods after failures. | '60' |
| `auth.auth-keycloak.cli.enabled` | Enables the Keycloak CLI for custom commands. | false |
| `auth.auth-keycloak.database.database` | Name of the Keycloak database. | - |
| `auth.auth-keycloak.database.hostname` | Hostname of the Keycloak database. | - |
| `auth.auth-keycloak.database.password` | Password for the Keycloak database. | - |
| `auth.auth-keycloak.database.port` | Port number for the Keycloak database. | - |
| `auth.auth-keycloak.database.username` | Username for the Keycloak database. | - |
| `auth.auth-keycloak.database.vendor` | Database vendor for Keycloak (e.g., postgres, mysql). | 'postgres' |
| `auth.auth-keycloak.defaultUserGroupRoles` | Default roles assigned to new users in Keycloak. | - |
| `auth.auth-keycloak.dmzCustomDomain.domain` | Domain name for the DMZ custom configuration. | - |
| `auth.auth-keycloak.dmzCustomDomain.enabled` | Enables custom domain for DMZ. | false |
| `auth.auth-keycloak.enabledOrganization` | Enables the organization feature in Keycloak. | - |
| `auth.auth-keycloak.enabledRegistration` | Enables user registration in Keycloak. | - |
| `auth.auth-keycloak.extraEnv` | Additional environment variables for the Keycloak deployment. | [] |
| `auth.auth-keycloak.extraInitContainers` | Additional init containers for the Keycloak deployment. | [] |
| `auth.auth-keycloak.extraVolumeMounts` | Extra volume mounts for the Keycloak deployment. | [] |
| `auth.auth-keycloak.extraVolumes` | Extra volumes for the Keycloak deployment. | [] |
| `auth.auth-keycloak.identityProviders.bitbucket.clientId` | Client ID for Bitbucket integration. | - |
| `auth.auth-keycloak.identityProviders.bitbucket.clientSecret` | Client secret for Bitbucket integration. | - |
| `auth.auth-keycloak.identityProviders.bitbucket.enabled` | Enables Bitbucket as an identity provider. | false |
| `auth.auth-keycloak.identityProviders.github.clientId` | Client ID for GitHub integration. | - |
| `auth.auth-keycloak.identityProviders.github.clientSecret` | Client secret for GitHub integration. | - |
| `auth.auth-keycloak.identityProviders.github.enabled` | Enables GitHub as an identity provider. | false |
| `auth.auth-keycloak.identityProviders.google.clientId` | Client ID for Google integration. | - |
| `auth.auth-keycloak.identityProviders.google.clientSecret` | Client secret for Google integration. | - |
| `auth.auth-keycloak.identityProviders.google.enabled` | Enables Google as an identity provider. | false |
| `auth.auth-keycloak.image.pullPolicy` | Image pull policy for Keycloak. | - |
| `auth.auth-keycloak.image.repository` | Repository for the Keycloak image. | - |
| `auth.auth-keycloak.image.tag` | Tag of the Keycloak image. | - |
| `auth.auth-keycloak.importRealm` | Enables importing of realms during startup. | false |
| `auth.auth-keycloak.ingress` | Ingress configuration for Keycloak. | - |
| `auth.auth-keycloak.ingress.enabled` | Enables ingress for Keycloak. | false |
| `auth.auth-keycloak.initialOrganizationId` | Initial organization ID for Keycloak. | - |
| `auth.auth-keycloak.initialPassword` | Initial password for the default user. | - |
| `auth.auth-keycloak.initialUsername` | Initial username for the default user. | 'admin@myappcircle.io' |
| `auth.auth-keycloak.organizationName` | Initial organization name in Keycloak. | 'myappcircle' |
| `auth.auth-keycloak.recaptcha.maxFailures` | Maximum failed attempts before requiring a reCAPTCHA. | '4' |
| `auth.auth-keycloak.recaptcha.requirement` | reCAPTCHA requirement level (e.g., DISABLED, OPTIONAL, REQUIRED). | 'DISABLED' |
| `auth.auth-keycloak.recaptcha.secret` | Secret key for reCAPTCHA integration. | - |
| `auth.auth-keycloak.recaptcha.siteKey` | Site key for reCAPTCHA integration. | - |
| `auth.auth-keycloak.userLookupDecisionStrategy` | Strategy for user lookup decisions in Keycloak. | - |
| `auth.auth-postgresql.architecture` | Defines the architecture of PostgreSQL (e.g., standalone, replication). | standalone |
| `auth.auth-postgresql.enabled` | Enables PostgreSQL for Keycloak. | true |
| `auth.auth-postgresql.auth.username` | Username for the PostgreSQL database. | 'keycloak' |
| `auth.auth-postgresql.auth.database` | The name of the PostgreSQL database to create. | 'keycloak' |
| `kafka.heapOpts` | JVM heap options for Kafka. | '-Xmx1408m -Xms512m' |
| `kafka.controller.replicaCount` | Number of Kafka controller replicas. | 3 |
| `kafka.controller.resourcesPreset` | Resource preset for the Kafka controller. | 'medium' |
| `kafka.controller.persistence.enabled` | Enables persistence for Kafka controller. | true |
| `kafka.controller.persistence.size` | Size of persistence storage for Kafka controller. | '8Gi' |
| `kafka.listeners.client.protocol` | Protocol used for Kafka client listener. | 'PLAINTEXT' |
| `kafka.listeners.controller.protocol` | Protocol used for Kafka controller listener. | 'PLAINTEXT' |
| `kafka.listeners.interbroker.protocol` | Protocol used for Kafka inter-broker communication. | 'PLAINTEXT' |
| `kafka.metrics.kafka.enabled` | Enables Kafka metrics. | false |
| `kafka.metrics.jmx.enabled` | Enables JMX metrics for Kafka. | false |
| `kafka.zookeeper.auth.enabled` | Enables authentication for ZooKeeper. | false |
| `kafka.zookeeper.metrics.enabled` | Enables metrics for ZooKeeper. | false |
| `kafka.client.protocol` | Protocol used by Kafka clients. | 'PLAINTEXT' |
| `kafka.extraConfig` | Additional configuration file for Kafka. | - |
| `webeventredis.enabled` | Enables WebEventRedis. | true |
| `webeventredis.tls.enabled` | Enables TLS for WebEventRedis. | false |
| `webeventredis.tls.existingSecret` | References an existing TLS secret for WebEventRedis. | 'appcircle-tls-wildcard' |
| `webeventredis.tls.certCAFilename` | Filename for the CA certificate in TLS. | 'ca.crt' |
| `webeventredis.tls.certFilename` | Filename for the server certificate in TLS. | 'tls.crt' |
| `webeventredis.tls.certKeyFilename` | Filename for the private key in TLS. | 'tls.key' |
| `webeventredis.ingress.enabled` | Enables ingress for WebEventRedis. | false |
| `webeventredis.ingress.tls` | Enables TLS for WebEventRedis ingress. | false |
| `webeventredis.ingress.ingressClassName` | Specifies the ingress class name for WebEventRedis. | `appcircle` |
| `webeventredis.ingress.annotations` | Annotations for WebEventRedis ingress. | - |
| `minio.enabled` | Enables MinIO. | true |
| `minio.mode` | MinIO mode (standalone, distributed, etc.). | 'standalone' |
| `minio.persistence.enabled` | Enables persistence for MinIO. | true |
| `minio.persistence.size` | Size of persistence storage for MinIO. | '8Gi' |
| `mongodb.enabled` | Enables MongoDB. | true |
| `mongodb.persistence.enabled` | Enables persistence for MongoDB. | true |
| `mongodb.persistence.size` | Size of persistence storage for MongoDB. | '5Gi' |
| `ingress-nginx.enabled` | Specifies whether ingress-nginx is enabled. | true |
| `ingress-nginx.controller.ingressClassResource.name` | Name of the IngressClass resource. | appcircle |
| `ingress-nginx.controller.ingressClassResource.enabled` | Specifies whether the IngressClass resource is enabled. | true |
| `ingress-nginx.controller.config.proxy-body-size` | Maximum allowed size of the client request body. | "4096m" |
| `ingress-nginx.controller.config.proxy-connect-timeout` | Timeout for establishing a connection to the backend server. | "600" |
| `ingress-nginx.controller.config.proxy-read-timeout` | Timeout for reading a response from the backend server. | "600" |
| `ingress-nginx.controller.config.client-header-timeout` | Timeout for reading the client request headers. | "180" |
| `ingress-nginx.controller.config.client-body-timeout` | Timeout for reading the client request body. | "180" |
| `ingress-nginx.controller.config.send-timeout` | Timeout for sending data to the client. | "180" |
| `ingress-nginx.controller.config.keepalive-timeout` | Timeout for idle keep-alive connections. | "75" |
| `ingress-nginx.controller.config.client-body-timeout` | Timeout for reading the client request body. | "180" |
| `ingress-nginx.controller.config.send-timeout` | Timeout for sending data to the client. | "180" |
| `ingress-nginx.controller.config.keepalive-timeout` | Timeout for idle keep-alive connections. | "75" |
| `ingress-nginx.controller.config.proxy-buffer-size` | Size of the buffer used for reading the first part of the response received from the proxied server. | "128k" |
| `ingress-nginx.controller.config.proxy-buffers-number` | Number of buffers used for reading a response from the proxied server. | "4" |
| `ingress-nginx.controller.config.proxy-busy-buffers-size` | Size of the buffer used for reading the entire response from the proxied server. | "128k" |
| `ingress-nginx.defaultBackend.enabled` | Specifies whether the default backend is enabled. | false |
| `vault.injector.enabled` | Enables the Vault sidecar injector. | false |
| `vault.server.dataStorage.size` | Size of the data storage for Vault. | '1Gi' |
| `vault.server.authDelegator.enabled` | Enables the auth delegator for Vault. | false |
| `vault.server.image.repository` | Repository of the Vault server image. | - |
| `vault.server.image.tag` | Tag of the Vault server image. | - |
| `vault.server.standalone.enabled` | Enables standalone mode for Vault. | true |
| `vault.server.standalone.config` | Configuration file for standalone Vault. | - |
| `vault.ui.enabled` | Enables the Vault UI. | true |
---
## Adding CA Certificates
## Adding Trusted CA Certificates to the Appcircle Services
If any services that the Appcircle server needs to connect to, such as your Git provider, use a self-signed SSL/TLS certificate or a certificate issued by an untrusted root CA from your organization, Appcircle will refuse the connection by default.
:::tip
To prevent potential issues with untrusted certificates, it is recommended to add your organization's root certificate from the Certificate Authority (CA) to Appcircle. This ensures that the server can properly validate and trust SSL/TLS certificates issued by your organization’s CA.
:::
To add these certificates as trusted, you need to update the `.global.trustedCerts` key in the `values.yaml` file and import the certificates.
:::info
The `.global` key already exists in your `values.yaml` file. You just need to add the `trustedCerts` key.
:::
The trusted certificate names must conform to the regex pattern `[-._a-zA-Z0-9]+`. It is recommended to use descriptive names for your certificates, such as `spacetech-root` for the root certificate and `spacetech-intermediate` for the intermediate certificate.
Here is an example of how to update the `values.yaml` file:
```yaml
global:
trustedCerts:
- name: spacetech-root
value: |
-----BEGIN CERTIFICATE-----
MIIGOTCCBCGgAwIBAgIUU5MNim6S8RDvILFbqSEEFJvqkUkwDQYJKoZIhvcNAQEL
...
JBr5DP/2RTmkKFtc53xoSYXQCmg61T8vMycvrdxWX6eAa8VSDszAtl//QFJIrwY8
ZmukIMGOIYPWDhsuJA==
-----END CERTIFICATE-----
- name: spacetech-intermediate
-----BEGIN CERTIFICATE-----
MIIGOTCCBCGgAwIBAgIUU5MNim6S8RDvILFbqSEEFJvqkUkwDQYJKoZIhvcNAQEL
...
JBr5DP/2RTmkKFtc53xoSYXQCmg61T8vMycvrdxWX6eAa8VSDszAtl//QFJIrwY8
ZmukIMGOIYPWDhsuJA==
-----END CERTIFICATE-----
```
---
## Domain Verification for Helm Chart Configuration
# Domain Verification
This document explains how to configure your Appcircle server's domain verification option when adding domains as trusted for Appcircle organizations. By skipping the domain verification process, domains will be automatically marked as verified without the need for TXT records.
Please note, this page does not cover the domain verification feature itself. For more detailed information on domain verification, please refer to the [Domain Verification](/account/my-organization/security/domain-verification) documentation.
By default, domain verification is **disabled** on the Appcircle server, meaning domains are automatically considered verified without the need to add a TXT record to your DNS configuration. However, if you change this option, Appcircle will require the addition of a TXT record to validate the domain.
## Configuring the Appcircle Server Chart
To enable or disable domain verification, follow these steps:
1. Open the `values.yaml` file in a text editor.
```bash
vi values.yaml
```
2. Locate the `auth` entry in the configuration file. Add or update the `domainVerification` key with the following settings, depending on your preference.
:::caution
If the `auth-keycloak` entry already exists in your `values.yaml` file, ensure you update the existing key instead of creating a new one.
:::
```yaml
auth:
auth-keycloak:
domainVerification:
enabled: true
```
:::note
- **`enabled`**: If this variable is set to `true`, it requires the addition of a TXT record for domain verification. If you want to skip TXT record verification and make the domain automatically considered as verified, then this variable should be set to `false`.
:::
3. Upgrade the Appcircle server release with new `values.yaml` settings.
4. Restart the Keycloak stateful set to apply new changes.
```bash
kubectl rollout restart statefulset appcircle-server-auth-keycloak -n appcircle
```
```bash
oc rollout restart statefulset appcircle-server-auth-keycloak -n appcircle
```
:::caution
Restarting the Keycloak stateful set affects active sessions and causes a redirection to the login page for the end-users to log in again. After re-login, the users can go on with their operations as usual from where they left off.
:::
---
## Enterprise App Store Customization
## Overview
Some additional Enterprise App Store settings can be customized for self-hosted installations in order to make them more tailored to your users.
You can change how your store looks using the **[Customize](/enterprise-app-store/portal-customization)** screen in the Enterprise App Store module, just like you can with Appcircle Cloud.
For self-hosted specific settings, you should follow the documentation below.
## Tab Title Localization
You can change the Enterprise App Store tab title according to the language selected on the self-hosted Appcircle server.
For example, you can set a title for **TR** and a different title for **EN** language selection on browsers.
If you set titles from `values.yaml` by following the steps below, your title settings configured from the Enterprise App Store's "Customize" page will be overridden.
```yaml
store:
store-web:
extraEnvVars:
- name: TR_STORE_TITLE
value: "Uygulama Mağazası"
- name: EN_STORE_TITLE
value: "App Store"
```
---
## External Image Registries for Helm Chart
# Overview
In Appcircle's orchestrated application ecosystem, users have the flexibility to access container images through various external image registries.
These external repositories serve as integral components, offering users different avenues to retrieve and manage container images based on their preferences and infrastructure requirements.
These services act as intermediaries, facilitating seamless image retrieval, caching frequently accessed images, and providing enhanced security measures for image distribution.
## Quay Configuration
Red Hat Quay provides a robust container registry solution that integrates well with Kubernetes and OpenShift environments. To configure Quay as your proxy registry, follow these steps:
- Enable the proxy cache feature by following one of these docs: [Project Quay Proxy Cache](https://docs.projectquay.io/config_quay.html#config-fields-proxy-cache), or [Red Hat Quay Proxy Cache](https://docs.redhat.com/en/documentation/red_hat_quay/3.13/html/use_red_hat_quay/quay-as-cache-proxy#red-hat-quay-proxy-cache-procedure).
- Create a new organization in Quay (e.g., named `appcircle`).
- Go to the organization settings and configure **Proxy Cache** section:
- Set **Remote Registry** as `europe-west1-docker.pkg.dev/appcircle/docker-registry`.
- Set **Remote Registry Username** as `_json_key`.
- Copy the content of your `cred.json` and paste into **Remote Registry Password** field.
- Save the configuration.
In the end, the configuration page should look like this:
## Appcircle Configuration
For the Appcircle server to work with your own container image registry, you should add additional settings to the `values.yaml` file of your deployment.
:::info
In this documentation, we will use `registry.spacetech.com` as an **example registry domain**, `spacetech` as an **example organization name** and `appcircle` as an **example namespace name**.
To see name and namespace of your existing Helm deployment, you can use the command below.
```bash
helm list --all-namespaces
```
:::
:::caution
If your registry uses a non-standard port (anything other than 443 for HTTPS or 80 for HTTP), you must specify it in the configuration as shown in the examples below with port `8083`.
:::
- Add or find the `imageRegistry` and `imageRepositoryPath` keys under `global` mapping in your `values.yaml` file.
- Additionally, you need to configure `vault`, `cert-utils-operator`, and `kube_rbac_proxy` images separately due to Helm restrictions that prevent automatic inheritance from the global registry settings.
Your configuration should be set as follows:
```yaml
global:
...
# Container image registry host for container images
imageRegistry: registry.spacetech.com:8083
# Container image repository path between registry host and image name (for Quay it is the organization name)
imageRepositoryPath: appcircle
...
# Appcircle vault configuration
vault:
server:
image:
# Appcircle vault image repository path
repository: registry.spacetech.com:8083/appcircle/appcircle-vault
cert-utils-operator:
image:
# Container image repository path for the cert-utils-operator
repository: registry.spacetech.com:8083/appcircle/cert-utils-operator
kube_rbac_proxy:
image:
# Container image repository path for the kube-rbac-proxy
repository: registry.spacetech.com:8083/appcircle/kube-rbac-proxy
...
```
Be careful with the indentation and the structure of the `values.yaml` file.
- Create a secret with credentials for the external container image registry.
```bash
kubectl create secret docker-registry containerregistry \
-n appcircle \
--docker-server='registry.spacetech.com:8083' \
--docker-username='yourRegistryUsername' \
--docker-password='superSecretRegistryPassword' \
--dry-run=client -o yaml | kubectl apply -f -
```
```bash
oc create secret docker-registry containerregistry \
-n appcircle \
--docker-server='registry.spacetech.com:8083' \
--docker-username='yourRegistryUsername' \
--docker-password='superSecretRegistryPassword' \
--dry-run=client -o yaml | oc apply -f -
```
Configuration is completed; now you can continue to the installation using the external container image registry.
:::tip
If the Appcircle server is already installed, you can test the container image registry connection using the command below.
```bash
helm upgrade appcircle-server appcircle/appcircle \
-n appcircle \
-f values.yaml
```
It will try to pull all the required images from the external registry and result in an images already exist message, since the application version is not changed.
:::
## Mirroring Images
If a proxy registry with pull-through cache ability is not available in your setup, you can mirror images manually with your preferred method using the following image list.
### Retrieving the Image List
A list of all container images is given below; image versions may vary depending on the Helm chart version.
Click to view the image list.
:::tip
The below container image list is based on the **`latest`** Helm chart version. See others in the [version history](https://docs.appcircle.io/self-hosted-appcircle/install-server/helm-chart/upgrades#version-history) page.
:::
```txt
europe-west1-docker.pkg.dev/appcircle/docker-registry/agentcacheservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/appcircle-keycloak:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/appcircle-vault:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/appparserserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/buildserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/dashboardserver:1.8.92-beta1196
europe-west1-docker.pkg.dev/appcircle/docker-registry/distributionserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/disttesterweb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/kafkab:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/keycloakversioning:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/licenseserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/minio/miniob:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/mongodb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/notificationserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/otpservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/postgresqlb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/privateapigateway:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/publishserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/redisb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/reportserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/resignservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/resourceserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/schedulemanagerservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/signingidentityserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeadminservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeapiservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeprofileservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storereportservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storesubmitserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeweb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/taskserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/testeradminservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/testerapiservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/toolbox:1.5.1
europe-west1-docker.pkg.dev/appcircle/docker-registry/uiserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/webhookservice:v3.27.3
```
```txt
europe-west1-docker.pkg.dev/appcircle/docker-registry/agentcacheservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/appcircle-keycloak:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/appcircle-vault:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/appparserserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/buildserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/cert-utils-operator:v1.3.12
europe-west1-docker.pkg.dev/appcircle/docker-registry/dashboardserver:1.8.92-beta1196
europe-west1-docker.pkg.dev/appcircle/docker-registry/distributionserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/disttesterweb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/kafkab:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/keycloakversioning:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/kube-rbac-proxy:v0.11.0
europe-west1-docker.pkg.dev/appcircle/docker-registry/licenseserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/minio/miniob:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/mongodb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/notificationserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/otpservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/postgresqlb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/privateapigateway:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/publishserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/redisb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/reportserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/resignservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/resourceserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/schedulemanagerservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/signingidentityserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeadminservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeapiservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeprofileservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storereportservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storesubmitserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/storeweb:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/taskserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/testeradminservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/testerapiservice:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/toolbox:1.5.1
europe-west1-docker.pkg.dev/appcircle/docker-registry/uiserver:v3.27.3
europe-west1-docker.pkg.dev/appcircle/docker-registry/webhookservice:v3.27.3
```
:::tip
You can also use the following command to get up-to-date image list required during `helm install`:
```bash
helm template appcircle appcircle/appcircle -f values.yaml | grep image: | sed 's/\s*image:\s*//; s/"//g' | sort -u
```
:::
## Insecure Registry
By default, Kubernetes and OpenShift require HTTPS connections to image registries. To use a registry over HTTP, you must configure it as an insecure registry.
### Kubernetes
Setting up a private container registry for Kubernetes clusters requires different approaches depending on the container runtime and Kubernetes distribution. While Docker was previously the default runtime, Kubernetes has transitioned to `containerd` and other CRI-compliant runtimes, which require different configurations.
#### Challenges with Kubernetes Distributions
Different Kubernetes distributions use various container runtimes, each requiring unique configurations:
- **General Kubernetes with Docker runtimes**: Might require configuring the Docker daemon, but some managed distributions restrict access to this file.
- **General Kubernetes nodes with `containerd` runtimes**: Might require modifying `/etc/containerd/config.toml`, but some managed distributions restrict access to this file.
- **Managed Kubernetes (GKE, EKS, AKS, Rancher, K3s, etc.)**: Configuration methods depend on the specific provider or service. For instance, managed Kubernetes services may restrict node-level configurations and instead use IAM-based authentication with cloud artifact registries. For self-managed services like Rancher or K3s, the configuration will vary, so it's important to consult the official documentation for each.
Because of these variations, it's important to consult the specific Kubernetes distribution’s documentation when configuring **insecure** private registries.
:::tip
##### Use HTTPS-based registries
Instead of configuring insecure HTTP registries, we strongly recommend using **HTTPS-based** artifact registries.
Using an HTTPS registry eliminates the need for complex `containerd`, `docker` or K8s related configurations and improves security.
:::
#### Sample K3s Configuration
For K3s clusters, the registry must be configured on each node using the `registries.yaml` file. The more detailed steps are located in the [official documentation](https://docs.k3s.io/installation/private-registry#without-tls).
1. Create the `registries.yaml` file on all nodes:
```sh
sudo vi /etc/rancher/k3s/registries.yaml
```
2. Add the private registry configuration:
```yaml
mirrors:
registry.spacetech.com:8083:
endpoint:
- "http://registry.spacetech.com:8083"
configs:
"registry.spacetech.com:8083":
auth:
username: "yourRegistryUsername"
password: "superSecretRegistryPassword"
```
3. Restart K3s to apply changes per its type:
- For control-plane nodes;
```sh
sudo systemctl restart k3s
```
- For worker nodes;
```sh
sudo systemctl restart k3s-agent
```
After configuring the registry on all nodes, Kubernetes will be able to pull images without requiring a separate Kubernetes secret.
For instructions on changing the image repository in your Helm `values.yaml`, refer to the [Appcircle configuration](#appcircle-configuration) section. Keep in mind that you can skip creating a secret with credentials step since it's already been done above for each node.
### OpenShift
Edit the cluster's image configuration:
```bash
oc edit image.config cluster
```
Add your registry address to the `insecureRegistries` section:
```yaml
...
spec:
...
registrySources:
insecureRegistries:
- registry.spacetech.com:8083
```
Save the file and exit.
:::caution
If your registry uses a non-standard port (anything other than 80 for HTTP), you must specify it in the configuration as shown in the example above with port `8083`.
:::
The Machine Config operator will apply the changes and reboot the nodes. Wait until the nodes are up and running.
:::info
- You can check the status of the nodes with the following command:
```bash
oc get nodes
```
Nodes should be in the `Ready` state.
- You can check the status of the configuration update with the command below:
```bash
oc get mcp
```
When the update is done successfully, the state fields look like this:
```bash
... UPDATED UPDATING DEGRADED ...
... True False False ...
```
:::
---
## Git Providers Configuration
## Overview
With default installation, self-hosted Appcircle comes with the connection options below:
- Bitbucket
- Azure
- GitLab
- Connect via SSH
- Connect via URL
But you're not limited with these options. You can configure the git providers and use them within your self-hosted Appcircle server.
### Enable/Disable Git Providers
If you want to enable or disable any of these providers, you can do so by updating your `values.yaml` file.
In the example below, there are enabled git providers list with comma separated:
```yaml
web:
web-app:
selfHostedGitProviders:
- "bitbucketServer"
- "azureDevopsServer"
- "gitlabSelfHosted"
- "ssh"
- "publicRepository"
```
You can delete the providers you do not need by removing them from `selfHostedGitProviders` list above.
For more details about "Bitbucket" usage, see related docs in the [Connecting to Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket) page.
For more details about "Azure" usage, see related docs in the [Connecting to Azure DevOps](/build/manage-the-connections/connection-guides/connecting-to-azure) page.
For more details about "GitLab" usage, see related docs in the [Connecting to GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab) page.
For more details about "Connect via SSH" usage, see related docs in the [Connect via SSH](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) page.
For more details about "Connect via URL" usage, see related docs in the [Connect via URL](/build/manage-the-connections/connection-guides/connecting-to-public-repository) page.
---
## Configuration
Helm charts support extensive customization through values files (values.yaml) or direct CLI overrides. Users can modify environment-specific settings, resource limits, and integrations without altering the chart structure.
Current headlines are listed below:
- [Production Readiness](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness)
- [Storage Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/storage-configuration)
- [Sensitive Values](/self-hosted-appcircle/install-server/helm-chart/configuration/sensitive-configuration)
- [Adding CA Certificates](/self-hosted-appcircle/install-server/helm-chart/configuration/ca-certificates)
- [License Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/license-configuration)
- [Ingress Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/ingress-configuration)
- [Enterprise App Store Customization](/self-hosted-appcircle/install-server/helm-chart/configuration/enterprise-store-configuration)
- [Git Providers Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/git-providers-configuration)
- [LDAP Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/ldap-configuration)
- [SSL Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/ssl-configuration)
- [Domain Verification](/self-hosted-appcircle/install-server/helm-chart/configuration/domain-verification)
- [External Image Registries](/self-hosted-appcircle/install-server/helm-chart/configuration/external-image-registry)
- [Advanced Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/advanced-configuration)
In order to see the details, check the submenu of this documentation page.
---
## Ingress Configuration
## Overview
The Appcircle Helm chart includes an Ingress controller, specifically ingress-nginx, which is enabled by default. For production environments, it is recommended to use your own Ingress controller for better control and customization.
## Appcircle Default Ingress-NGINX Configuration
The default `ingress-nginx` configuration in the `values.yaml` file includes several parameters that apply globally to the Ingress controller. These configurations can be adjusted as needed to fit your deployment requirements. If you are using your own Ingress controller, you can configure these values globally or on a per-Ingress basis for Appcircle ingresses.
Default Configurations in `values.yaml` of the Appcircle server Helm chart:
```yaml
ingress-nginx:
controller:
config:
proxy-body-size: '4096m'
client-body-buffer-size: '128k'
proxy-connect-timeout: '600'
proxy-send-timeout: '600'
proxy-read-timeout: '600'
proxy-buffer-size: '128k'
proxy-buffers-number: '4'
proxy-busy-buffers-size: '128k'
```
You can change the default values of the Ingress controller that is installed with the Appcircle Helm chart as your needs dictate.
## Configuring Ingress Annotations
Adding per-Ingress annotations is recommended for external Ingress controllers. By setting annotations per Ingress, you can fine-tune the behavior of specific Appcircle services without impacting the entire Ingress controller.
Example Ingress configurations for `values.yaml` of the Appcircle server Helm chart:
```yaml
# For APK, IPA, build artifact uploads from browsers and Appcircle runners
apigateway:
ingress:
annotations:
# For Ingres-Nginx Controller
nginx.ingress.kubernetes.io/proxy-body-size: "4096m"
nginx.ingress.kubernetes.io/client-body-buffer-size: "128k"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "128k"
# For build cache uploads from Appcircle runners
resource:
ingress:
annotations:
# For Ingres-Nginx Controller
nginx.ingress.kubernetes.io/proxy-body-size: "4096m"
nginx.ingress.kubernetes.io/client-body-buffer-size: "128k"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "128k"
```
:::tip
If you are using an ingress controller other than `ingress-nginx`, please refer to the documentation for your specific ingress controller to find the relevant configurations. Each ingress controller may have different annotations and settings to achieve similar functionality.
:::
---
## LDAP Configuration
## Overview
You can see some options for the LDAP configurations in this documentation.
## LDAP Brute Force Protection
Enabling LDAP authentication introduces the risk of brute-force attacks that can originate from external or internal sources.
A sustained LDAP brute-force attack can result in user accounts being locked out of the LDAP directory, preventing access to other applications integrated with the directory.
To mitigate this risk, a self-hosted Appcircle server can be configured to block repeated failed login attempts for a duration before allowing additional attempts.
The Appcircle server's brute-force algorithm is based on successive failed attempts, not failed attempts over a period of time.
### Default Configuration
Appcircle server comes with brute-force protection **turned off** by default.
It is completely up to you to set this up. See the following sections for details.
### Brute-Force Arguments
The appropriate blocking threshold and duration are dependent on the account lockout policies enforced on the LDAP server itself.
For example, if the LDAP server locks accounts for 1 hour after 10 failed attempts, Appcircle can be configured to block login attempts for 2 hours after 5 failures to provide an early warning system.
So the users won't be blocked by the LDAP server and can continue to use other applications.
Follow the recommendations below when tuning the brute-force protection mechanisms:
- Review the number of failed login attempts that trigger account lockout and the lockout duration configured on your LDAP server.
- Configure the Appcircle server's maximum retry attempts equal to or lower than your LDAP server's threshold. For example, if LDAP locks accounts after 10 failed logins, set the Appcircle server to block after 5-8 attempts.
- Configure Appcircle's lockout duration to be equal to or greater than LDAP. For instance, if LDAP locks accounts for 1 hour, Appcircle should be 1 hour or more.
- Test updated configurations in a non-production environment first. Validate that the Appcircle server lockouts are triggered before LDAP lockouts when deliberately failing logins.
- Monitor logs for incidents blocked by the Appcircle server to optimize configurations based on real activity targeting your environment.
Following these best practices will allow the Appcircle server to effectively function as an early warning system for brute-force attacks against LDAP infrastructure. Besides, you will prevent a general LDAP lockout, which can block your LDAP users from using other systems on the intranet.
:::caution
LDAP brute-force settings can be configured for only **Testing Distribution** and **Enterprise App Store** modules.
[Appcircle login with LDAP](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings#appcircle-login-with-ldap) is not supported and is out-of-scope for the brute-force settings.
:::
To configure LDAP brute force protection, you can edit the `values.yaml` file and add the following settings under `auth`:
```yaml
auth:
auth-keycloak:
bruteForce:
distribution:
maxFailureCount: "5"
maxLockDuration: "600"
store:
maxFailureCount: "5"
maxLockDuration: "600"
```
## User Lookup Decision Settings
The LDAP (Lightweight Directory Access Protocol) user lookup decision strategy is a crucial aspect of user authentication in applications that utilize LDAP for user management.
When Appcircle receives a user login request from the Enterprise App Store or Testing Distribution, it needs to determine which LDAP configuration to use for the user lookup and authentication process.
In scenarios where a user exists in multiple LDAP configurations, a decision must be made on which configuration to use for authentication.
This documentation provides insights into the LDAP user lookup decision strategy and how it can be configured to handle scenarios where a user has multiple usernames and passwords across different LDAP configurations.
### Editing User Lookup Decision Strategy
To configure LDAP lookup decision settings, you can edit the `values.yaml` like in the example below:
```yaml
auth:
auth-keycloak:
userLookupDecisionStrategy: decisive
```
If you don't define it or it has an unknown value, it is assumed to be `decisive` by default.
#### Affirmative
When `userLookupDecisionStrategy` is set to "affirmative", the LDAP authentication process will check all LDAP settings, even if the user is found on a particular LDAP configuration. This means that if a user has multiple accounts on different LDAP configurations with different passwords, they will be able to login successfully. The authentication system will search across all LDAP configurations to find a matching username or email and validate the user's password, allowing the user to access the system.
#### Decisive
On the other hand, when `userLookupDecisionStrategy` is set to "decisive", the LDAP authentication process will check a specific LDAP configuration for the user's username or email. If the authentication system finds the username on a particular LDAP, it will verify the user's password only on that specific LDAP configuration. If the provided password is incorrect, the authentication system will not check other LDAP configurations and will immediately return invalid credentials, denying access to the user.
#### Tolerant
When `userLookupDecisionStrategy` is set to "tolerant", similar to the "affirmative" strategy, it retrieves the list of LDAP providers where the user is found and checks the password sequentially. If the password is correct, the process ends. If it is incorrect, the search continues until the last LDAP provider. Unlike "affirmative", if an LDAP provider is unreachable or an error occurs, the process continues, and the faulty provider is ignored.
:::
## Appcircle Login with LDAP
Appcircle login with LDAP aims to provide an alternative authentication solution via the LDAP server. Appcircle's LDAP integration allows businesses to integrate existing directory services, especially Active Directory, directly into the Appcircle login process. This integration simplifies user management.
The LDAP distinguished name (DN) is associated with existing Appcircle registered users when:
- The existing user signs in to Appcircle with LDAP for the first time.
- The LDAP email address is the email address of an existing Appcircle user.
If the LDAP email attribute isn’t found in the Appcircle user database, a new user is created.
If existing Appcircle users want to enable LDAP to sign in for themselves, they should:
- Check that their Appcircle user email address matches their LDAP user email address.
- Sign in to Appcircle by using their LDAP credentials.
:::caution
This feature only provides a solution for self-hosted Appcircle server installations. Appcircle Login with LDAP is not possible for Appcircle Cloud users.
:::
### Attribute Configuration Settings
LDAP users must have an email address, regardless of whether or not it’s used to sign in.
Appcircle uses these LDAP attributes to create an account for the LDAP user.
- The username LDAP attribute is a string. For example,'mail'.
| Settings | Description | Required | Examples |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------- |
| Username LDAP Attribute | Name of LDAP attribute, which is mapped as username. For many LDAP server vendors it can be 'uid'. For an active directory, it can be 'sAMAccountName' or 'cn'. | Yes | mail,email |
### Adding LDAP Configuration
- To get started, click on the "Admin" button from the left menu.
- Go to the "Self-Hosted Settings" screen.
- And press the "Connect" button next to "LDAP Login".
- Click on the "Create" button to create your LDAP configuration.
- Enter the details of your LDAP configuration.
:::caution
After you fill out the LDAP configuration form, it's strongly recommended that you test the configuration using the test buttons below.
- Test Connection
- Test Authentication
:::
:::info
Appcircle supports multiple LDAP configurations. If you are using multiple LDAP configurations and a user exists in both LDAPs, user authentication will look at the LDAP order.
The "Order" field when adding a LDAP configuration is required to do this ordering.
LDAP configuration with an order value of `1` will be used before LDAP configuration with an order value of `2` in user authentication.
:::
### Remove User From LDAP Server
If the user is deleted via LDAP, users coming from LDAP or previously connected users cannot log in to the system. And users who are logged in are automatically logged out.
### Remove LDAP Configuration
You can quickly remove your saved LDAP configuration from Appcircle Login.
- To delete a LDAP configuration, press the "Manage" button next to the "LDAP Login" option on the "Self-Hosted Settings" page.
- Select the LDAP configuration you want to delete and click on the "Remove" button.
After confirmation, the LDAP configuration will be deleted from Appcircle.
:::info
If a user is logged in to Appcircle with an LDAP configuration and that LDAP configuration is removed, the user will not be able to register in Appcircle.
This user is also removed from the organization in Appcircle.
:::
## LDAP Mapping
LDAP Mapping in Appcircle allows you to synchronize user groups and roles from your LDAP directory to your Appcircle environment seamlessly. This guide provides a step-by-step approach to setting up and managing LDAP mappings, ensuring your user and role integrations are as efficient as possible.
### Group And Role Mapper Configuration
Group and role mapper configuration must be completed before starting the LDAP mapping configuration. The LDAP group and role mapper define how groups and roles are retrieved from LDAP.
You can configure it using the following steps:
1. To get started, click on the **Admin** button from the left menu.
2. Go to the **Self-Hosted Settings** screen.
3. And press the **Manage** button next to **LDAP Login**.
4. Click the **Set Up LDAP Configuration**, then click **Edit** button in your LDAP provider.
5. In the **LDAP Connection screen**, scroll down to find the **Group Mapper** and **Role Mapper** sections.
6. Click the **Add** button next to the Group Mapper to create a proper group mapper configuration for retrieving groups and members from LDAP.
7. Click the **Add** button next to the Role Mapper to create proper role mapper configuration for retrieving roles and members from LDAP.
### Accessing LDAP Settings
To configure LDAP Mapping, follow these steps:
1. Navigate to the **Admin** section on your dashboard.
2. Select **Self-Hosted Settings** and click on **LDAP Login** to access the LDAP configuration options.
### Configuring LDAP Mapping
#### Setting Up LDAP Configuration
- **Select LDAP Configuration**: Begin by selecting your LDAP configuration from the dropdown menu. This is where you define and select the LDAP source to be used for mapping.
- **LDAP Groups and Appcircle Organizations**: Choose an LDAP group and the corresponding Appcircle organization you want to synchronize.
#### Associating LDAP Groups with Appcircle Organizations
- **Mapping LDAP Groups**: After selecting the LDAP group, map it to an Appcircle organization by clicking **Add**. This establishes a link where users from the LDAP group are automatically mapped to the corresponding organization in Appcircle.
:::caution
- Appcircle Organizations must be created manually before using them with LDAP Mapping.
:::
### Managing LDAP Groups and Mappings
- **View Configurations**: All active LDAP mappings can be viewed under the LDAP Mapping section. You can modify or delete each mapping as needed by using the **Config** option.
### LDAP Role Mapping
LDAP Role Mapping allows you to assign specific roles to users based on their LDAP group memberships. This feature streamlines user management by automatically assigning roles to users based on their LDAP role associations.
#### Configuring Role Mappings
- Navigate to the **LDAP Role Mapping** section where you can assign specific Appcircle roles based on the LDAP roles assigned to users.
- **Add a New Role**: Select a role from the available LDAP roles and assign it to users within the specified Appcircle organization. Roles such as administrator, developer, or custom group roles can be mapped accordingly.
#### Role and Permissions Management
- Each role can have varied permissions across different modules such as Build, Deploy, and Admin settings. Configure these permissions to ensure users have appropriate access levels based on their role.
### LDAP Synchronization
You can synchronize users from LDAP groups to Appcircle organizations using LDAP Synchronization. This process involves adding new users and removing unnecessary ones.
:::info
If you configure an Appcircle organization for synchronization, the synchronization task will override any manual configurations.
Please note that the synchronization is one-way from LDAP to Appcircle, meaning changes made in Appcircle do not affect LDAP.
:::
:::caution
- The sync operation does not fetch all users. If a user has not logged in before, they will join the organization with the assigned roles as soon as they log in, provided LDAP Mapping is enabled.
- If a user does not exist in Appcircle (has not been imported yet), they will be ignored by the synchronization task.
- The synchronization operation also does not affect the admin user. Even if the admin user is not in the LDAP group, they remain a member of the Appcircle organization.
- Appcircle Root Organizations must have at least one owner. The synchronization operation will not remove a user if they are the last owner of the root organization.
- You need to run the synchronization task once for users who are already in Appcircle and linked to LDAP.
:::
#### Enabling and Managing Synchronization
- **Activate Synchronization**: Toggle the LDAP Synchronization option to enable automatic syncing between LDAP and Appcircle.
- **Manual Sync and Interval Settings**: Use the **Sync Now** button to manually trigger a sync or set a synchronization interval to automate the process at regular intervals.
### Conclusion
Setting up LDAP Mapping streamlines user management by automating the synchronization of user roles and groups from LDAP into Appcircle. This guide should assist you in effectively managing user access and roles within your organization, ensuring security and efficiency in your app development processes.
## Troubleshooting
:::info
If the LDAP configuration is incorrect or the LDAP server cannot be accessed for some reason, you can always login with the "initial username" and "initial password" that were configured while installing the server.
See the [configure](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in the installation page for the `global.yaml` details.
:::
---
## License Configuration
## Overview
The Appcircle server comes with a default license to let you explore Appcircle if you have installed it with Helm to a Kubernetes cluster.
If you have purchased a license from Appcircle, you can follow this documentation to apply your license.
### Retrieving the Initial Organization ID
The initial organization ID is printed alongside the Helm output during installation. If you miss the initial output or need to retrieve the organization ID later, use the following command:
```bash
kubectl get secret appcircle-server-auth-keycloak \
-n appcircle \
-o jsonpath="{.data.initialOrganizationId}" | base64 --decode && echo
```
```bash
oc get secret appcircle-server-auth-keycloak \
-n appcircle \
-o jsonpath="{.data.initialOrganizationId}" | base64 --decode && echo
```
### Creating a Secret for License Authentication
Create a secret that contains the `cred.json` file you received from Appcircle to authenticate the Appcircle license.
1. Save the `cred.json` file.
2. Create/update the secret named **`${releaseName}-auth-license`** with the **`credentialJson`** key:
```bash
kubectl create secret generic appcircle-server-auth-license \
-n appcircle \
--from-literal=credentialJson="$(cat cred.json | base64 -w0)" \
--save-config --dry-run=client -o yaml | kubectl apply -f -
```
```bash
oc create secret generic appcircle-server-auth-license \
-n appcircle \
--from-literal=credentialJson="$(cat cred.json | base64 -w0)" \
--save-config --dry-run=client -o yaml | oc apply -f -
```
:::tip
Creating a secret for the license should be done once. Other license updates do not require repeating this step.
:::
### Updating the License
If your organization’s Appcircle server license has been updated and you need to apply the new license, you can upgrade the Appcircle server deployment using Helm:
```bash
helm upgrade appcircle-server appcircle/appcircle \
-n appcircle \
-f values.yaml
```
---
## AWS S3 Configuration
## Overview
This guide provides comprehensive instructions for configuring AWS S3 as your object storage backend for the Appcircle server. While the default Helm chart deployment includes MinIO as an in-cluster object storage solution, **production environments** benefit from using a more robust and scalable solution like AWS S3.
### What This Guide Covers
This guide will walk you through the process of configuring AWS S3 as your object storage backend for the Appcircle server. To use AWS S3 with Appcircle server, you need to:
- **Set up AWS infrastructure**: S3 buckets, IAM users, and permissions
- **Configure Appcircle server**: Update Helm values to use S3
- **Optional CDN setup**: CloudFront for performance optimization
## Prerequisites
To complete this guide, you must have the following:
### 1. AWS Account and Permissions
An **AWS account** with appropriate permissions to create and manage S3 buckets, IAM users, and policies.
Click to view more details about AWS permissions.
You need the following AWS permissions to complete this configuration:
- **S3 permissions**: Create buckets, configure CORS, manage bucket policies
- **IAM permissions**: Create users, policies, and access keys
- **STS permissions**: Get caller identity (for policy attachment)
- **CloudFront permissions**: Create distributions, manage origins, and configure caching
If you're working in a restricted environment, ensure you have the necessary permissions before proceeding.
### 2. AWS CLI
The **AWS CLI version `2.x`** is **required** and must be **[installed](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)** and **[configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)** on your machine.
Click to view more details about AWS CLI configuration.
To configure AWS CLI, you need:
- **Access Key ID** and **Secret Access Key** for your AWS account
- **Default region** for your AWS resources
- **Output format** (JSON is recommended)
You can configure AWS CLI using:
```bash
aws configure
```
Or by setting environment variables:
```bash
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_OUTPUT=json
```
:::warning
Please make sure that the output format is set to `json` to avoid any issues with the `jq` command in the next steps.
:::
### 3. Kubernetes/OpenShift Access
**`kubectl`** (for Kubernetes) or **`oc`** (for OpenShift) CLI is **required** and must be configured to access your cluster.
:::info
This guide assumes you have administrative access to your AWS account and Kubernetes/OpenShift cluster. If you're working in a restricted environment, ensure you have the necessary permissions before proceeding.
:::
### 4. Basic Understanding
Basic understanding of **AWS IAM**, **S3**, and **Kubernetes/OpenShift** concepts is recommended.
### 5. Virtual-hosted Style S3 Endpoint
The Appcircle server does not support the path-style S3 endpoint model. Your S3 endpoints should be virtual-hosted style, which can be accessible using relevant DNS subdomains.
:::info
Refer [here](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/) or to the [AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) documentation to see the differences between S3 endpoint styles and configure your S3 endpoints if necessary.
:::
### 6. Optional: Domain and SSL Certificates
For CloudFront CDN setup (optional), you'll need:
- **Domain name**: For custom CDN domains
- **SSL certificates**: For HTTPS access to your CDN
## Configuration Steps
### 1. Set Up Environment Variables
**Set up your environment variables** before proceeding with the configuration. These variables will be used throughout the configuration process.
:::note
In this documentation, we will use `spacetech` as an **example organization name** and `us-east-1` as an **example AWS region**. You should **replace these values** with your actual organization name and preferred AWS region.
:::
```bash
# Set your organization name and region
ORG_NAME="spacetech" # Replace with your organization name
BUCKET_PREFIX="appcircle-${ORG_NAME}-"
REGION="us-east-1" # Replace with your preferred AWS region
IAM_USER="appcircle-server"
```
### 2. Create AWS S3 Buckets
**Create the required S3 buckets** to store the artifacts generated by the Appcircle server.
Appcircle server requires the following S3 buckets for different purposes:
- **`${BUCKET_PREFIX}temp`**: Temporary files and uploads (requires CORS configuration for direct uploads/downloads from the client browsers)
- **`${BUCKET_PREFIX}build`**: Build artifacts and logs
- **`${BUCKET_PREFIX}distribution`**: Testing Distribution files
- **`${BUCKET_PREFIX}storesubmit`**: Appcircle Store Submit files
- **`${BUCKET_PREFIX}store`**: Enterprise App Store files
- **`${BUCKET_PREFIX}agent-cache`**: Appcircle Runner cache files
- **`${BUCKET_PREFIX}backup`**: Backup files
- **`${BUCKET_PREFIX}publish`**: Published mobile app binaries
:::tip
**Bucket Naming**: Bucket names must be globally unique across all AWS accounts. Using your organization name as a prefix ensures uniqueness.
:::
**Create all required buckets:**
```bash
# Create buckets one by one
aws s3 mb s3://${BUCKET_PREFIX}temp --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}build --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}distribution --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}storesubmit --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}store --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}agent-cache --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}backup --region ${REGION}
aws s3 mb s3://${BUCKET_PREFIX}publish --region ${REGION}
```
:::info
The bucket names use your organization name to ensure global uniqueness, as AWS S3 bucket names must be unique across all AWS accounts worldwide.
:::
### 3. Configure CORS Settings
**Configure CORS settings** for the `temp` bucket to allow cross-origin requests from your Appcircle server dashboard.
:::caution
Replace the `https://my.appcircle.spacetech.com` with the dashboard URL that you will use to access the Appcircle server. For example, if you are using `.appcircle.spacetech.com` as the domain in the Helm `values.yaml` file, the dashboard URL will be `https://my.appcircle.spacetech.com`.
:::
**Configure CORS for the `temp` bucket:**
```bash
aws s3api put-bucket-cors \
--bucket ${BUCKET_PREFIX}temp \
--region ${REGION} \
--cors-configuration '{
"CORSRules": [
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedOrigins": ["https://my.appcircle.spacetech.com"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3600
}
]
}'
```
:::tip
- The CORS configuration is only required for the `temp` bucket.
- Other buckets don't require CORS configuration, as they are accessed server-side.
- If you're using the Appcircle server dashboard with HTTP instead of HTTPS, replace `https://` with `http://` in the **`AllowedOrigins`**.
:::
### 4. Create IAM User and Policy
**Create an IAM user with minimal permissions** to make the Appcircle server able to access the S3 buckets.
```bash
aws iam create-user --user-name ${IAM_USER}
```
**Create an IAM policy** that grants the necessary S3 permissions:
```bash
cat << EOF > appcircle-s3-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::${BUCKET_PREFIX}temp",
"arn:aws:s3:::${BUCKET_PREFIX}temp/*",
"arn:aws:s3:::${BUCKET_PREFIX}build",
"arn:aws:s3:::${BUCKET_PREFIX}build/*",
"arn:aws:s3:::${BUCKET_PREFIX}distribution",
"arn:aws:s3:::${BUCKET_PREFIX}distribution/*",
"arn:aws:s3:::${BUCKET_PREFIX}storesubmit",
"arn:aws:s3:::${BUCKET_PREFIX}storesubmit/*",
"arn:aws:s3:::${BUCKET_PREFIX}store",
"arn:aws:s3:::${BUCKET_PREFIX}store/*",
"arn:aws:s3:::${BUCKET_PREFIX}agent-cache",
"arn:aws:s3:::${BUCKET_PREFIX}agent-cache/*",
"arn:aws:s3:::${BUCKET_PREFIX}backup",
"arn:aws:s3:::${BUCKET_PREFIX}backup/*",
"arn:aws:s3:::${BUCKET_PREFIX}publish",
"arn:aws:s3:::${BUCKET_PREFIX}publish/*"
]
}
]
}
EOF
```
**Create the IAM policy:**
```bash
aws iam create-policy \
--policy-name ${IAM_USER}-s3-policy \
--policy-document file://appcircle-s3-policy.json
```
**Get your AWS account ID:**
```bash
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
```
**Attach the policy to the IAM user:**
```bash
aws iam attach-user-policy \
--user-name ${IAM_USER} \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/${IAM_USER}-s3-policy
```
### 5. Create Access Keys for the IAM User
Create access keys for the IAM user to be used by Appcircle server:
```bash
ACCESS_KEY_OUTPUT=$(aws iam create-access-key --user-name ${IAM_USER})
ACCESS_KEY_ID=$(echo "$ACCESS_KEY_OUTPUT" | jq -r '.AccessKey.AccessKeyId')
SECRET_ACCESS_KEY=$(echo "$ACCESS_KEY_OUTPUT" | jq -r '.AccessKey.SecretAccessKey')
```
:::warning
**CRITICAL: Save the access key and secret access key securely**. You'll need these credentials in the next step to create the Kubernetes secret.
:::
### 6. Validate Basic S3 Configuration
Before proceeding to CloudFront setup (optional) or Kubernetes secret creation, verify your basic S3 configuration:
```bash
# 1. Verify all buckets were created successfully
echo "Checking S3 buckets..."
aws s3 ls | grep ${BUCKET_PREFIX}
# 2. Verify CORS configuration on temp bucket
echo "Checking CORS configuration..."
aws s3api get-bucket-cors --bucket ${BUCKET_PREFIX}temp
# 3. Verify IAM user exists
echo "Checking IAM user..."
aws iam get-user --user-name ${IAM_USER}
# 4. Verify IAM policy is attached
echo "Checking IAM policy attachment..."
aws iam list-attached-user-policies --user-name ${IAM_USER}
```
**Expected Output:**
- All 8 buckets should be listed
- CORS configuration should show your Appcircle server URL
- IAM user should exist and have the policy attached
### 7. Optional: Create CloudFront CDN for AWS S3 Buckets
CloudFront is AWS's Content Delivery Network (CDN) service that improves performance by caching your S3 content at edge locations worldwide. This reduces latency and improves download speeds for your users.
:::tip
- **Follow this guide** if you need production-grade performance to serve your users globally.
- **Skip this section** if you're setting up for development/testing or have a small or medium team.
- You can always enable CloudFront later without reinstalling the Appcircle server.
- **Skip to** the [Create Kubernetes Secret](#create-kubernetesopenshift-secret-for-access-keys) step if you do not need CDN configuration.
:::
This guide will walk you through the process of creating a CloudFront distribution for your S3 buckets with the `aws` CLI.
:::info
**Flexibility Note**: You can achieve the same results with other tools (AWS Console, Terraform, CloudFormation, etc.) as long as you create the same infrastructure components described in this documentation. You can also add additional configurations (security policies, monitoring, etc.) as long as you don't break the core requirements:
- CloudFront must be configured to serve the S3 buckets
- S3 bucket policies must be updated to allow CloudFront access
- CloudFront public-private key pair must be created and configured
- SSL certificate should be managed or imported for the CloudFront distribution
- DNS must be configured to point to the CloudFront distribution
- Kubernetes secret must contain the correct credentials for the CloudFront public-private key pair
- Helm values must include the specified CDN configuration for the Appcircle server
:::
#### Step 7.1: Generate Public and Private Keys for URL Signing
CloudFront uses signed URLs to secure access to your content. You need to generate a key pair for this.
```bash
# Generate a private key
openssl genrsa -out private_key.pem 2048
# Generate the public key
openssl rsa -in private_key.pem -pubout -out public_key.pem
# Convert the public key to single-line format (required by AWS)
SINGLE_LINE_PUBLIC_KEY=$(awk '{printf "%s\\n", $0}' public_key.pem)
```
:::caution
**Security Note**: Keep your `private_key.pem` file secure. Anyone with this key can create valid signed URLs for your content.
:::
#### Step 7.2: Create CloudFront Public Key
Create a public key in CloudFront that will be used to verify signed URLs.
```bash
# Create the public key configuration
cat << EOF > public-key-config.json
{
"CallerReference": "appcircle-cdn-sign-key",
"Name": "appcircle-cdn-sign-key",
"EncodedKey": "${SINGLE_LINE_PUBLIC_KEY}",
"Comment": "appcircle cdn sign key"
}
EOF
# Create the public key in CloudFront
PUBLIC_KEY_ID=$(aws cloudfront create-public-key --public-key-config file://public-key-config.json --query 'PublicKey.Id' --output text)
```
#### Step 7.3: Create CloudFront Key Group
A key group allows you to manage multiple public keys together.
```bash
# Create key group configuration
cat << EOF > key-group.json
{
"Name": "appcircle-cdn-key-group",
"Items": ["${PUBLIC_KEY_ID}"]
}
EOF
# Create the key group
KEY_GROUP_ID=$(aws cloudfront create-key-group --key-group-config file://key-group.json --query 'KeyGroup.Id' --output text)
```
**Save the Key Group ID** from the output.
#### Step 7.4: Store Private Key in Kubernetes
The private key needs to be available to your Appcircle server for creating signed URLs.
```bash
# Convert private key to single line
SINGLE_LINE_PRIVATE_KEY=$(cat private_key.pem | tr -d '\n')
# Create Kubernetes secret with the private key
kubectl create secret generic appcircle-cdn-url-sign-key -n appcircle \
--from-literal="cdn-url-sign-key-name=${PUBLIC_KEY_ID}" \
--from-literal="cdn-url-sign-key=${SINGLE_LINE_PRIVATE_KEY}"
```
#### Step 7.5: Import SSL Certificate
If you want to use custom domains (like `cdn.yourcompany.com`), you need an SSL certificate.
:::caution
CloudFront requires SSL certificates to be in the `us-east-1` region, regardless of where your S3 buckets are located.
Also make sure to change the `fullchain.pem` and `privkey.pem` to your actual certificate and private key file paths in the command below.
:::
```bash
# Import your SSL certificate to us-east-1 region
CERTIFICATE_ARN=$(
aws acm import-certificate \
--certificate fileb://cert1.pem \
--certificate-chain fileb://fullchain1.pem \
--private-key fileb://privkey1.pem \
--region us-east-1 \
--query 'CertificateArn' \
--output text
)
```
#### Step 7.6: Create Origin Access Control
Origin Access Control (OAC) secures the connection between CloudFront and your S3 buckets.
```bash
# Create OAC configuration
cat << EOF > appcircle-oac-config.json
{
"Name": "Appcircle-S3-OAC",
"Description": "OAC for Appcircle S3 buckets",
"SigningBehavior": "always",
"SigningProtocol": "sigv4",
"OriginAccessControlOriginType": "s3"
}
EOF
# Create the origin access control
OAC_ID=$(aws cloudfront create-origin-access-control \
--origin-access-control-config file://appcircle-oac-config.json \
--query 'OriginAccessControl.Id' --output text)
```
#### Step 7.7: Create CloudFront Distribution
This is the main CloudFront distribution that will serve your S3 content.
**Bucket List for CloudFront Setup:**
- `${BUCKET_PREFIX}distribution` - Testing Distribution files
- `${BUCKET_PREFIX}store` - Enterprise App Store files
- `${BUCKET_PREFIX}build` - Build artifacts and logs
- `${BUCKET_PREFIX}storesubmit` - Appcircle Store Submit files
- `${BUCKET_PREFIX}publish` - Published mobile app binaries
**For each bucket you want to serve via CloudFront, follow these steps:**
1. **Set the bucket variable:**
```bash
# Choose one of these buckets:
BUCKET=${BUCKET_PREFIX}distribution # For distribution files
# BUCKET=${BUCKET_PREFIX}store # For store files
# BUCKET=${BUCKET_PREFIX}build # For build artifacts
# BUCKET=${BUCKET_PREFIX}storesubmit # For store submit files
# BUCKET=${BUCKET_PREFIX}publish # For published binaries
```
2. **Create CloudFront distribution configuration for the selected bucket:**
:::caution
Replace `appcircle-cdn-domain.spacetech.com` with your actual CDN domain for each bucket.
For example:
- If you want to create a CDN for the `distribution` bucket, you can replace `appcircle-cdn-domain.spacetech.com` with `appcircle-distribution-cdn.spacetech.com`.
- If you want to create a CDN for the `store` bucket, you can replace `appcircle-cdn-domain.spacetech.com` with `appcircle-store-cdn.spacetech.com`.
:::
```bash
# Create CloudFront distribution configuration
cat << EOF > cloudfront-config-${BUCKET#${BUCKET_PREFIX}}.json
{
"CallerReference": "appcircle-${BUCKET#${BUCKET_PREFIX}}-bucket-cdn",
"Comment": "Appcircle ${BUCKET#${BUCKET_PREFIX}} Bucket CDN",
"Aliases": {
"Quantity": 1,
"Items": [
"appcircle-cdn-domain.spacetech.com"
]
},
"ViewerCertificate": {
"ACMCertificateArn": "${CERTIFICATE_ARN}",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"CertificateSource": "acm"
},
"Enabled": true,
"Origins": {
"Items": [
{
"Id": "S3Origin",
"DomainName": "${BUCKET}.s3.${REGION}.amazonaws.com",
"OriginAccessControlId": "${OAC_ID}",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
],
"Quantity": 1
},
"DefaultCacheBehavior": {
"TargetOriginId": "S3Origin",
"ViewerProtocolPolicy": "redirect-to-https",
"TrustedKeyGroups": {
"Enabled": true,
"Quantity": 1,
"Items": [
"${KEY_GROUP_ID}"
]
},
"AllowedMethods": {
"Quantity": 2,
"Items": [
"GET",
"HEAD"
],
"CachedMethods": {
"Quantity": 2,
"Items": [
"GET",
"HEAD"
]
}
},
"ForwardedValues": {
"QueryString": false,
"Cookies": {
"Forward": "none"
}
},
"MinTTL": 0,
"DefaultTTL": 86400,
"MaxTTL": 31536000
}
}
EOF
```
3. **Create the CloudFront distribution:**
```bash
# Create the CloudFront distribution
aws cloudfront create-distribution --distribution-config file://cloudfront-config-${BUCKET#${BUCKET_PREFIX}}.json
```
4. **Save the CloudFront Distribution ARN and Distribution Domain Names** from the output.
5. **Repeat for other buckets** by changing the `BUCKET` variable and running steps 2-4 again.
:::tip
**Save all Distribution ARNs**: You'll need each CloudFront Distribution ARN for the bucket policy updates in the next step.
:::
#### Step 7.8: Update S3 Bucket Policy
Allow CloudFront to access your S3 buckets securely.
**For each bucket that has a CloudFront distribution, update the bucket policy:**
1. **Set the bucket variable:**
```bash
# Choose the bucket you want to update:
BUCKET=${BUCKET_PREFIX}distribution # For distribution files
# BUCKET=${BUCKET_PREFIX}store # For store files
# BUCKET=${BUCKET_PREFIX}build # For build artifacts
# BUCKET=${BUCKET_PREFIX}storesubmit # For store submit files
# BUCKET=${BUCKET_PREFIX}publish # For published binaries
```
2. **Create bucket policy for CloudFront access:**
:::caution
Replace `` with the actual CloudFront distribution ARN for each specific bucket.
:::
```bash
# Create bucket policy for CloudFront access
cat << EOF > ${BUCKET#${BUCKET_PREFIX}}-bucket-policy.json
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::${BUCKET}/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": ""
}
}
}
]
}
EOF
```
3. **Apply the bucket policy:**
```bash
# Apply the bucket policy
aws s3api put-bucket-policy \
--bucket ${BUCKET} \
--policy file://${BUCKET#${BUCKET_PREFIX}}-bucket-policy.json
```
4. **Repeat for other buckets** by changing the `BUCKET` variable and running steps 2-3 again.
#### Step 7.9: Configure DNS
For each CloudFront distribution, create a CNAME record in your domain provider.
- **Create CNAME records in your domain provider for each CloudFront distribution you have created with different CDN domains**
- **Name**: `appcircle-cdn-domain.spacetech.com` (replace with your actual CDN domain for each bucket)
- **Type**: CNAME
- **Value**: `` (replace with your actual CloudFront Distribution Domain Name for each bucket)
## Create Kubernetes/OpenShift Secret for Access Keys
- Create the namespace that Appcircle server will be installed in if you haven't yet:
```bash
kubectl create namespace appcircle
```
- **Create a Kubernetes secret** named `-minio-connection` with your S3-compatible access and secret keys:
```bash
kubectl create secret generic appcircle-server-minio-connection \
-n appcircle \
--from-literal=accessKey= \
--from-literal=secretKey=
```
- Create the project that Appcircle server will be installed in if you haven't yet:
```bash
oc new-project appcircle
```
- **Create an OpenShift secret** named `-minio-connection` with your S3-compatible access and secret keys:
```bash
oc create secret generic appcircle-server-minio-connection \
-n appcircle \
--from-literal=accessKey= \
--from-literal=secretKey=
```
:::caution
- Replace `appcircle` with your actual namespace or project if different.
- Replace `` and `` with your actual access and secret keys.
- Replace `appcircle-server-minio-connection` with `-minio-connection`. Appcircle documentation uses `appcircle-server` as the release name.
:::
## Configure Helm Values
**Configure your `values.yaml` file** to use AWS S3 instead of MinIO.
Add the following configuration to your `values.yaml` file:
```yaml
global:
minio:
url: https://s3.us-east-1.amazonaws.com # Replace with your AWS S3 endpoint
region: "us-east-1" # Replace with your AWS region
useHttp: "false" # Set to "false" since we need to use HTTPS for the AWS S3 endpoint
bucketPrefix: "appcircle-spacetech-"
resource:
s3:
clientProvider: "AWS" # Set to "AWS" to use AWS S3
minio:
enabled: false # Disable internal MinIO deployment
```
:::caution
- Replace `https://s3.us-east-1.amazonaws.com` with your [AWS S3 endpoint](https://docs.aws.amazon.com/general/latest/gr/s3.html).
- Replace `us-east-1` with your AWS region.
- Replace `appcircle-spacetech-` with your actual bucket prefix. If you haven't terminated the terminal session, you can run `echo $BUCKET_PREFIX` to get the bucket prefix.
:::
```yaml
global:
minio:
url: https://s3.us-east-1.amazonaws.com # Replace with your AWS S3 endpoint
region: "us-east-1" # Replace with your AWS region
useHttp: "false" # Set to "false" since we need to use HTTPS for the AWS S3 endpoint
bucketPrefix: "appcircle-spacetech-"
resource:
s3:
clientProvider: "AWS" # Set to "AWS" to use AWS S3
cdnProvider: "AWS" # Set to "AWS" to use AWS CloudFront CDN
urlSignKeySecretName: "appcircle-cdn-url-sign-key" # Set to the secret name of the CDN URL signing key
cdnMapping: "Build=https://appcircle-build-cdn.spacetech.com,Distribution=https://appcircle-distribution-cdn.spacetech.com,Storesubmit=https://appcircle-storesubmit-cdn.spacetech.com,Store=https://appcircle-store-cdn.spacetech.com,Publish=https://appcircle-publish-cdn.spacetech.com" # Replace with your CDN mapping
urlSignPolicy: "{'Statement':[{'Resource':'%RESOURCE%','Condition':{'DateGreaterThan': {'AWS:EpochTime': %START_TIME%},'DateLessThan':{'AWS:EpochTime':%END_TIME%}}}]}" # You don't need to change this value if there are no specific requirements.
minio:
enabled: false # Disable internal MinIO deployment
```
:::caution
- Replace `https://s3.us-east-1.amazonaws.com` with your [AWS S3 endpoint](https://docs.aws.amazon.com/general/latest/gr/s3.html).
- Replace `us-east-1` with your AWS region.
- Replace `appcircle-spacetech-` with your actual bucket prefix. If you haven't terminated the terminal session, you can run `echo $BUCKET_PREFIX` to get the bucket prefix.
- Replace `appcircle-build-cdn.spacetech.com` with your actual `build` bucket CDN domain
- Replace `appcircle-distribution-cdn.spacetech.com` with your actual `distribution` bucket CDN domain
- Replace `appcircle-storesubmit-cdn.spacetech.com` with your actual `storesubmit` bucket CDN domain
- Replace `appcircle-store-cdn.spacetech.com` with your actual `store` bucket CDN domain
- Replace `appcircle-publish-cdn.spacetech.com` with your actual `publish` bucket CDN domain
:::
## Next Steps
After completing the AWS S3 configuration:
1. **Return to the main installation guide**:
- For Kubernetes: [Kubernetes Installation](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes)
- For OpenShift: [OpenShift Installation](/self-hosted-appcircle/install-server/helm-chart/installation/openshift)
2. **Continue with the installation process** using your configured `values.yaml` file
3. **Verify the configuration** by checking that Appcircle server can access the S3 buckets after installation
---
## Database and Vault Configurations
By default, the Appcircle Helm chart will deploy all the required services to the Kubernetes cluster for testing purposes. It is recommended that stateful applications, such as databases or object storage, be deployed outside the scope of the Helm chart. This allows you to have better control over their configuration and management.
If you wish to deploy these services within the Helm chart scope, you can use the default configuration provided by the Appcircle Helm chart.
:::caution
The configurations for production readiness should be **done before the first deployment** and **cannot be changed later**. To modify these settings, you should **[uninstall Appcircle](/self-hosted-appcircle/install-server/helm-chart/uninstallation)** and redeploy it.
:::
:::info
The commands below assume you have already created a namespace for Appcircle. If you haven’t yet, you can create and switch to the Appcircle namespace using the following commands:
```bash
# Create the namespace
kubectl create namespace appcircle
```
Make sure to replace `appcircle` with your preferred namespace name if necessary.
:::
### PostgreSQL
The Appcircle chart, by default, includes an in-cluster PostgreSQL deployment provided by `bitnami/PostgreSQL`.
If you are deploying the Appcircle server for testing purposes, you may use the built-in PostgreSQL deployment.
For a production-ready setup, it is recommended to configure an external PostgreSQL instance. The recommended version is PostgreSQL `12.x`, with a disk size of 40GB.
To use an external PostgreSQL database, you can follow the steps below:
- Create a secret for the PostgreSQL password. While you can choose your own secret name and key, it is recommended to use the format `${releaseName}-postgresql-connection` with the key `password`.
```bash
kubectl create secret generic appcircle-server-postgresql-connection \
-n appcircle \
--from-literal=password=superSecretPostgresqlPassword
```
- Update the `values.yaml` accordingly.
```yaml
auth:
auth-keycloak:
database:
hostname: "192.168.1.244"
port: "5432"
username: "ackeycloak"
database: "ackeycloak"
existingSecret: "appcircle-server-postgresql-connection"
existingSecretKey: "password"
auth-postgresql:
enabled: false
```
### MongoDB
By default, the Appcircle chart includes an in-cluster MongoDB deployment provided by `bitnami/mongodb` by default.
If you are deploying the Appcircle server for testing purposes, the built-in MongoDB deployment can be used.
For production environments, it is recommended to set up an external, production-grade MongoDB instance. The recommended version is MongoDB `4.2` or later, with a disk size of 40GB.
:::info
The Appcircle server supports MongoDB versions between `4.2` and `8.0`.
Later versions of the Appcircle server may deprecate `4.x` versions and might remove support for MongoDB EOL (end-of-life) [releases](https://www.mongodb.com/docs/manual/release-notes/).
For this reason, it will be better to choose a recent stable version of MongoDB instead of an EOL release, which can prevent future migration efforts as much as possible.
:::
To use an external MongoDB database, you can follow the steps below:
- Create individual users and passwords for each Appcircle service on the MongoDB instance. Each service should have its own user with distinct credentials to ensure proper access control and security. Below is an example of how to generate a secret with MongoDB connection strings for each service, where each user is assigned specific permissions for its corresponding service.
- Create a secret for the MongoDB connections. While you can choose your own secret name and key, it is recommended to use the format `${releaseName}-mongo-connections` with the multiple keys for each service.
```bash
kubectl create secret generic appcircle-server-mongo-connections \
-n appcircle \
--from-literal=agentcache='mongodb://agentcachemongo:agentPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=build='mongodb://buildmongo:buildPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=distribution='mongodb://distributionmongo:distPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=license='mongodb://licensemongo:licensePassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=notification='mongodb://notificationmongo:notificationPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=publish='mongodb://publishmongo:publishPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=reporting='mongodb://reportmongo:reportPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=resign='mongodb://resignmongo:resignPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=resource='mongodb://resourcemongo:resourcePassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=schedulemanager='mongodb://schedulemanagermongo:schedulerPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=signingidentity='mongodb://signingmongo:signingPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=store='mongodb://storemongo:storePassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=storesubmit='mongodb://storesubmitmongo:storeSubmitPassword@192.168.1.244:27017?retryWrites=true' \
--from-literal=webhook='mongodb://webhookmongo:webhookPassword@192.168.1.244:27017?retryWrites=true'
```
- Update the `values.yaml` accordingly.
Click to view example `values.yaml` file.
```yaml
agentcache:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "agentcache"
database: agentCacheStore
build:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "build"
database: buildStore
distribution:
distribution-server:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "distribution"
database: distributionStore
distribution-testeradmin:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "distribution"
database: distributionStore
distribution-testerapi:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "distribution"
database: distributionStore
distribution-testerweb:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "distribution"
database: distributionStore
distribution-web:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "distribution"
database: distributionStore
license:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "license"
database: licenseStore
notification:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "notification"
database: notificationStore
publish:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "publish"
database: publishStore
reporting:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "reporting"
database: reportingStore
resign:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "resign"
database: resignStore
resource:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "resource"
database: resourceStore
schedulemanager:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "schedulemanager"
database: scheduleManagerStore
signingidentity:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "signingidentity"
database: signingIdentityStore
store:
store-web:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "store"
database: enterpriseStore
store-admin:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "store"
database: enterpriseStore
store-api:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "store"
database: enterpriseStore
store-profile:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "store"
database: enterpriseStore
store-report:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "store"
database: enterpriseStore
storesubmit:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "storesubmit"
database: storeSubmitStore
webhook:
mongodb:
external:
enabled: true
existingConnectionSecret: "appcircle-server-mongo-connections"
existingConnectionSecretKey: "webhook"
database: webhookStore
mongodb:
enabled: false
```
### HashiCorp Vault
By default, the Appcircle chart includes an in-cluster HashiCorp Vault deployment provided by `hashicorp/vault`.
#### Test (or Trial) Environments
For testing purposes, the built-in Vault deployment can be used. In this setup, the storage is kept in Kubernetes.
If the Kubernetes cluster has multiple nodes, it should be configured to guarantee that all Vault replicas reach the same storage for consistency.
#### Production Environments
For production environments, it is recommended to configure an external HashiCorp Vault instance instead of using the built-in deployment. There are two approaches for this:
##### External Vault Service
In this setup, Appcircle connects to an externally managed Vault service. Vault operates independently from Kubernetes, ensuring better availability and scalability. The recommended Vault version is `v1.10.3` with a disk size of at least 20GB.
To use an external Vault instance, follow these steps:
- Create a Kubernetes secret with the name `${releaseName}-vault-seal` containing the Vault access token:
```bash
kubectl create secret generic appcircle-server-vault-seal \
-n appcircle \
--from-literal=token=hvs.superSecretVaultKey
```
- Update the `values.yaml` file accordingly:
```yaml
global:
vault:
url: "http://10.33.167.78:8082/v1/local/"
vault:
enabled: false
```
##### External Data Store (e.g., MSSQL)
As an alternative to using an external Vault service, you can configure Vault to use an external database such as MSSQL for storage while keeping the Vault instance inside Kubernetes.
You can find more storage configurations on the official HashiCorp documentation: [HashiCorp Vault Database Capabilities](https://developer.hashicorp.com/vault/docs/v1.10.x/secrets/databases#database-capabilities).
To use MSSQL as the storage backend:
- Ensure that your MSSQL database is accessible and properly configured.
- Update the `values.yaml` file to configure Vault with MSSQL as the backend:
```yaml
# Third party charts
vault:
server:
standalone:
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "mssql" {
server = "10.10.117.67"
port = 1433
username = "sqlserveruser"
password = "supersecretpassword"
database = "appcircle-vault"
table = "vault"
appname = "vault"
schema = "dbo"
connectionTimeout = 30
logLevel = 0
}
dataStorage:
enabled: false
```
#### Choosing the Right Setup
- If you have an **existing Vault service**, configure Appcircle to connect to it (**recommended for production**).
- If you prefer **running Vault inside Kubernetes** but want persistent storage, use an **external data store (e.g., MSSQL)** as the storage backend.
- For testing (or trial) purposes, the built-in Vault deployment **can be used but is not recommended for production workloads**. Also, it should be configured to guarantee that all Vault replicas reach the same storage for consistency when the cluster has multiple nodes.
---
## GCP Cloud Storage Configuration
## Overview
This guide provides comprehensive instructions for configuring **Google Cloud Storage (GCS)** as your object storage backend for the Appcircle server. While the default Helm chart deployment includes MinIO as an in-cluster object storage solution, **production environments** benefit from using a more robust and scalable solution like GCP Cloud Storage.
### What This Guide Covers
This guide will walk you through the process of configuring GCP Cloud Storage as your object storage backend for the Appcircle server. To use GCP Cloud Storage with Appcircle server, you need to:
- **Set up GCP infrastructure**: GCS buckets, IAM service accounts, and permissions
- **Configure Appcircle server**: Update Helm values to use GCS
- **Optional CDN setup**: Google Cloud CDN for performance optimization
## Prerequisites
To complete this guide, you must have the following:
### 1. GCP Account and Permissions
A **Google Cloud Platform (GCP) account** with appropriate permissions to create and manage Cloud Storage buckets, IAM service accounts, and roles.
Click to view more details about GCP permissions.
You need the following GCP permissions to complete this configuration:
- **Cloud Storage permissions**: Create buckets, configure CORS, manage bucket policies
- **IAM permissions**: Create service accounts, roles, and manage IAM bindings
- **Project permissions**: Access to the GCP project where resources will be created
If you're working in a restricted environment, ensure you have the necessary permissions before proceeding.
### 2. Google Cloud SDK
The **Google Cloud SDK** is **required** and must be **[installed](https://cloud.google.com/sdk/docs/install)** and **[configured](https://cloud.google.com/sdk/docs/authorizing)** on your machine.
Click to view more details about Google Cloud SDK configuration.
To configure Google Cloud SDK, you need:
- **Project ID** for your GCP project
- **Service account credentials** for authentication
You can configure Google Cloud SDK using:
```bash
gcloud init
```
Or by setting environment variables:
```bash
export GOOGLE_CLOUD_PROJECT="your-project-id"
export GOOGLE_APPLICATION_CREDENTIALS="path/to/service-account-key.json"
```
### 3. Kubernetes/OpenShift Access
**`kubectl`** (for Kubernetes) or **`oc`** (for OpenShift) CLI is **required** and must be configured to access your cluster.
:::info
This guide assumes you have administrative access to your GCP project and Kubernetes/OpenShift cluster. If you're working in a restricted environment, ensure you have the necessary permissions before proceeding.
:::
### 4. Basic Understanding
Basic understanding of **GCP IAM**, **Cloud Storage**, and **Kubernetes/OpenShift** concepts is recommended.
### 5. Optional: Domain and SSL Certificates
For Google Cloud CDN setup (optional), you'll need:
- **Domain name**: For custom CDN domains
- **SSL certificates**: For HTTPS access to your CDN
## Configuration Steps
### 1. Set Up Environment Variables
**Set up your environment variables** before proceeding with the configuration. These variables will be used throughout the configuration process.
:::note
In this documentation, we will use `spacetech` as an **example organization name** and `us-east1` as an **example GCP region**. You should **replace these values** with your actual organization name and preferred GCP region.
:::
```bash
# Set your organization name and GCP project details
ORG_NAME="spacetech" # Replace with your organization name
PROJECT_ID="my-gcp-project" # Replace with your actual GCP project ID
BUCKET_PREFIX="appcircle-${ORG_NAME}-" # Make sure to add a hyphen at the end of the bucket prefix
LOCATION="us-east1" # Replace with your preferred GCP region
SERVICE_ACCOUNT_NAME="appcircle-server"
```
:::caution
- Replace `spacetech` with your organization name in the `ORG_NAME` variable
- Replace `my-gcp-project` with your actual GCP project ID in the `PROJECT_ID` variable
- Replace `us-east1` with your preferred GCP region in the `LOCATION` variable
- Ensure your organization name follows GCS naming conventions:
- 3-63 characters long
- Lowercase letters, numbers, dots (.), and hyphens (-)
- Must start and end with a letter or number
- Must be DNS-compliant
:::
### 2. Create GCP Cloud Storage Buckets
**Create the required GCS buckets** to store the artifacts generated by the Appcircle server.
Appcircle server requires the following GCS buckets for different purposes:
- **`${BUCKET_PREFIX}temp`**: Temporary files and uploads (requires CORS configuration for direct uploads/downloads from the client browsers)
- **`${BUCKET_PREFIX}build`**: Build artifacts and logs
- **`${BUCKET_PREFIX}distribution`**: Testing Distribution files
- **`${BUCKET_PREFIX}storesubmit`**: Appcircle Store Submit files
- **`${BUCKET_PREFIX}store`**: Enterprise App Store files
- **`${BUCKET_PREFIX}agent-cache`**: Appcircle Runner cache files
- **`${BUCKET_PREFIX}backup`**: Backup files
- **`${BUCKET_PREFIX}publish`**: Published mobile app binaries
:::tip
**Bucket Naming**: Bucket names must be globally unique across all GCP projects. Using your organization name as a prefix ensures uniqueness.
:::
**Create all required buckets:**
```bash
# Create all required buckets
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}temp/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}build/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}distribution/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}storesubmit/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}store/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}agent-cache/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}backup/
gsutil mb -l ${LOCATION} gs://${BUCKET_PREFIX}publish/
```
:::info
The bucket names use your organization name to ensure global uniqueness, as GCS bucket names must be unique across all GCP projects worldwide.
:::
### 3. Configure CORS Settings
**Configure CORS settings** for the `temp` bucket to allow cross-origin requests from your Appcircle server dashboard.
:::caution
Replace the `https://my.appcircle.spacetech.com` with the dashboard URL that you will use to access the Appcircle server. For example, if you are using `.appcircle.spacetech.com` as the domain in the Helm `values.yaml` file, the dashboard URL will be `https://my.appcircle.spacetech.com`.
:::
- Create a CORS configuration file:
```bash
cat << 'EOF' > appcircle-gcs-policy.json
[
{
"origin": ["https://my.appcircle.spacetech.com"],
"method": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"responseHeader": ["*"],
"maxAgeSeconds": 3600
}
]
EOF
```
- Apply the CORS configuration:
```bash
gsutil cors set appcircle-gcs-policy.json gs://${BUCKET_PREFIX}temp
```
:::tip
- The CORS configuration is only required for the `temp` bucket.
- Other buckets don't require CORS configuration, as they are accessed server-side.
- If you're using HTTP instead of HTTPS, replace `https://` with `http://` in the **`origin`**.
:::
### 4. Create Service Account and Permissions
**Create a service account with minimal permissions** to make the Appcircle server able to access the GCS buckets.
- **Create a service account** for Appcircle server to access the GCS buckets.
```bash
gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
--description="Appcircle GCS access service account" \
--display-name="Appcircle server"
```
- **Create a custom role** with granular access for better security:
```bash
gcloud iam roles create AppcircleGCSRole \
--project=$PROJECT_ID \
--title="Appcircle GCS Role" \
--description="For Appcircle server to access GCS buckets" \
--permissions="storage.objects.get,storage.objects.list,storage.objects.create,storage.objects.delete" \
--stage=GA
```
**Bind the role to the service account for each bucket:**
```bash
# Bind permissions to each bucket
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}temp \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}build \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}distribution \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}storesubmit \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}store \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}agent-cache \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}backup \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}publish \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="projects/${PROJECT_ID}/roles/AppcircleGCSRole"
```
### 5. Generate Service Account Credentials
**Generate and download credentials** for the service account:
```bash
gcloud iam service-accounts keys create appcircle-sa-key.json \
--iam-account=${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
```
:::warning
**CRITICAL: Save the service account key file (`appcircle-sa-key.json`) securely.** You'll need these credentials in the next step to create the Kubernetes secret.
:::
### 6. Optional: Create CDN for Google Storage Buckets
Google Cloud CDN can improve performance by caching your GCS content at edge locations worldwide. This reduces latency and improves download speeds for your users.
:::tip
- **Follow this guide** if you need production-grade performance to serve your users globally.
- **Skip this section** if you're setting up for development/testing or have a small or medium team.
- You can always enable Google Cloud CDN later without reinstalling the Appcircle server.
- **Skip to** the [Create Kubernetes Secret](#create-kubernetesopenshift-secret-for-gcp-credentials) step if you do not need CDN configuration.
:::
This guide will walk you through the process of creating a CDN for your GCS buckets with the `gcloud` CLI.
:::info
**Flexibility Note**: You can achieve the same results with other tools (GCP Console, Terraform, etc.) as long as you create the same infrastructure components described in this documentation. You can also add additional configurations (security policies, monitoring, etc.) as long as you don't break the core requirements:
- CDN must be configured to serve the GCS buckets
- GCS bucket policies must be updated to allow CDN access
- URL signing key must be created and configured
- SSL certificate should be managed or imported for the CDN
- DNS must be configured to point to the CDN endpoint
- Kubernetes secret must contain the correct credentials for the URL signing key
- Helm values must include the specified CDN configuration for the Appcircle server
:::
#### Step 6.1: Create Backend Buckets and Enable CDN
**For each bucket you want to serve via CDN, create a backend bucket and enable CDN:**
```bash
gcloud compute backend-buckets create ${BUCKET_PREFIX}distribution-bucket \
--gcs-bucket-name=${BUCKET_PREFIX}distribution \
--enable-cdn \
--cache-mode=FORCE_CACHE_ALL \
--project=$PROJECT_ID
gcloud compute backend-buckets create ${BUCKET_PREFIX}build-bucket \
--gcs-bucket-name=${BUCKET_PREFIX}build \
--enable-cdn \
--cache-mode=FORCE_CACHE_ALL \
--project=$PROJECT_ID
gcloud compute backend-buckets create ${BUCKET_PREFIX}publish-bucket \
--gcs-bucket-name=${BUCKET_PREFIX}publish \
--enable-cdn \
--cache-mode=FORCE_CACHE_ALL \
--project=$PROJECT_ID
gcloud compute backend-buckets create ${BUCKET_PREFIX}store-bucket \
--gcs-bucket-name=${BUCKET_PREFIX}store \
--enable-cdn \
--cache-mode=FORCE_CACHE_ALL \
--project=$PROJECT_ID
gcloud compute backend-buckets create ${BUCKET_PREFIX}storesubmit-bucket \
--gcs-bucket-name=${BUCKET_PREFIX}storesubmit \
--enable-cdn \
--cache-mode=FORCE_CACHE_ALL \
--project=$PROJECT_ID
```
#### Step 6.2: Create URL Signing Key
**Create a URL signing key** to sign the URLs of the GCS buckets.
```bash
head -c 16 /dev/random | base64 | tr +/ -_ > url-signing-key.txt
```
#### Step 6.3: Add Signed URL Key to Backend Buckets
**Add the URL signing key to the backend buckets.**
```bash
gcloud compute backend-buckets add-signed-url-key ${BUCKET_PREFIX}distribution-bucket \
--key-name=appcircle-sign-key \
--key-file=url-signing-key.txt \
--project=$PROJECT_ID
gcloud compute backend-buckets add-signed-url-key ${BUCKET_PREFIX}build-bucket \
--key-name=appcircle-sign-key \
--key-file=url-signing-key.txt \
--project=$PROJECT_ID
gcloud compute backend-buckets add-signed-url-key ${BUCKET_PREFIX}publish-bucket \
--key-name=appcircle-sign-key \
--key-file=url-signing-key.txt \
--project=$PROJECT_ID
gcloud compute backend-buckets add-signed-url-key ${BUCKET_PREFIX}store-bucket \
--key-name=appcircle-sign-key \
--key-file=url-signing-key.txt \
--project=$PROJECT_ID
gcloud compute backend-buckets add-signed-url-key ${BUCKET_PREFIX}storesubmit-bucket \
--key-name=appcircle-sign-key \
--key-file=url-signing-key.txt \
--project=$PROJECT_ID
```
#### Step 6.4: Import SSL Certificate
**If you want to use custom domains (like `cdn.yourcompany.com`), you need an SSL certificate.**
:::info
You can skip this step if you already have an SSL certificate in your GCP project.
:::
```bash
gcloud compute ssl-certificates create appcircle-cdn-ssl-cert \
--certificate= \
--private-key= \
--global
```
#### Step 6.5: Reserve a Global Static External IP Address
**Reserve a global static external IP address** to use as the CDN endpoint.
```bash
gcloud compute addresses create appcircle-cdn-ip \
--network-tier=PREMIUM \
--ip-version=IPV4 \
--global
```
#### Step 6.6: Create URL Map for Backend Buckets
**Create a URL map** for the backend buckets.
```bash
gcloud compute url-maps create appcircle-cdn-url-map \
--default-backend-bucket=${BUCKET_PREFIX}build-bucket \
--global
```
#### Step 6.7: Create Target HTTPS Proxy for the URL Map
**Create a target HTTPS proxy** for the URL map.
```bash
gcloud compute target-https-proxies create appcircle-https-lb-proxy \
--ssl-certificates=appcircle-cdn-ssl-cert \
--url-map=appcircle-cdn-url-map
```
#### Step 6.8: Create Global Forwarding Rule for the Target HTTPS Proxy
**Create a global forwarding rule** for the target HTTPS proxy.
```bash
gcloud compute forwarding-rules create appcircle-cdn-forwarding-rule \
--address=appcircle-cdn-ip \
--global \
--target-https-proxy=appcircle-https-lb-proxy \
--ports=443 \
--load-balancing-scheme=EXTERNAL \
--network-tier=PREMIUM \
--project=$PROJECT_ID
```
#### Step 6.9: Add Additional URL Maps for Backend Buckets
**Add additional URL maps** for the backend buckets.
```bash
gcloud compute url-maps add-path-matcher appcircle-cdn-url-map \
--path-matcher-name=appcircle-distribution-matcher \
--new-hosts=appcircle-distribution-cdn.spacetech.com \
--default-backend-bucket=${BUCKET_PREFIX}distribution-bucket \
--project=$PROJECT_ID
gcloud compute url-maps add-path-matcher appcircle-cdn-url-map \
--path-matcher-name=appcircle-publish-matcher \
--new-hosts=appcircle-publish-cdn.spacetech.com \
--default-backend-bucket=${BUCKET_PREFIX}publish-bucket \
--project=$PROJECT_ID
gcloud compute url-maps add-path-matcher appcircle-cdn-url-map \
--path-matcher-name=appcircle-store-matcher \
--new-hosts=appcircle-store-cdn.spacetech.com \
--default-backend-bucket=${BUCKET_PREFIX}store-bucket \
--project=$PROJECT_ID
gcloud compute url-maps add-path-matcher appcircle-cdn-url-map \
--path-matcher-name=appcircle-storesubmit-matcher \
--new-hosts=appcircle-storesubmit-cdn.spacetech.com \
--default-backend-bucket=${BUCKET_PREFIX}storesubmit-bucket \
--project=$PROJECT_ID
```
#### Step 6.10: Grant CDN Service Account Access to Buckets
**Grant CDN service account access to the buckets.**
```bash
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='get(projectNumber)')
```
**Assign the `roles/storage.objectViewer` to the LoadBalancer service account to make it able to access the private GCS buckets:**
```bash
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}distribution \
--member=serviceAccount:service-${PROJECT_NUMBER}@cloud-cdn-fill.iam.gserviceaccount.com \
--role=roles/storage.objectViewer
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}build \
--member=serviceAccount:service-${PROJECT_NUMBER}@cloud-cdn-fill.iam.gserviceaccount.com \
--role=roles/storage.objectViewer
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}publish \
--member=serviceAccount:service-${PROJECT_NUMBER}@cloud-cdn-fill.iam.gserviceaccount.com \
--role=roles/storage.objectViewer
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}store \
--member=serviceAccount:service-${PROJECT_NUMBER}@cloud-cdn-fill.iam.gserviceaccount.com \
--role=roles/storage.objectViewer
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_PREFIX}storesubmit \
--member=serviceAccount:service-${PROJECT_NUMBER}@cloud-cdn-fill.iam.gserviceaccount.com \
--role=roles/storage.objectViewer
```
#### Step 6.11: Create Kubernetes Secret for CDN URL Sign Key
**Create a Kubernetes secret** for the URL signing key.
```bash
kubectl create secret generic appcircle-cdn-url-sign-key -n appcircle \
--from-literal='cdn-url-sign-key-name=appcircle-sign-key' \
--from-literal="cdn-url-sign-key=$(cat url-signing-key.txt)"
```
## Create Kubernetes/OpenShift Secret for GCP Credentials
- Create the namespace that Appcircle server will be installed in if you haven't yet:
```bash
kubectl create namespace appcircle
```
- **Create a Kubernetes secret** named `-gcs-credentials` with the GCP credentials to be used by Appcircle server.
```bash
# Convert the service account key to base64
ENCODED_CREDENTIALS=$(cat appcircle-sa-key.json | base64 -w 0)
# Create the Kubernetes secret
kubectl create secret generic appcircle-gcs-credentials \
-n appcircle \
--from-literal=gcs-credentials-base64="${ENCODED_CREDENTIALS}"
```
- Create the project that Appcircle server will be installed in if you haven't yet:
```bash
oc new-project appcircle
```
- **Create an OpenShift secret** named `-gcs-credentials` with the GCP credentials to be used by Appcircle server.
```bash
# Convert the service account key to base64
ENCODED_CREDENTIALS=$(cat appcircle-sa-key.json | base64 -w 0)
# Create the OpenShift secret
oc create secret generic appcircle-gcs-credentials \
-n appcircle \
--from-literal=gcs-credentials-base64="${ENCODED_CREDENTIALS}"
```
:::caution
- Replace `appcircle` with your actual namespace or project if different.
- Ensure the `appcircle-sa-key.json` file is in your current directory.
- The secret name `appcircle-gcs-credentials` will be referenced in the Helm configuration.
:::
## Configure Helm Values
**Configure your `values.yaml` file** to use GCP Cloud Storage instead of MinIO.
Add or update the following configuration to your `values.yaml` file:
```yaml
global:
minio:
url: https://storage.googleapis.com # Do not replace this value
region: "us-east1" # Replace with your GCP region
useHttp: "false" # Set to "false" since the GCS endpoint is HTTPS
bucketPrefix: "appcircle-spacetech-" # Replace with your bucket prefix
resource:
s3:
clientProvider: "GCLOUD" # Set to "GCLOUD" to use GCP Cloud Storage
cdnProvider: "GCLOUD" # Set to "GCLOUD" to use GCP Cloud Storage
urlSignKeySecretName: "appcircle-cdn-url-sign-key" # Reference to the secret created above
googleCredentialsSecretName: "appcircle-gcs-credentials" # Reference to the secret created above
cdnMapping: "Build=https://appcircle-build-cdn.spacetech.com,Distribution=https://appcircle-distribution-cdn.spacetech.com,Storesubmit=https://appcircle-storesubmit-cdn.spacetech.com,Store=https://appcircle-store-cdn.spacetech.com,Publish=https://appcircle-publish-cdn.spacetech.com" # Replace with your CDN mapping
minio:
enabled: false
```
```yaml
global:
minio:
url: https://storage.googleapis.com # Do not replace this value
region: "us-east1" # Replace with your GCP region
useHttp: "false" # Set to "false" since the GCS endpoint is HTTPS
bucketPrefix: "appcircle-spacetech-" # Replace with your bucket prefix
resource:
s3:
clientProvider: "GCLOUD" # Set to "GCLOUD" to use GCP Cloud Storage
googleCredentialsSecretName: appcircle-gcs-credentials # Reference to the secret created above
minio:
enabled: false # Disable internal MinIO deployment
```
:::caution
- Do not change the `https://storage.googleapis.com` value. It is set to the default GCS endpoint.
- Replace `us-east1` with your GCP region.
- Run `echo $LOCATION` to get your GCP region from the variables defined in the previous steps.
- Replace `appcircle-spacetech-` with your actual bucket prefix.
- Run `echo $BUCKET_PREFIX` to get your bucket prefix from the variables defined in the previous steps.
- Ensure `googleCredentialsSecretName` matches the secret name created in the previous step.
:::
## Next Steps
After completing the GCP Cloud Storage configuration:
1. **Return to the main installation guide**:
- For Kubernetes: [Kubernetes Installation](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes)
- For OpenShift: [OpenShift Installation](/self-hosted-appcircle/install-server/helm-chart/installation/openshift)
2. **Continue with the installation process** using your configured `values.yaml` file
3. **Verify the configuration** by checking that Appcircle server can access the GCS buckets after installation
---
## Production Readiness
Appcircle server Helm chart support extensive customization through values files for production configurations.
Current headlines are listed below:
- [Database and Vault Configurations](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness/database-and-vault) contains the configurations for PostgreSQL, MongoDB and HashiCorp Vault.
- Object Storage Configuration contains the object storage configurations for the Appcircle server.
- [S3 Compatible Object Storage Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness/s3-compatible-storage-configuration.md)
- [AWS S3 Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness/aws-s3-configuration)
- [Google Cloud Storage Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness/gcp-cloud-storage-configuration)
In order to see the details, check the submenu of this documentation page.
---
## S3-Compatible Object Storage Configuration
## Overview
This guide provides comprehensive instructions for configuring **any S3-compatible object storage** (such as MinIO, Wasabi, Backblaze B2, DigitalOcean Spaces, Cloudflare R2, etc.) as your object storage backend for the Appcircle server.
By default, the Appcircle chart includes an in-cluster MinIO deployment provided by `bitnami/minio`. If you are installing the Appcircle for testing purposes, you may use the built-in MinIO deployment.
For production environments, it is recommended to configure an external MinIO or S3-compatible object storage instance. If you prefer to use an external MinIO service, the recommended MinIO version is `2024-03-15` or later, with a disk size of at least 100GB.
:::info
The recommended disk size for the object storage may vary depending on your usage requirements. It can range from 100GB to 3-4TB.
:::
### What This Guide Covers
This guide will walk you through the process of configuring an S3-compatible object storage backend for the Appcircle server Helm chart. To use an S3-compatible provider with Appcircle server, you need to:
- **Set up your object storage provider**: Buckets, users, and permissions
- **CORS setup**: For direct browser uploads/downloads
- **Configure Appcircle server**: Update Helm values to use your S3-compatible storage
:::info
This guide is for any S3-compatible provider. For [AWS S3](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness/aws-s3-configuration) or [GCP Cloud Storage](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness/gcp-cloud-storage-configuration), see their dedicated guides.
:::
## Prerequisites
To complete this guide, you must have the following:
- An S3-compatible object storage provider (MinIO, Wasabi, Backblaze B2, DigitalOcean Spaces, Cloudflare R2, etc.)
- Access to the provider's management console or CLI
- Basic understanding of object storage, access keys, and Kubernetes
:::caution
Keep in mind that if you will use an AWS S3-compatible provider, the `resource.s3.clientProvider` [setting](#5-configure-appcircle-server-to-use-s3-compatible-storage) used for the `AWS` option has limited support for the S3 endpoint styles.
The Appcircle server does not support the path-style S3 endpoint model. So, your S3 endpoints should be virtual-hosted style, which can be accessible using relevant DNS subdomains.
Refer [here](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/) to see the differences between two styles and configure your S3 endpoints if necessary.
:::
## Configuration Steps
### 1. Create and Configure Buckets
**Create the required buckets** to store the artifacts generated by the Appcircle server.
Appcircle server requires the following buckets for different purposes:
- **`${BUCKET_PREFIX}temp`**: Temporary files and uploads (requires CORS configuration for direct uploads/downloads from the client browsers)
- **`${BUCKET_PREFIX}build`**: Build artifacts and logs
- **`${BUCKET_PREFIX}distribution`**: Testing Distribution files
- **`${BUCKET_PREFIX}storesubmit`**: Appcircle Store Submit files
- **`${BUCKET_PREFIX}store`**: Enterprise App Store files
- **`${BUCKET_PREFIX}agent-cache`**: Appcircle Runner cache files
- **`${BUCKET_PREFIX}backup`**: Backup files
- **`${BUCKET_PREFIX}publish`**: Published mobile app binaries
:::tip
**Bucket Naming**: Choose a unique bucket prefix for your organization or environment (e.g., `appcircle-spacetech-`).
:::
**Create the required buckets** using your S3-compatible provider's management console, CLI, or API. Refer to your provider's documentation for specific instructions on bucket creation.
:::info
You can use your provider's web console, CLI tools, or API to create the buckets. The exact method varies by provider.
:::
### 2. IAM/User Setup and Access Keys
**Create a user (or access key pair) with permissions** to manage objects in the above buckets. The process varies by provider:
- **MinIO**: Use the MinIO Console or `mc admin user add` to create a user and assign policies.
- **Wasabi**: Use the Wasabi Console to create an access key/secret key pair with full access to the relevant buckets.
- **Backblaze B2**: Use the B2 Console to create an application key with access to the required buckets.
- **DigitalOcean Spaces**: Use the DigitalOcean Console to create a Spaces access key with appropriate permissions.
- **Cloudflare R2**: Use the Cloudflare Dashboard to create an API token with R2 permissions.
:::caution
Restrict permissions to only the required buckets for better security.
:::
### 3. CORS Configuration
**Configure CORS settings** for the `temp` bucket to allow cross-origin requests from your Appcircle server dashboard.
- Here is a sample CORS configuration for the `temp` bucket that is compatible with AWS CLI:
:::caution
Make sure to replace the `https://my.appcircle.spacetech.com` with the dashboard URL that you will use to access the Appcircle server. For example, if you are using `.appcircle.spacetech.com` as the domain in the Helm `values.yaml` file, the dashboard URL will be `https://my.appcircle.spacetech.com`.
:::
```bash
export CORS='{
"CORSRules": [
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedOrigins": ["https://my.appcircle.spacetech.com"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3600
}
]
}'
```
Refer to your provider's documentation for how to apply CORS settings.
:::tip
- The CORS configuration is only required for the `temp` bucket.
- **Make sure** that the clients are allowed to access the `temp` bucket over network. The clients (Appcircle users with the dashboard) use the `temp` bucket to upload/download files.
- Other buckets don't require CORS configuration, as they are accessed server-side.
- If you will use the Appcircle server dashboard with HTTP instead of HTTPS, replace `https://` with `http://` in the **`AllowedOrigins`**.
:::
:::info
If the S3-compatible provider supports CORS configuration with the AWS CLI, you can use the following steps:
- Configure the AWS CLI with your access key, secret key, region, and endpoint URL for the S3-compatible provider.
```bash
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_DEFAULT_REGION=
export AWS_ENDPOINT_URL=
```
- Apply the CORS configuration to the `temp` bucket:
```bash
aws s3api put-bucket-cors \
--endpoint-url $AWS_ENDPOINT_URL \
--bucket ${BUCKET_PREFIX}temp \
--cors-configuration "$CORS"
```
- Check the CORS configuration:
```bash
aws s3api get-bucket-cors \
--endpoint-url $AWS_ENDPOINT_URL \
--bucket ${BUCKET_PREFIX}temp
```
:::
### 4. Create Kubernetes/OpenShift Secret with Access Keys
- Create the namespace that Appcircle server will be installed in if you haven't yet:
```bash
kubectl create namespace appcircle
```
- **Create a Kubernetes secret** named `-minio-connection` with your S3-compatible access and secret keys:
```bash
kubectl create secret generic appcircle-server-minio-connection \
-n appcircle \
--from-literal=accessKey= \
--from-literal=secretKey=
```
- Create the project that Appcircle server will be installed in if you haven't yet:
```bash
oc new-project appcircle
```
- **Create an OpenShift secret** named `-minio-connection` with your S3-compatible access and secret keys:
```bash
oc create secret generic appcircle-server-minio-connection \
-n appcircle \
--from-literal=accessKey= \
--from-literal=secretKey=
```
:::caution
- Replace `appcircle` with your actual namespace or project if different.
- Replace `` and `` with your actual access and secret keys.
- Replace `appcircle-server-minio-connection` with `-minio-connection`. Appcircle documentation uses `appcircle-server` as the release name.
:::
### 5. Configure Appcircle server to Use S3-Compatible Storage
**Configure your `values.yaml` file** to use your S3-compatible object storage.
Add or update the following configuration to your `values.yaml` file:
```yaml
global:
minio:
url: "https://your-minio-endpoint.com" # e.g., https://minio.spacetech.com:9000
region: "local" # MinIO uses "local" as the region
useHttp: "false" # Set to "true" if the MinIO endpoint uses HTTP instead of HTTPS
bucketPrefix: "appcircle-spacetech-" # Replace with your actual bucket prefix
resource:
s3:
clientProvider: "MINIO" # Use "MINIO" for MinIO
minio:
enabled: false # Disable the internal MinIO server if you are using an external MinIO server
```
```yaml
global:
minio:
url: "https://your-s3-endpoint.com" # e.g., https://s3.wasabisys.com
region: "us-east-1" # Use the region of the buckets
useHttp: "false" # Set to "true" if the S3 endpoint uses HTTP instead of HTTPS
bucketPrefix: "appcircle-spacetech-" # Replace with your actual bucket prefix
resource:
s3:
clientProvider: "AWS" # Use "AWS" for AWS S3-compatible providers
minio:
enabled: false # Disable the internal MinIO server if you are using an external MinIO server
```
:::info
- Set `useHttp` to `true` only if your S3 or MinIO endpoint does not support HTTPS (not recommended for production).
- Check your provider's documentation for the correct endpoint URL and region.
- Replace `appcircle-spacetech-` with your actual bucket prefix.
:::
## Next Steps
After completing the S3-compatible storage configuration:
1. **Return to the main installation guide**:
- For Kubernetes: [Kubernetes Installation](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes)
- For OpenShift: [OpenShift Installation](/self-hosted-appcircle/install-server/helm-chart/installation/openshift)
2. **Continue with the installation process** using your configured `values.yaml` file
3. **Verify the configuration** by checking that the Appcircle server can access the buckets after installation.
---
## Sensitive Values
## Secrets for Sensitive Values
To manage sensitive information such as the Appcircle initial user password, SSL certificates, and other secrets, it is recommended to use Kubernetes secrets. This ensures that sensitive data is stored securely and can be accessed by applications running within the cluster in a controlled manner. Some settings like SMTP can be configured either through Kubernetes secrets during initial deployment or directly from the Appcircle Dashboard after installation.
:::caution
The configurations for secret values should be **done before the first deployment** and **cannot be changed later**. To modify these settings, you should **[uninstall Appcircle](/self-hosted-appcircle/install-server/helm-chart/uninstallation)** and redeploy it.
:::
:::info
The commands below assume you have already created a namespace for Appcircle. If you haven’t yet, you can create the Appcircle namespace using the following commands:
```bash
# Create the namespace
kubectl create namespace appcircle
```
Make sure to replace `appcircle` with your preferred namespace name if necessary.
:::
You can follow the steps below to create a secret for each sensitive value.
:::tip
If the `HISTCONTROL` environment variable is set to `ignoreboth`, commands with a leading space character will not be stored in the shell history. This allows you to create secrets safely without storing sensitive information in the shell history.
:::
#### Appcircle initial user password
- Create a secret with the name `${releaseName}-auth-keycloak-passwords` containing the `initialPassword` and `adminPassword` keys.
:::info
In the example, **`appcircle-server`** is used as the **release name**. Make sure to replace it with your actual release name if it's different.
:::
```bash
kubectl create secret generic appcircle-server-auth-keycloak-passwords \
--from-literal=initialPassword=Test1234 \
--from-literal=adminPassword=KeycloakAdminPassword1234 \
-n appcircle
```
- Remove the `.auth.auth-keycloak.initialPassword` and `.auth.auth-keycloak.adminPassword` keys from the `values.yaml` file if they exist.
#### SMTP password
:::caution
Starting from the server version `3.28.2`, SMTP settings can be configured and updated directly from the Appcircle Dashboard. This is the recommended approach for managing SMTP settings as it allows you to update the configuration at any time without requiring server reset.
See the [email integration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) document for more information about the SMTP configuration.
See the [version history](/self-hosted-appcircle/install-server/helm-chart/upgrades#version-history) to find out the minimum required Helm chart version for the server.
:::
If you prefer to configure SMTP via Kubernetes secrets during initial deployment:
- Create a secret with the name `${releaseName}-smtp` containing the `password` key.
:::info
In the example, **`appcircle-server`** is used as the **release name**. Make sure to replace it with your actual release name if it's different.
:::
```bash
kubectl create secret generic appcircle-server-smtp \
--from-literal=password="superSecretSMTPPassword" \
-n appcircle
```
- Remove the `.global.mail.smtp.password` key from the `values.yaml` file if it exists.
:::tip
Even if you initially configure SMTP using Kubernetes secrets, you can still use the Appcircle Dashboard for subsequent updates.
But **keep in mind that** beforehand you should remove the relevant settings from the server configuration effectively, which requires you to apply configuration changes.
:::
#### SSL certificate
- Create a secret with the name `appcircle-tls-wildcard` containing the `tls.crt`, `tls.key` and `ca.crt` keys.
:::caution
The name **`appcircle-tls-wildcard`** is **reserved** and **cannot be changed**.
:::
```bash
kubectl create secret generic appcircle-tls-wildcard \
--from-file=tls.crt='fullchain.crt' \
--from-file=tls.key='private.key' \
--from-file=ca.crt='root-ca.crt' \
--type=kubernetes.io/tls \
-n appcircle
```
- Remove the `.global.tlsWildcard` key from the `values.yaml` file if it exists.
#### Apply Configuration Changes
---
## Helm SSL Configuration
# Overview
This guide provides detailed instructions for configuring an SSL certificate for HTTPS connections in the Appcircle Helm chart.
By default, the Helm chart is configured for HTTP without an SSL certificate. If you use Appcircle with HTTP, you need to open port 6379 on the ingress controller for Redis the connection.
:::caution
Appcircle must be installed with HTTPS from the initial installation. If you initially installed Appcircle with HTTP, you will need to [uninstall](/self-hosted-appcircle/install-server/helm-chart/uninstallation) it and then reinstall it with HTTPS.
:::
You have two options for configuring SSL certificates:
1. **Trial Purposes**: Define the SSL certificate directly in the `values.yaml` by following [this section](#define-the-ssl-certificate-in-valuesyaml).
2. **Production**: Create a Kubernetes secret for better security and manageability by following [this section](#define-the-ssl-certificate-in-secrets).
:::info
When configuring Appcircle with HTTPS, you have the option to use self-signed or untrusted root certificates. However, if you choose to do so, it is essential to add the certificate or the root CA certificate to the trusted certificates. Failure to do this may result in connection errors. For detailed instructions about adding trusted CA certificates, refer to the [Adding Trusted CA Certificates](/self-hosted-appcircle/install-server/helm-chart/configuration/ca-certificates) documentation.
:::
## Define the SSL Certificate in `values.yaml`
### Initial SSL Configuration
#### Update the `values.yaml`
To configure the SSL certificate, update your `values.yaml` file with the following settings:
```yaml
global:
urls:
scheme: https
tlsWildcard:
# Public certificate - Fullchain including leaf (app), intermediate and root SSL certificates
cert: |
-----BEGIN CERTIFICATE-----
MIIFzTCCBLWgAwIBAgISBMLn5uQI6Wmzku14xXUbbIbmMA0GCSqGSIb3DQEBCwUA
...
SA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFBjCCAu6gAwIBAgIRAIp9PhPWLzDvI4a9KQdrNPgwDQYJKoZIhvcNAQELBQAw
...
uYkQ4omYCTX5ohy+knMjdOmdH9c7SpqEWBDC86fiNex+O0XOMEZSa8DA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
...
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Private key for the SSL certificate
key: |
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3wS87baGONXjr
...
oUcjMAu/mGJjtn9AS0S7rRa58Q==
-----END PRIVATE KEY-----
# Certificate Authority public key - Typically the bottom certificate of the fullchain SSL certificate
caCert: |
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
...
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Web event Redis configuration
webeventredis:
# Enable TLS for Redis connections
tls:
enabled: true
# Ingress configuration for Redis
ingress:
enabled: true
tls: true
```
### Updating the Certificate
To update the SSL certificate used on Appcircle server, perform the following steps to update the Helm chart and restart the required services:
1. Update the SSL certificate defined in the `values.yaml`.
2. Run the Helm upgrade command to apply the changes:
```bash
helm upgrade appcircle-server appcircle/appcircle -n appcircle -f values.yaml
```
3. To restart the Redis service after updating the SSL certificate, you need to first filter and find the names of the stateful sets, as the names might change according to the release name. Use the following command to get the stateful sets:
```bash
kubectl get statefulset -n appcircle | grep webeventredis
````
4. Restart the Redis StatefulSets to apply the changes:
```bash
kubectl rollout restart statefulset/appcircle-server-webeventredis-master -n appcircle
kubectl rollout restart statefulset/appcircle-server-webeventredis-replicas -n appcircle
```
## Define the SSL Certificate in Secrets
### Initial SSL Configuration
#### Updating the `values.yaml`
To configure the SSL certificate, update your `values.yaml` file with the following settings:
```yaml
global:
urls:
scheme: https
# Web event Redis configuration
webeventredis:
# Enable TLS for Redis connections
tls:
enabled: true
# Ingress configuration for Redis
ingress:
enabled: true
tls: true
```
#### Create the Secret
Create a secret with the name `appcircle-tls-wildcard` containing the `tls.crt`, `tls.key` and `ca.crt` keys.
:::info
The certificate (`cert`) should be in PEM format and include the full-chain (leaf, intermediate, and root certificates).
The private key (`key`) should not be password-protected.
:::
:::caution
The name **`appcircle-tls-wildcard`** is **reserved** and **cannot be changed**.
:::
```bash
kubectl create secret generic appcircle-tls-wildcard \
--from-file=tls.crt='fullchain.crt' \
--from-file=tls.key='private.key' \
--from-file=ca.crt='root-ca.crt' \
--type=kubernetes.io/tls \
-n appcircle
```
### Updating the Certificate
To update an existing SSL certificate, use the following commands.
1. Update the secret with the new certificate.
```bash
kubectl create secret generic appcircle-tls-wildcard \
-n appcircle \
--from-file=tls.crt='fullchain.crt' \
--from-file=tls.key='private.key' \
--from-file=ca.crt='root-ca.crt' \
--type=kubernetes.io/tls \
--save-config --dry-run=client -o yaml | kubectl apply -f -
```
2. To restart the Redis service after updating the SSL certificate, you need to first filter and find the names of the stateful sets, as the names might change according to the release name. Use the following command to get the stateful sets:
```bash
kubectl get statefulset -n appcircle | grep webeventredis
````
3. Restart the Redis StatefulSets to apply the changes:
```bash
kubectl rollout restart statefulset/appcircle-server-webeventredis-master -n appcircle
kubectl rollout restart statefulset/appcircle-server-webeventredis-replicas -n appcircle
```
## Final Steps
Verify the SSL configuration by accessing the Appcircle server over HTTPS.
---
## Storage Configuration
### Persistent Volume Configuration
Appcircle server Helm chart supports configuring storage classes and volume sizes for persistent volume claims (PVCs). If you don't specify any storage class or size, the PVCs will be created using the default storage class of your Kubernetes cluster with the default size. If you want to adjust these settings, you can specify them in the `values.yaml`.
:::caution
The configurations for storage classes should be **done before the first deployment** and **cannot be changed later**. To modify these settings, you should **[uninstall Appcircle](/self-hosted-appcircle/install-server/helm-chart/uninstallation)** and redeploy it.
:::
:::tip
You can check your **default storage class** by running the following command and check the output:
```bash
kubectl get storageclass
```
According to the sample output below, there is a `default` storage class.
```output
kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 59d
```
If the Kubernetes cluster you are deploying Appcircle server **doesn't have a default** storage class, you can **set** the storage class from `values.yaml`.
:::
:::caution
Some storage classes do not support **expanding volumes**. You should verify the capabilities of your own storage class. If volume expansion is needed, **manual operations**, such as moving data from the old volume to a new one, may be required.
:::
You can configure the `values.yaml` like in the example below. The storage values given in the example are recommended values for production usage.
```yaml
auth:
auth-postgresql:
primary:
persistence:
size: 40Gi
storageClass: nfs-client
mongodb:
persistence:
size: 30Gi
storageClass: nfs-client
kafka:
controller:
persistence:
size: 8Gi
storageClass: nfs-client
minio:
persistence:
storageClass: nfs-client
size: 1Ti
vault:
server:
dataStorage:
size: 20Gi
storageClass: nfs-client
webeventredis:
master:
persistence:
size: 2Gi
storageClass: nfs-client
replica:
persistence:
size: 2Gi
storageClass: nfs-client
```
---
## Troubleshooting & FAQ
### When we try to login to the Appcircle server, we see `too many redirects` error from browser
This error usually happens when the pods can't resolve some of [the Appcircle server domains](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes#1-domain-name).
For the solution, please make sure that the domain name server of the worker nodes of the Kubernetes cluster can resolve the Appcircle server domain names.
### When we deploy the Helm chart, the `appcircle-server-webeventredis-master-0` pod is stuck in `CrashLoopBackOff` state
This error usually happens when you select a non-valid `Appcircle CA Certificate File` while [creating the configuration file](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes#1-create-valuesyaml). Please make sure that the certificate you choose is the **root** certificate of the full-chain certificate.
:::tip
If you created the SSL/TLS certificate with LetsEncrypt, you should know that the `fullchain.pem` file doesn't include the root CA certificate by default.
:::
To fix the problem, you can edit the `values.yaml` file and upgrade the Helm chart.
```bash
helm upgrade appcircle-server appcircle/appcircle \
--timeout 1200s \
-n appcircle \
-f values.yaml
```
:::caution
The `stateful` pods won't be recreated from a error state. This is known issue of Kubernetes.
You should delete the pods manually to fix this problem. The new updated pods will be created automatically. You can use the example commands below to delete the pods:
```bash
kubectl delete pods appcircle-server-webeventredis-master-0 -n appcircle && \
kubectl delete pods appcircle-server-webeventredis-replicas-0 -n appcircle && \
kubectl delete pods appcircle-server-webeventredis-replicas-1 -n appcircle
```
:::
### What should we do if the deployment hasn't been completed and timed out?
If the deployment hasn't completed and timed out after `1200` seconds:
- **Low Network Bandwidth or Insufficient Processing Power:** If the timeout occurred due to low network bandwidth or insufficient processing power, you can re-run the Helm deployment command as it is idempotent.
- **Configuration Issues:** If the timeout was caused by a configuration problem, you will need to troubleshoot the issue. Review your configuration settings and logs to identify and resolve any errors before attempting the deployment again.
:::tip
If you face a timeout due to configuration problems, it is better to re-install Appcircle freshly. Refer to the [Uninstalling Appcircle](/self-hosted-appcircle/install-server/helm-chart/uninstallation) section for detailed instructions on how to uninstall and clean up the existing deployment before starting anew.
:::
### What should we do if we use an Ingress controller other then Nginx Ingress?
If you are using an ingress controller other than the Nginx Ingress controller, you should add an additional annotation to the `resource` ingress.
By default, Appcircle adds the [`upstream vhost`](https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#custom-nginx-upstream-vhost) annotation. You should add alternative annotation for your ingress controller.
For example, if you are using HAProxy as an Ingress controller, you should add the annotation to the `values.yaml` of the Appcircle Helm chart:
:::caution
`appcircle-server` below should be the Helm chart release name. In the installation document, we use `appcircle-server` for the release name. You should change it if you changed the release name.
:::
```yaml
resource:
ingress:
annotations:
haproxy.org/set-host: "appcircle-server-minio:9000"
```
---
## Helm Chart
Helm is a package manager for Kubernetes that simplifies the deployment and management of applications using predefined templates called charts. A Helm Chart bundles Kubernetes resources, configurations, and dependencies into a reusable package, making it easier to deploy, upgrade, and manage applications consistently across different environments.
Current headlines are listed below:
- [Installation](/self-hosted-appcircle/install-server/helm-chart/installation)
- [Upgrades](/self-hosted-appcircle/install-server/helm-chart/upgrades)
- [Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration)
- [Uninstallation](/self-hosted-appcircle/install-server/helm-chart/uninstallation)
- [Troubleshooting & FAQ](/self-hosted-appcircle/install-server/helm-chart/faq)
In order to see the details, check the submenu of this documentation page.
---
## Installation
Helm charts can be deployed on Kubernetes and OpenShift clusters using the Helm CLI. The installation process involves adding the Helm repository, configuring values, and deploying the chart using the helm install command.
Current headlines are listed below:
- [Kubernetes](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes)
- [OpenShift](/self-hosted-appcircle/install-server/helm-chart/installation/openshift)
In order to see the details, check the submenu of this documentation page.
---
## Kubernetes
## Overview
This guide offers a comprehensive overview of installing the Appcircle chart. While the provided **default values** are suitable **for initial trials**, they are not recommended for production environments.
**For production deployments**, it is essential to **review the detailed descriptions** and **optional sections** to ensure a secure and reliable setup. **This document supports both trial and production installations**.
## Prerequisites
To complete this guide, you must have the following:
### 1. Domain Name
A main **domain name**, which will have **subdomains**, is **required** for the Appcircle server.
:::note
In this documentation, we will use `appcircle.spacetech.com` as an **example main domain** and `spacetech` as an **example organization name**.
:::
Click to view more details about domain name prerequisite.
By default, Appcircle uses seven subdomains. These subdomains are:
1. api.appcircle.spacetech.com
2. auth.appcircle.spacetech.com
3. dist.appcircle.spacetech.com
4. hook.appcircle.spacetech.com
5. resource.appcircle.spacetech.com
6. my.appcircle.spacetech.com
7. kvs.appcircle.spacetech.com
**Upon completing the deployment** of the Appcircle server, you will need to create DNS records based on the Ingress objects created in Kubernetes.
### 2. SSL Certificate
An **SSL certificate** is **required** to deploy the Appcircle server for **production** environments.
You **can skip** SSL certificate if you are deploying Appcircle server **for trial purposes**.
Click to view more details about SSL certificate prerequisite.
- The SSL certificate private key shouldn't be password protected.
- The SSL certificate should be in PEM format.
- Ensure the **one certificate** covers **all the subdomains** in the [domain name](#1-domain-name) section.
- Make sure to configure the Appcircle server with a **fullchain certificate**, which should include the leaf (or app) certificate, intermediate certificates, and the root certificate.
:::tip
You can use a **wildcard certificate** to cover all the subdomains, simplifying the certificate management process. For example, a wildcard certificate for **`*.appcircle.spacetech.com`** will be enough.
:::
:::caution
If you use a domain like `appcircle.spacetech.com`, it will have **two levels of subdomains**. Ensure that both your DNS provider and SSL certificate provider support multi-level subdomains for proper configuration.
:::
### 3. Kubernetes Cluster
A **Kubernetes cluster** is **required** to install the Appcircle server using Helm.
**Minimum hardware requirements for enterprise installation:**
- Node(s) with `x86_64` architecture
- 8 CPUs
- 16 GB RAM
- 50 GB Disk per node
:::tip
The required storage size for the Appcircle server depends significantly on the size of the artifacts (APK, IPA, cache).
:::
Click to view more details about Kubernetes cluster prerequisite.
**Recommended hardware requirements for enterprise installation:**
- Nodes with `x86_64` architecture
- 32 CPUs
- 64 GB RAM
- 1 TB Disk
For production environments, if you deploy stateful applications with the Appcircle Helm chart, you will need significant storage capacity, as specified above. You can configure disk resource allocations through Helm values according to your needs.
However, if you opt to use external services for components such as PostgreSQL or MinIO, the storage requirements for the cluster are significantly reduced to around 50GB. It is **highly recommended** to deploy stateful apps outside of the Appcircle Helm chart configuration.
:::tip
For stateful apps that should deployed out of scope this helm chart, you can check the [Production Readiness](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness) document.
For storage details, you can check the [Storage Class Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/storage-configuration) section.
:::
:::info
Using SSD storage is highly recommended if stateful applications are installed within the Appcircle Helm chart scope. SSDs provide faster read/write speeds, improving the performance and responsiveness of your applications.
:::
Additionally, ensure that your Kubernetes version is 1.29.1 or later to maintain compatibility and support.
### 4. `kubectl`
The **`kubectl`** CLI is **required**.
### 5. Helm v3
**Helm version `3.11.0`** or later is **required**.
## Pre-installation Steps
### 1. Ingress Controller
The Kubernetes cluster should have **an Ingress controller** installed and configured since Appcircle exposes its services through **Ingress objects**.
For **trial** purposes, you can **use** the default **Ingress-Nginx** controller deployed **within the Helm chart** scope and skip this section.
You can check the default Ingress-Nginx controller values and configure as your needs by checking the [Ingress Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/ingress-configuration.md#appcircle-default-ingress-nginx-configuration) documentation.
For **production** environments, it's recommended to use **your own Ingress controller**.
Appcircle server supports Ingress-Nginx controller by default. To install Ingress-Nginx controller to the Kubernetes cluster, please check [the Ingress-Nginx controller documentation](https://kubernetes.github.io/ingress-nginx/deploy/#installation-guide).
:::info
**Other Ingress controllers** like HAProxy Ingress controller are also **supported** by **modifying Helm values** accordingly.
:::
#### Enable SSL Passthrough
You can **skip** this section **if you use the default** Ingress-Nginx controller deployed **within the Helm chart scope**.
Enable **`ssl-passthrough`** feature on your ingress-controller Enabling the SSL passthrough depends on the Ingress controller that is used in the Kubernetes cluster. For example:
- For Nginx Ingress controller, you can check [the Nginx documentation](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#ssl-passthrough).
- For HAProxy Ingress controller, you can check [the HAProxy documentation](https://www.haproxy.com/documentation/kubernetes-ingress/community/configuration-reference/ingress/#ssl-passthrough).
:::info
Enabling the SSL passthrough option **does not** automatically allow all SSL traffic **from all Ingress objects** to pass through to the original service. Instead, it enables Ingress resources to leverage the SSL passthrough feature, allowing encrypted traffic to reach the backend service without being decrypted by the Ingress controller.
:::
#### Ingress Configurations
You can **skip** this section **if you use the default** Ingress-Nginx controller deployed **within the Helm chart scope**.
Configure the Appcircle ingresses for production usage. For more details, please check the [Ingress Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/ingress-configuration.md#configuring-ingress-annotations) documentation.
### 2. Create Namespace
**Create a namespace** for the Appcircle server deployment. In this documentation, we will use `appcircle` as the example namespace.
```bash
kubectl create namespace appcircle
```
### 3. Create Container Registry Secret
By default, Appcircle uses its own image registry, which requires authentication with the `cred.json` file provided by Appcircle.
If you are using your own container image registry to access Appcircle container images, you can either skip authentication if your registry doesn't require it or create a secret for your custom registry.
Follow the steps below to create the registry secret in the `appcircle` namespace for pods to successfully pull images:
:::info
If you are using your own container registry, follow the `Custom Registry` section below.
If your registry doesn't require authentication, you can skip this section.
:::
- Save the `cred.json` file.
- Create the container registry secret:
```bash
kubectl create secret docker-registry containerregistry \
-n appcircle \
--docker-server='europe-west1-docker.pkg.dev' \
--docker-username='_json_key' \
--docker-password="$(cat cred.json)"
```
:::tip
If the `HISTCONTROL` environment variable is set to `ignoreboth`, commands with a leading space character will not be stored in the shell history. This allows you to create secrets safely without storing sensitive information in the shell history.
:::
- Update the `server`, `username`, and `password` fields for your own custom registry and create the container registry secret:
```bash
kubectl create secret docker-registry containerregistry \
-n appcircle \
--docker-server='registry.spacetech.com' \
--docker-username='yourRegistryUsername' \
--docker-password='superSecretRegistryPassword'
```
See [External Image Registries](/self-hosted-appcircle/install-server/helm-chart/configuration/external-image-registry) page for more details.
## Installation
### 1. Create `values.yaml`
Below is a minimal `values.yaml` file that you should configure for your deployment.
**Please adjust these values** according to your environment requirements and **save your file**.
In the example values below, we used `spacetech` as an **example organization name**. You should **replace it** with your actual organization name or any other value you prefer.
:::caution
Please **review the comments for the `values.yaml`** below. If the values provided are incompatible, the installation may not complete successfully. Ensure that all configurations are correctly entered to avoid potential issues during the setup process.
:::
Click to view example `values.yaml` file.
```yaml
# Global configurations for Appcircle deployment
global:
urls:
# Main domain configuration - All Appcircle services will be subdomains of this domain
domainName: .appcircle.spacetech.com
# SMTP server configuration for sending emails (Authentication, Notifications, Testing Distribution)
mail:
smtp:
# SMTP server host
host: "smtp.spacetech.com"
# SMTP Server port, 587 typically used for StartTLS
port: "587"
# Email address that will be used as sender
from: "appcircle@yandex.com"
# SSL configuration - Set to 'true' if the SMTP server uses SSL/TLS protocol for secure communication, typically on port 465.
ssl: "false"
# StartTLS configuration - Set to 'true' if the SMTP server uses StartTLS protocol, typically on port 587.
tls: "true"
# SMTP authentication settings
auth: "true"
username: "appcircle-smtp-user"
password: "superSecretSmtpPassword"
# Authentication configuration
auth:
auth-keycloak:
# Initial admin user email for Appcircle server
initialUsername: "admin@spacetech.com"
```
Click to view example `values.yaml` file.
```yaml
# Global configurations for Appcircle deployment
global:
urls:
# Main domain configuration - All Appcircle services will be subdomains of this domain
domainName: .appcircle.spacetech.com
# Protocol to be used for connections
scheme: https
# SMTP server configuration for sending emails (Authentication, Notifications, Testing Distribution)
mail:
smtp:
# SMTP server host
host: smtp.spacetech.com
# SMTP Server port, 587 typically used for StartTLS
port: "587"
# Email address that will be used as sender
from: appcircle@spacetech.com
# SSL configuration - Set to 'true' if the SMTP server uses SSL/TLS protocol for secure communication, typically on port 465.
ssl: "false"
# StartTLS configuration - Set to 'true' if the SMTP server uses StartTLS protocol, typically on port 587.
tls: "true"
# SMTP authentication settings
auth: "true"
username: smtpUserName
# You can create a secret with the password or directly enter the password here.
password: superSecretSmtpPassword
# If the K8s cluster access the container images from a private container image registry, you can configure it here.
# Container Image Registry host for container images
imageRegistry: europe-west1-docker.pkg.dev
# Container Image Repository path between registry host and image name
imageRepositoryPath: appcircle/docker-registry
# Kubernetes Ingress controller class
ingressClassName: "nginx"
# SSL/TLS certificate configuration for HTTPS
# You can create a secret with the certificate and key or directly enter them here.
tlsWildcard:
# Public certificate - Fullchain including leaf (app), intermediate and root SSL certificates
cert: |
-----BEGIN CERTIFICATE-----
MIIFzTCCBLWgAwIBAgISBMLn5uQI6Wmzku14xXUbbIbmMA0GCSqGSIb3DQEBCwUA
...
SA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFBjCCAu6gAwIBAgIRAIp9PhPWLzDvI4a9KQdrNPgwDQYJKoZIhvcNAQELBQAw
...
uYkQ4omYCTX5ohy+knMjdOmdH9c7SpqEWBDC86fiNex+O0XOMEZSa8DA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
...
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Private key for the SSL certificate
key: |
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3wS87baGONXjr
...
oUcjMAu/mGJjtn9AS0S7rRa58Q==
-----END PRIVATE KEY-----
# Certificate Authority public key - Typically the bottom certificate of the fullchain SSL certificate
caCert: |
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
...
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Authentication configuration
auth:
auth-keycloak:
# Organization name for Appcircle server
organizationName: spacetech
# Initial admin user email for Appcircle server
initialUsername: "admin@example.com"
# Initial admin password - Should contain: min 6 chars, 1 lowercase, 1 uppercase, 1 number
# You can create a secret with the password or directly enter the password here
initialPassword: "superSecretAppcirclePassword1234"
# Internal Ingress controller configuration
ingress-nginx:
enabled: false
# Appcircle vault configuration
vault:
server:
image:
# Appcircle vault image repository path
repository: europe-west1-docker.pkg.dev/appcircle/docker-registry/appcircle-vault
cert-utils-operator:
image:
# Container image repository path for the cert-utils-operator
repository: europe-west1-docker.pkg.dev/appcircle/docker-registry/cert-utils-operator
kube_rbac_proxy:
image:
# Container image repository path for the kube-rbac-proxy
repository: europe-west1-docker.pkg.dev/appcircle/docker-registry/kube-rbac-proxy
# Web event Redis configuration
webeventredis:
# Enable TLS for Redis connections
tls:
enabled: true
# Ingress configuration for Redis
ingress:
enabled: true
tls: true
```
#### Production Readiness Configuration
If you are deploying the Appcircle server for a production environment, it is recommended that stateful applications, such as databases or object storage, be deployed outside the scope of the Appcircle server Helm chart.
For more information, you can check the [Production Readiness](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness) documentation.
:::caution
Starting from the server version `3.28.2`, SMTP settings can be configured and updated directly from the Appcircle Dashboard. This is the recommended approach for managing SMTP settings as it allows you to update the configuration at any time without requiring server reset. To use this method:
1. Exclude the `global.mail` part from the `values.yaml` file.
2. Configure SMTP settings on the Appcircle Dashboard after installation.
See the [email integration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) document for more information about the SMTP configuration.
See the [version history](/self-hosted-appcircle/install-server/helm-chart/upgrades#version-history) to find out the minimum required Helm chart version for the server.
:::
### 2. Remove Sensitive Information From `values.yaml`
**Remove sensitive information** such as Appcircle initial user password, SMTP password, SSL certificates, and other secrets from the `values.yaml` **for production environments**, by checking the [Sensitive Values](/self-hosted-appcircle/install-server/helm-chart/configuration/sensitive-configuration) documentation.
### 3. Add the Appcircle Helm Repository
**Add the Appcircle Helm repository** to the configuration of Helm:
```bash
helm repo add appcircle https://helm-package.appcircle.io && \
helm repo update
```
### 4. Install the Appcircle Server
**Run the following Helm command** to install the Appcircle server chart.
In this example, we deploy the Appcircle server to a single namespace, using **`appcircle`** as the **namespace** and **`appcircle-server`** as the Helm **release name**.
```bash
helm install appcircle-server appcircle/appcircle \
--timeout 1200s \
-n appcircle \
-f values.yaml
```
:::warning
If you need or want to change the release name, please note that it should be 18 characters or fewer.
:::
You can watch the Appcircle server installation with any Kubernetes monitoring tool. The installation process duration depends on factors such as network speed and the processing power of your Kubernetes nodes. Typically, the installation may take up to **10 to 15 minutes**.
To make sure that the Appcircle server is installed successfully, you can run the command below and wait to finish:
```bash
kubectl wait --for=condition=ready pod \
-l app.kubernetes.io/instance=appcircle-server \
-n appcircle --timeout 1200s && \
echo "Appcircle is ready to use. Happy building! "
```
## Post-installation Steps
### 1. Add DNS Records
List the Ingresses with `kubectl` to check the IP address of the Appcircle services domains.
```bash
kubectl get ingresses -n appcircle
```
According to the example output below, you need to configure your DNS as follows:
```bash
NAME CLASS HOSTS ADDRESS PORTS AGE
appcircle-apigateway nginx api.appcircle.spacetech.com,auth.appcircle.spacetech.com 10.45.140.78 80,443 24m
appcircle-distribution-testerweb nginx dist.appcircle.spacetech.com 10.45.140.78 80,443 24m
appcircle-resource nginx resource.appcircle.spacetech.com 10.45.140.78 80,443 24m
appcircle-store-web nginx *.store.appcircle.spacetech.com 10.45.140.78 80,443 24m
appcircle-web-app nginx my.appcircle.spacetech.com 10.45.140.78 80,443 24m
appcircle-web-event nginx hook.appcircle.spacetech.com 10.45.140.78 80,443 24m
appcircle-webeventredis nginx kvs.appcircle.spacetech.com 10.45.140.78 80,443 24m
```
1. **Create an A Record for the `api` domain:**
- `api.appcircle.spacetech.com` → **10.45.140.78**
2. **Create CNAME Records for the other domains:**
- `auth.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `dist.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `resource.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `*.store.appcircle.spacetech.com` → You can skip this domain and use a [Custom Enterprise App Store Domain](https://docs.appcircle.io/enterprise-app-store/portal-settings#store-domain).
- `my.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `hook.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `kvs.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
### 2. Login to the Appcircle Dashboard
Check the output of the `helm install` command to see login URL, initial username and command to get initial user password.
```bash
Self-Hosted Configuration:
- Initial Organization Id : 8c23e250-4aa8-4ef6-888b-9514695aa1c7
- Initial User : admin@spacetech.com
- Retrieve the initial user password by executing the following command:↴
kubectl get secret -n appcircle appcircle-server-auth-keycloak-passwords -ojsonpath='{.data.initialPassword}' | base64 --decode ; echo
You can access the application dashboard at:↴
https://my.appcircle.spacetech.com
Support:
For any issues or questions, please contact the system administrator or check the application documentation.
```
### 3. Connecting Runners
When you complete installation successfully by following above steps, you're ready for your first build. :tada:
But in order to run build pipelines, you need to install and connect self-hosted runners. We have dedicated section for installation and configuration of self-hosted runners.
Follow and apply related guidelines in [here](/self-hosted-appcircle/self-hosted-runner/installation).
Self-hosted runner section in docs, has all details about runners and their configuration.
:::::caution
By default, self-hosted runner package has pre-configured `ASPNETCORE_REDIS_STREAM_ENDPOINT` and `ASPNETCORE_BASE_API_URL` for Appcircle-hosted cloud.
- `webeventredis.appcircle.io:6379,ssl=true`
- `https://api.appcircle.io/build/v1`
:point_up: You need to change these values with your self-hosted Appcircle server's Redis and API URL.
Assuming our sample scenario explained above, these values should be:
- `kvs.appcircle.spacetech.com:6379,ssl=false`
- `http://api.appcircle.spacetech.com/build/v1`
for our example configuration.
:::info
If your Appcircle server is running with `HTTPS`, then Redis and API URL should be like this:
- `kvs.appcircle.spacetech.com:443,ssl=true`
- `https://api.appcircle.spacetech.com/build/v1`
:::
:reminder_ribbon: After [download](/self-hosted-appcircle/self-hosted-runner/installation#1-download), open `appsettings.json` with a text editor and change the `ASPNETCORE_REDIS_STREAM_ENDPOINT` and the `ASPNETCORE_BASE_API_URL` values according to your configuration.
Please note that, you should do this before [register](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
:::::
Considering system performance, it will be good to install self-hosted runners to other machines. Self-hosted Appcircle server should run on a dedicated machine itself.
You can install any number of runners regarding to your needs and connect them to self-hosted Appcircle server.
### 4. Apply the Appcircle License
When you deploy the Appcircle server using Helm, a default license is provided. You can explore the Appcircle with the default license.
To obtain the license you purchased, please share the initial organization ID, which is printed after the `helm` deployment command, with the Appcircle team and follow the detailed instructions available in the [Appcircle License Update](/self-hosted-appcircle/install-server/helm-chart/configuration/license-configuration) section.
---
## OpenShift
## Overview
This guide offers a comprehensive overview of installing the Appcircle chart. While the provided **default values** are suitable **for initial trials**, they are not recommended for production environments.
**For production deployments**, it is essential to **review the detailed descriptions** and **optional sections** to ensure a secure and reliable setup. **This document supports both trial and production installations**.
## Prerequisites
To complete this guide, you must have the following:
### 1. Domain Name
A main **domain name**, which will have **subdomains**, is **required** for the Appcircle server.
:::note
In this documentation, we will use `appcircle.spacetech.com` as an **example main domain** and `spacetech` as an **example organization name**.
:::
Click to view more details about domain name prerequisite.
By default, Appcircle uses seven subdomains. These subdomains are:
1. api.appcircle.spacetech.com
2. auth.appcircle.spacetech.com
3. dist.appcircle.spacetech.com
4. hook.appcircle.spacetech.com
5. resource.appcircle.spacetech.com
6. my.appcircle.spacetech.com
7. kvs.appcircle.spacetech.com
**Upon completing the deployment** of the Appcircle server, you will need to create DNS records based on the routes created in OpenShift.
### 2. SSL Certificate
An **SSL certificate** is **required** to deploy the Appcircle server for **production** environments.
You **can skip** SSL certificate if you are deploying Appcircle server **for trial purposes**.
Click to view more details about SSL certificate prerequisite.
- The SSL certificate private key shouldn't be password protected.
- The SSL certificate should be in PEM format.
- Ensure the **one certificate** covers **all the subdomains** in the [domain name](#1-domain-name) section.
- Make sure to configure the Appcircle server with a **fullchain certificate**, which should include the leaf (or app) certificate, intermediate certificates, and the root certificate.
:::tip
You can use a **wildcard certificate** to cover all the subdomains, simplifying the certificate management process. For example, a wildcard certificate for **`*.appcircle.spacetech.com`** will be enough.
:::
:::caution
If you use a domain like `appcircle.spacetech.com`, it will have **two levels of subdomains**. Ensure that both your DNS provider and SSL certificate provider support multi-level subdomains for proper configuration.
:::
### 3. OpenShift Cluster
A **OpenShift cluster** is **required** to install the Appcircle server using Helm.
**Minimum hardware requirements for enterprise installation:**
- Node(s) with `x86_64` architecture
- 8 CPUs
- 32 GB RAM
- 100 GB Disk per node
:::tip
The required storage size for the Appcircle server depends significantly on the size of the artifacts (APK, IPA, cache).
:::
Click to view more details about OpenShift cluster prerequisite.
**Recommended hardware requirements for enterprise installation:**
- Nodes with `x86_64` architecture
- 32 CPUs
- 64 GB RAM
- 1 TB Disk
For production environments, if you deploy stateful applications with the Appcircle Helm chart, you will need significant storage capacity, as specified above. You can configure disk resource allocations through Helm values according to your needs.
However, if you opt to use external services for components such as PostgreSQL or MinIO, the storage requirements for the cluster are significantly reduced to around 50GB. It is **highly recommended** to deploy stateful apps outside of the Appcircle Helm chart configuration.
:::tip
For stateful apps that should deployed out of scope this helm chart, you can check the [Production Readiness](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness) document.
For storage details, you can check the [Storage Class Configuration](/self-hosted-appcircle/install-server/helm-chart/configuration/storage-configuration) section.
:::
:::info
Using SSD storage is highly recommended if stateful applications are installed within the Appcircle Helm chart scope. SSDs provide faster read/write speeds, improving the performance and responsiveness of your applications.
:::
Additionally, ensure that your OpenShift cluster is running version 4.12 or later to maintain compatibility and support.
### 1. `oc`
The **`oc`** OpenShift CLI is **required**.
### 2. Helm v3
**Helm version `3.11.0`** or later is **required**.
## Pre-installation Steps
### 1. Configure `oc` CLI
Log in to your OpenShift cluster using the `oc` CLI. If you are already logged in and have set the correct project, you may skip this step.
```bash
oc login -u ${username} ${OPENSHIFT_API_URL}
```
### 2. Create Project
**Create a project** for the Appcircle server deployment. In this documentation, we will use `appcircle` as the example project.
```bash
oc new-project appcircle
```
### 3. Create Container Registry Secret
By default, Appcircle uses its own image registry, which requires authentication with the `cred.json` file provided by Appcircle.
If you are using your own container image registry to access Appcircle container images, you can either skip authentication if your registry doesn't require it or create a secret for your custom registry.
Follow the steps below to create the registry secret in the `appcircle` project for pods to successfully pull images:
:::info
If you are using your own container registry, follow the `Custom Registry` section below.
If your registry doesn't require authentication, you can skip this section.
:::
- Save the `cred.json` file.
- Create the container registry secret:
```bash
oc create secret docker-registry containerregistry \
-n appcircle \
--docker-server='europe-west1-docker.pkg.dev' \
--docker-username='_json_key' \
--docker-password="$(cat cred.json)"
```
:::tip
If the `HISTCONTROL` environment variable is set to `ignoreboth`, commands with a leading space character will not be stored in the shell history. This allows you to create secrets safely without storing sensitive information in the shell history.
:::
- Update the `server`, `username`, and `password` fields for your own custom registry and create the container registry secret:
```bash
oc create secret docker-registry containerregistry \
-n appcircle \
--docker-server='registry.spacetech.com' \
--docker-username='yourRegistryUsername' \
--docker-password='superSecretRegistryPassword'
```
See [External Image Registries](/self-hosted-appcircle/install-server/helm-chart/configuration/external-image-registry) page for more details.
## Installation
### 1. Create `values.yaml`
Below is a minimal `values.yaml` file that you should configure for your deployment.
**Please adjust these values** according to your environment requirements and **save your file**.
In the example values below, we used `spacetech` as an **example organization name**. You should **replace it** with your actual organization name or any other value you prefer.
:::caution
Please **review the comments for the `values.yaml`** below. If the values provided are incompatible, the installation may not complete successfully. Ensure that all configurations are correctly entered to avoid potential issues during the setup process.
:::
Click to view example `values.yaml` file.
```yaml
# Global configurations for Appcircle deployment
global:
# OpenShift
openshift: true
urls:
# Main domain configuration - All Appcircle services will be subdomains of this domain
domainName: .appcircle.spacetech.com
# SMTP server configuration for sending emails (Authentication, Notifications, Testing Distribution)
mail:
smtp:
# SMTP server host
host: "smtp.spacetech.com"
# SMTP Server port, 587 typically used for StartTLS
port: "587"
# Email address that will be used as sender
from: "appcircle@spacetech.com"
# SSL configuration - Set to 'true' if the SMTP server uses SSL/TLS protocol for secure communication, typically on port 465.
ssl: "false"
# StartTLS configuration - Set to 'true' if the SMTP server uses StartTLS protocol, typically on port 587.
tls: "true"
# SMTP authentication settings
auth: "true"
username: "appcircle-smtp-user"
password: "superSecretSmtpPassword"
# Authentication configuration
auth:
auth-keycloak:
# Initial admin user email for Appcircle server
initialUsername: "admin@spacetech.com"
# Internal Ingress controller configuration
ingress-nginx:
enabled: false
```
Click to view example `values.yaml` file.
```yaml
# Global configurations for Appcircle deployment
global:
# OpenShift
openshift: true
urls:
# Main domain configuration - All Appcircle services will be subdomains of this domain
domainName: .appcircle.spacetech.com
# Protocol to be used for connections
scheme: https
# SMTP server configuration for sending emails (Authentication, Notifications, Testing Distribution)
mail:
smtp:
# SMTP server host
host: "smtp.spacetech.com"
# SMTP Server port, 587 typically used for StartTLS
port: "587"
# Email address that will be used as sender
from: "appcircle@spacetech.com"
# SSL configuration - Set to 'true' if the SMTP server uses SSL/TLS protocol for secure communication, typically on port 465.
ssl: "false"
# StartTLS configuration - Set to 'true' if the SMTP server uses StartTLS protocol, typically on port 587.
tls: "true"
# SMTP authentication settings
auth: "true"
username: "smtpUserName"
# You can create a secret with the password or directly enter the password here.
password: "superSecretSmtpPassword"
# If the K8s cluster access the container images from a private container image registry, you can configure it here.
# Container Image Registry host for container images
imageRegistry: europe-west1-docker.pkg.dev
# Container Image Repository path between registry host and image name
imageRepositoryPath: appcircle/docker-registry
# SSL/TLS certificate configuration for HTTPS
# You can create a secret with the certificate and key or directly enter them here.
tlsWildcard:
# Public certificate - Fullchain including leaf (app), intermediate and root SSL certificates
cert: |
-----BEGIN CERTIFICATE-----
MIIFzTCCBLWgAwIBAgISBMLn5uQI6Wmzku14xXUbbIbmMA0GCSqGSIb3DQEBCwUA
...
SA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFBjCCAu6gAwIBAgIRAIp9PhPWLzDvI4a9KQdrNPgwDQYJKoZIhvcNAQELBQAw
...
uYkQ4omYCTX5ohy+knMjdOmdH9c7SpqEWBDC86fiNex+O0XOMEZSa8DA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
...
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Private key for the SSL certificate
key: |
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3wS87baGONXjr
...
oUcjMAu/mGJjtn9AS0S7rRa58Q==
-----END PRIVATE KEY-----
# Certificate Authority public key - Typically the bottom certificate of the fullchain SSL certificate
caCert: |
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
...
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Authentication configuration
auth:
auth-keycloak:
# Organization name for Appcircle server
organizationName: spacetech
# Initial admin user email for Appcircle server
initialUsername: "admin@example.com"
# Initial admin password - Should contain: min 6 chars, 1 lowercase, 1 uppercase, 1 number
# You can create a secret with the password or directly enter the password here
initialPassword: "superSecretAppcirclePassword1234"
# Internal Ingress controller configuration
ingress-nginx:
enabled: false
# Appcircle vault configuration
vault:
server:
image:
# Appcircle vault image repository path
repository: europe-west1-docker.pkg.dev/appcircle/docker-registry/appcircle-vault
cert-utils-operator:
image:
# Container image repository path for the cert-utils-operator
repository: europe-west1-docker.pkg.dev/appcircle/docker-registry/cert-utils-operator
kube_rbac_proxy:
image:
# Container image repository path for the kube-rbac-proxy
repository: europe-west1-docker.pkg.dev/appcircle/docker-registry/kube-rbac-proxy
# Web event Redis configuration
webeventredis:
# Enable TLS for Redis connections
tls:
enabled: true
```
#### Production Readiness Configuration
If you are deploying the Appcircle server for a production environment, it is recommended that stateful applications, such as databases or object storage, be deployed outside the scope of the Appcircle server Helm chart.
For more information, you can check the [Production Readiness](/self-hosted-appcircle/install-server/helm-chart/configuration/production-readiness) documentation.
:::caution
Starting from the server version `3.28.2`, SMTP settings can be configured and updated directly from the Appcircle Dashboard. This is the recommended approach for managing SMTP settings as it allows you to update the configuration at any time without requiring server reset. To use this method:
1. Exclude the `global.mail` part from the `values.yaml` file.
2. Configure SMTP settings on the Appcircle Dashboard after installation.
See the [email integration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) document for more information about the SMTP configuration.
See the [version history](/self-hosted-appcircle/install-server/helm-chart/upgrades#version-history) to find out the minimum required Helm chart version for the server.
:::
### 2. Remove Sensitive Information From `values.yaml`
**Remove sensitive information** such as Appcircle initial user password, SMTP password, SSL certificates, and other secrets from the `values.yaml` **for production environments**, by checking the [Sensitive Values](/self-hosted-appcircle/install-server/helm-chart/configuration/sensitive-configuration) documentation.
### 3. Add the Appcircle Helm Repository
**Add the Appcircle Helm repository** to the configuration of Helm:
```bash
helm repo add appcircle https://helm-package.appcircle.io && \
helm repo update
```
### 4. Install the Appcircle Server
**Run the following Helm command** to install the Appcircle server chart.
In this example, we deploy the Appcircle server to a single project, using **`appcircle`** as the **project name** and **`appcircle-server`** as the Helm **release name**.
```bash
helm install appcircle-server appcircle/appcircle \
--timeout 1200s \
-n appcircle \
-f values.yaml
```
:::warning
If you need or want to change the release name, please note that it should be 18 characters or fewer.
:::
You can watch the Appcircle server installation with any OpenShift monitoring tool. The installation process duration depends on factors such as network speed and the processing power of your cluster nodes. Typically, the installation may take up to **10 to 15 minutes**.
To make sure that the Appcircle server is installed successfully, you can run the command below and wait to finish:
```bash
oc wait --for=condition=ready pod \
-l app.kubernetes.io/instance=appcircle-server \
-n appcircle --timeout 1200s && \
echo "Appcircle is ready to use. Happy building! "
```
## Post-installation Steps
### 1. Add DNS Records
List the services with `oc` to check the IP address of the OpenShift default router
```bash
oc get svc -n openshift-ingress
```
According to the example output below, you need to configure your DNS as follows:
```bash
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
router-default LoadBalancer 10.217.4.108 10.45.140.78 80/TCP,443/TCP,1936/TCP 44d
```
1. **Create an A Record for the `api` domain:**
- `api.appcircle.spacetech.com` → **10.45.140.78**
2. **Create CNAME Records for the other domains:**
- `auth.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `dist.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `resource.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `*.store.appcircle.spacetech.com` → You can skip this domain and use a [Custom Enterprise App Store Domain](https://docs.appcircle.io/enterprise-app-store/portal-settings#store-domain).
- `my.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `hook.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
- `kvs.appcircle.spacetech.com` → **api.appcircle.spacetech.com**
### 2. Login to the Appcircle Dashboard
Check the output of the `helm install` command to see login URL, initial username and command to get initial user password.
```bash
Self-Hosted Configuration:
- Initial Organization Id : 8c23e250-4aa8-4ef6-888b-9514695aa1c7
- Initial User : admin@spacetech.com
- Retrieve the initial user password by executing the following command:↴
oc get secret -n appcircle appcircle-server-auth-keycloak-passwords -ojsonpath='{.data.initialPassword}' | base64 --decode ; echo
You can access the application dashboard at:↴
https://my.appcircle.spacetech.com
Support:
For any issues or questions, please contact the system administrator or check the application documentation.
```
### 3. Connecting Runners
When you complete installation successfully by following above steps, you're ready for your first build. :tada:
But in order to run build pipelines, you need to install and connect self-hosted runners. We have dedicated section for installation and configuration of self-hosted runners.
Follow and apply related guidelines in [here](/self-hosted-appcircle/self-hosted-runner/installation).
Self-hosted runner section in docs, has all details about runners and their configuration.
:::::caution
By default, self-hosted runner package has pre-configured `ASPNETCORE_REDIS_STREAM_ENDPOINT` and `ASPNETCORE_BASE_API_URL` for Appcircle-hosted cloud.
- `webeventredis.appcircle.io:6379,ssl=true`
- `https://api.appcircle.io/build/v1`
:point_up: You need to change these values with your self-hosted Appcircle server's Redis and API URL.
Assuming our sample scenario explained above, these values should be:
- `kvs.appcircle.spacetech.com:6379,ssl=false`
- `http://api.appcircle.spacetech.com/build/v1`
for our example configuration.
:::info
If your Appcircle server is running with `HTTPS`, then Redis and API URL should be like this:
- `kvs.appcircle.spacetech.com:443,ssl=true`
- `https://api.appcircle.spacetech.com/build/v1`
:::
:reminder_ribbon: After [download](/self-hosted-appcircle/self-hosted-runner/installation#1-download), open `appsettings.json` with a text editor and change the `ASPNETCORE_REDIS_STREAM_ENDPOINT` and the `ASPNETCORE_BASE_API_URL` values according to your configuration.
Please note that, you should do this before [register](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
:::::
Considering system performance, it will be good to install self-hosted runners to other machines. Self-hosted Appcircle server should run on a dedicated machine itself.
You can install any number of runners regarding to your needs and connect them to self-hosted Appcircle server.
### 4. Apply the Appcircle License
When you deploy the Appcircle server using Helm, a default license is provided. You can explore the Appcircle with the default license.
To obtain the license you purchased, please share the initial organization ID, which is printed after the `helm` deployment command, with the Appcircle team and follow the detailed instructions available in the [Appcircle License Update](/self-hosted-appcircle/install-server/helm-chart/configuration/license-configuration) section.
---
## Uninstallation
If you want to uninstall the Appcircle server, you can just remove the Helm release from the Kubernetes cluster.
If you haven't changed the release name and namespace name while following the [Deploy Using Helm](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes#4-install-the-appcircle-server) section, you can run the command below to uninstall the Appcircle server.
```bash
helm uninstall -n appcircle appcircle-server
```
Helm uninstall doesn't delete the Appcircle server data stored in the persistent volumes. If you want to delete all the data of the Appcircle server, you can simply delete the namespace.
If you haven't changed the namespace name while following the [Deploy Using Helm](/self-hosted-appcircle/install-server/helm-chart/installation/kubernetes#4-install-the-appcircle-server) section, you can run the command below to delete all data of the Appcircle server.
```bash
kubectl delete namespace appcircle
```
---
## Upgrades
To **upgrade** the Appcircle server to the **latest** version and apply any configuration changes, you can follow the sections below.
## Updating to the Latest Version
To update the Appcircle server to the latest version, follow these steps:
1. Check the installed Helm chart and Appcircle server version.
```bash
helm list -n appcircle
```
2. Update the Appcircle Helm chart repository.
```bash
helm repo update
```
3. Update the Appcircle server
```bash
helm upgrade appcircle-server appcircle/appcircle \
--timeout 1200s \
-n appcircle \
-f values.yaml
```
By following these steps, you can ensure that your Appcircle server is updated to the latest version with all the latest features.
## Version History
Below is the version history of the self-hosted Appcircle server and the Helm chart. This table helps you track the latest updates and releases since your current version.
:::tip
To keep the below table brief, we are adding only versions for Helm chart upgrades along with the bundled Appcircle server version.
You can also check Docker/Podman architecture [version history](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/update#version-history) to see all released self-hosted versions.
:::
Click to view version history.
Since the cloud and self-hosted versions are released asynchronously, the release dates listed in the table may differ from those on the **[Release Notes](https://docs.appcircle.io/release-notes)** page.
| Appcircle Server Version | Helm Chart Version | Release Date |
| ------------------------ | ------------------ | ------------ |
| 3.27.3 | 0.3.20 | 28/07/2025 |
| 3.27.3 | 0.3.19 | 28/05/2025 |
| 3.25.1 | 0.2.8 | 05/02/2025 |
| 3.23.2 | 0.1.1 | 23/12/2024 |
| 3.23.2 | 0.1.0 | 20/12/2024 |
## Updating to a Specific Version
You can specify a **specific version** of the Appcircle Helm chart by adding the `--version` flag to the Helm upgrade command.
For instance, to upgrade the **Appcircle Helm chart** to a **specific version** and view the Appcircle server Helm chart versions that are available:
**1.** Check the list of available versions.
```bash
helm search repo appcircle/appcircle -l
```
The output should look like the following:
```txt
NAME CHART VERSION APP VERSION DESCRIPTION
appcircle/appcircle 0.3.19 3.27.3 Official Appcircle Chart | Enterprise-Grade Ful...
appcircle/appcircle 0.2.8 3.25.1 A Helm chart for Kubernetes
appcircle/appcircle 0.1.1 3.23.2 A Helm chart for Kubernetes
appcircle/appcircle 0.1.0 3.23.2 A Helm chart for Kubernetes
```
:::caution
### OpenShift Support
`0.2.x` and older versions are deprecated. They are not getting maintenance updates, and they do not support [OpenShift](/self-hosted-appcircle/install-server/helm-chart/installation/openshift) installation.
We strongly recommend you use `0.3.x` or later versions, which are actively maintained and have new features like supporting installation on [OpenShift](/self-hosted-appcircle/install-server/helm-chart/installation/openshift).
:::
**2.** Update the Appcircle Helm chart to a specific version.
```bash
helm upgrade appcircle-server appcircle/appcircle \
--version 0.2.8 \
--timeout 1200s \
-n appcircle \
-f values.yaml
```
By following these steps, you can upgrade your Appcircle server to a specific version of the Helm chart.
### Why is my Helm chart not updating to the latest version?
If your Helm chart is not updating to the latest version, it could be due to several reasons such as an outdated repository, local cache issues, or network problems. Follow the steps below to troubleshoot and resolve the issue:
1. **Update the Helm Repository:** Make sure your Helm repository is up to date by running the following command:
```sh
helm repo update
```
2. **Clear the Local Cache:** Sometimes, clearing the local cache can help in fetching the latest charts.
- For Linux, delete `$HOME/.cache/helm` directory.
```sh
rm -rf "$HOME/.cache/helm"
```
- For MacOS, delete `$HOME/Library/Caches/helm` directory.
```sh
rm -rf "$HOME/Library/Caches/helm"
```
- For Windows, delete `%TEMP%\helm` folder.
3. **Re-add the Repository:** If the update doesn't resolve the issue, try removing and re-adding the repository:
```sh
helm repo remove appcircle
helm repo add appcircle https://helm-package.appcircle.io
helm repo update
```
4. **Verify the Index:** After updating, you can check the repository index to ensure that the latest version is available.
```sh
curl -fsSL https://helm-package.appcircle.io/index.yaml | grep -A 5 'appcircle'
```
5. **Check for Errors:** Ensure there are no issues with your internet connection or any firewall rules that might be blocking the update.
---
## Server Setup
Setting up the server involves deploying the application using containerized environments. The recommended methods for deployment include Docker/Podman and Helm Chart. Each method provides flexibility in managing application instances, scaling, and configurations based on the infrastructure requirements.
Current headlines are listed below:
- [Docker/Podman](/self-hosted-appcircle/install-server/linux-package)
- [Helm Chart](/self-hosted-appcircle/install-server/helm-chart)
In order to see the details, check the submenu of this documentation page.
---
## Command-Line Interface (CLI) Configuration
Appcircle CLI is a command-line interface designed to use Appcircle from the terminals. The Appcircle CLI tool, which is executed directly from the terminal, provides users with a streamlined command-driven experience for efficient management of Appcircle.
The Appcircle CLI is user-friendly and versatile, offering a range of commands to enhance backend control. You can start builds, download build artifacts, publish applications on the Enterprise App Store, and do more.
Additionally, its scriptable nature allows for easy automation through shell scripts, enabling users to automate tasks and integrate the CLI into existing workflows effortlessly.
For detailed usage, you can head over to the [Appcircle CLI](https://github.com/appcircleio/appcircle-cli#appcircle-command-line-interface) documentation.
## Pre-Requirements
To configure Appcircle CLI to use your self-hosted Appcircle, you need a **Personal Access Key** for authentication. Also, you need the `api` and the `auth` URLs of the Appcircle server.
### 1. Create a Personal Access Key
For the Appcircle CLI to authenticate to your self-hosted Appcircle, you need to create a **Personal Access Key** and configure the Appcircle CLI to use it.
You can follow the [Generating and Managing Personal Access Keys](/account/my-organization/security/personal-access-key) page to create one.
### 2. Find out the Appcircle server URLs
To find these URLs, you have two ways.
1. Change the subdomain of an Appcircle URL and test if it is working.
2. Get the URLs from the Appcircle server configuration.
#### Change the subdomain with `api` and `auth` for the default configuration
To find out the `api` and the `auth` URL, you can check the URL that you are using to access the Appcircle web UI (dashboard) and then change its subdomain according to the format.
For example, if you are using `https://my.appcircle.spacetech.com` to access the Appcircle web UI,
- Change `my` to `api` for the **API_HOSTNAME**.
- It should be `https://api.appcircle.spacetech.com`.
- Change `my` to `auth` for the **AUTH_HOSTNAME**.
- It should be `https://auth.appcircle.spacetech.com`.
You can test the **API** URL access by running the command below.
```bash
curl -v https://api.appcircle.spacetech.com
```
If you are facing a connectivity error, there are two possible problems:
1. There is no network access between the computer that runs the `curl` command above and the Appcircle server.
2. Or the **API** URL is not correct. In order to get the correct URL, you can follow the title below.
#### Get the subdomains from the Appcircle server for any type of configuration
To get the `api` and the `auth` URL, you should login to the Appcircle server and follow the steps below:
- Change the directory on the Appcircle server.
```bash
cd appcircle-server
```
- Update the environment variable `PATH` with the required dependencies.
```bash
export PATH=$PATH:$(pwd)/deps/bin
```
- Get the `api` and `auth` URL from the configuration file of your project.
:::info
`spacetech` in the example below is an example project name.
To find out your projects, list the content of the `./projects` directory.
```bash
ls -l ./projects
```
:::
```bash
yq '.apiGateway.external.url' ./projects/spacetech/export/.global.yaml && \
yq '.keycloak.external.url' ./projects/spacetech/export/.global.yaml
```
You can test the **API** URL access by running the command below.
```bash
curl -v https://api.appcircle.spacetech.com
```
If you are still getting a connectivity error, you should check the network access between the host that runs `curl` and the Appcircle server.
## Configure CLI to Use Your Self-Hosted Server
By default, Appcircle CLI is configured to interact with the Appcircle cloud. But with a few commands, you can change this behavior and use your own self-hosted Appcircle server with the CLI.
:::info
We are assuming that you have already installed the Appcircle CLI and that it is ready to use.
Follow the installation instructions [here](https://github.com/appcircleio/appcircle-cli?tab=readme-ov-file#installation) to install Appcircle CLI if it's not ready to use.
To test, you can open a terminal and run the command below in your terminal.
```bash
appcircle --version
```
If you see the Appcircle CLI version without any errors, you are ready to configure the tool.
:::
To configure the Appcircle CLI to use with the self-hosted Appcircle server follow the steps below.
**1.** Add a new configuration with any desired name.
```bash
appcircle config add "${CONFIGURATION_NAME}"
```
For example;
```bash
appcircle config add "spacetech"
```
**2.** Set the [required URLs](#2-find-out-the-appcircle-server-urls) to communicate with the self-hosted Appcircle server.
```bash
appcircle config set API_HOSTNAME 'https://api.appcircle.spacetech.com'
```
```bash
appcircle config set AUTH_HOSTNAME 'https://auth.appcircle.spacetech.com'
```
**3.** Set the [Personal Access Key](#1-create-a-personal-access-key) for authentication on the server.
```bash
appcircle login personal-access-key --secret "${PERSONAL_ACCESS_KEY}"
```
For example;
```bash
appcircle login personal-access-key --secret "TTk0...RhNw=="
```
:::warning Personal API Token Renamed
The Personal Access Key was previously referred to as the Personal API Token. The old login method is still available, but it is recommended to migrate to the new version.
For reference, the old login method was:
```bash
appcircle login --pat "${PERSONAL_API_TOKEN}"
```
:::
:::caution
If you face any self-signed certificate error, for example, "self-signed certificate in certificate chain", check the [Trusting Certificate](#trusting-the-ssl-certificate-recommended) section for troubleshooting.
:::
You can check the configuration with the command below.
```bash
appcircle config list
```
You should see the current (active) configuration, the path of the `config.json` file, and server URLs per configuration.
You can also configure the Appcircle CLI in interactive mode.
```bash
appcircle -i
```
You should use the relevant menu item and follow the instructions there that are similar to the steps above.
When you successfully log in with the Appcircle CLI, you can list the build profiles with the command below.
```bash
appcircle listBuildProfiles
```
For detailed usage information about the Appcircle CLI, you can refer to the [Appcircle CLI](https://github.com/appcircleio/appcircle-cli#appcircle-command-line-interface) documentation.
## Self-Signed Certificates
If you are using a self-signed SSL certificate on the self-hosted Appcircle server and the certificate is not trusted on your host, you may face an error like below while trying to run the Appcircle CLI tool.
```bash
$ appcircle login --pat "TTk0...RhNw=="
self-signed certificate in certificate chain undefined
```
That error occurs when the root CA certificate or the self-signed certificate of the Appcircle server is not trusted on your host.
You can trust the SSL certificate of the Appcircle server to secure the network between the CLI and the server, or you can disable certificate verification.
:::danger
Disabling certificate verification is risky and not recommended.
For secure and reliable communication, you should trust the SSL certificate.
:::
### Trusting the SSL Certificate (recommended)
You can trust the SSL certificate of the Appcircle server with the Appcircle CLI tool itself to make sure all the requests are secured and trusted.
You should already have [configured](#configure-cli-to-use-your-self-hosted-server) the Appcircle CLI tool for the self-hosted Appcircle server.
:::info
This command is supported on **MacOS** and **Linux** operating systems only.
If you are a **Windows** user, you can download the SSL certificate and make it trusted under the `MMC` menu in Windows.
:::
:::caution
Trusting the SSL certificate is supported for Appcircle CLI version `1.1.1` or later.
For older versions, you should upgrade the Appcircle CLI, or although it's not recommended, you can [disable the SSL verification](#disabling-the-ssl-certificate-verification-not-recommended).
:::
To trust the SSL certificate of the configured Appcircle server, run the `config trust` subcommand of the Appcircle CLI.
```bash
appcircle config trust
```
:::info
The command may ask for the `sudo` password for some system-wide operations. You should be sudoer.
:::
When the script successfully trusts the certificate, you will see an output like below.
```bash
[+] OS: Darwin
Appcircle URL is valid: https://api.appcircle.spacetech.com
[-] Allowing addition of root certificates
[-] Getting root certificate of 'api.appcircle.spacetech.com'
Found cert that has same subject and issuer
[+] Certificate written to 'api.appcircle.spacetech.com.crt'
[+] Subject: Crtforge ROOT CA, emailAddress=contact@spacetech.com
[+] Expires on: Jan 31 10:12:39 2044 GMT
[-] Adding 'api.appcircle.spacetech.com.crt' to Keychain
Password:
YES (0)
YES (0)
[-] Adding Certs to Nodejs
The line already exists in /Users/spacetech/.zshrc
[-] Verifying connection to 'api.appcircle.spacetech.com'
[+] Verification successful!
The root cert has been trusted successfully.
You must open a new terminal session for the changes to take effect.
```
Now you should open a new terminal for the changes to take effect.
In a new terminal session, you can run the `appcircle` commands securely without any certificate problems.
### Disabling the SSL Certificate Verification (not-recommended)
Disabling SSL certificate verification removes a critical layer of security, leaving the communication vulnerable to a variety of threats, including those associated with man-in-the-middle attacks, data integrity issues, and trustworthiness concerns.
Proper SSL certificate validation is essential for ensuring the authenticity and security of the communication between the Appcircle CLI and the Appcircle server.
It's crucial to prioritize security measures to protect sensitive data and maintain the integrity of your system.
:::danger
While we do not recommend it, you have the choice to accept the mentioned risk by selectively disabling certificate verification specifically for the Appcircle CLI.
It can be used when you have problems [trusting the SSL certificates](#trusting-the-ssl-certificate-recommended).
:::
To disable the SSL certificate verification just for the Appcircle CLI tool, you should add a prefix to the `appcircle` command.
:::info
SSL and TLS are the same concepts for this document. So, TLS certificates are also known as SSL certificates.
:::
```bash
alias appcircle="NODE_TLS_REJECT_UNAUTHORIZED=0 appcircle"
```
After disabling SSL certificate verification, there will be a warning saying SSL verification is disabled.
```bash
$ appcircle listBuildProfiles
(node:74065) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
...
```
You can ignore it. All the subcommands will work as they should.
---
## Cache Size Configuration
Appcircle has a limit for cache sizes that can be pushed or pulled on the build workflows.
The `maxBodySize` parameter in the `global.yaml` file allows you to configure the maximum cache file size that can be uploaded with the [Cache Push](/workflows/common-workflow-steps/#cache-push) component.
By default, the cache size is set to **4096m**. However, you can increase or decrease this limit according to your needs by modifying the `global.yaml` file.
## Configuring the Appcircle Server
We are assuming that you have installed the Appcircle server with version `3.10.0` or later.
To configure the `maxBodySize` parameter, you can follow the steps below:
- Log in to Appcircle server with SSH or remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Find the `nginx` entry, add or edit the key named `maxBodySize`, and set it to the desired value.
```yaml
nginx:
maxBodySize: 5120m
```
If your `global.yaml` file does not have the `nginx` key, you can add it yourself.
Replace `5120m` with the desired maximum cache size according to your needs. The size should be specified in megabytes (m).
:::caution
Larger cache sizes require more disk space on the Appcircle server. So be cautious about allowing large cache sizes in your installation.
:::
Once your server is up and healthy, you can run the build that requires pushing a cache file larger than 4096m but less than 5120m.
You can also reduce the default `maxBodySize` for security purposes.
---
## Configure Container Engine Network Subnet
## Overview
This document explains how to configure your Appcircle server's and Appcircle DMZ server's network subnet of the containers if the existing subnet is conflicting with other networks or not suitable for your use case.
:::info
This feature is included in the Appcircle server package version **`3.28.2` or later**.
:::
## Configuring the Subnet for Appcircle Server
To configure the network subnet of the containers of the Appcircle server, follow these steps:
1. Log in to your Appcircle server via SSH or a remote connection.
2. Change to the directory containing the Appcircle server configuration.
```bash
cd appcircle-server
```
3. Open the `global.yaml` file in a text editor.
```bash
vi ./projects/spacetech/global.yaml
```
4. Create or update the `networkSettings` entry in the `global.yaml` configuration file.
:::caution
If the `networkSettings` entry already exists in your `global.yaml` file, ensure you update the existing key instead of creating a new one.
:::
```yaml
networkSettings:
enabled: true
networkSubnet: 10.0.0.0/16
```
:::tip
The `networkSubnet` will be used to configure the network subnet of the Appcircle server containers.
:::
5. After saving the configuration changes, restart your Appcircle server to apply the new settings.
## Configuring the Subnet for Appcircle DMZ Server
To configure the network subnet of the containers of the DMZ server, follow these steps:
1. Log in to your Appcircle server via SSH or a remote connection.
2. Change to the directory containing the Appcircle server configuration.
```bash
cd appcircle-server
```
3. Open the `global.yaml` file in a text editor.
```bash
vi ./projects/spacetech/global.yaml
```
4. Create or update the `dmzNetworkSettings` entry in the `global.yaml` configuration file.
:::caution
If the `dmzNetworkSettings` entry already exists in your `global.yaml` file, ensure you update the existing key instead of creating a new one.
:::
```yaml
dmzNetworkSettings:
enabled: true
networkSubnet: 10.0.0.0/16
```
:::tip
The `networkSubnet` will be used to configure the network subnet of the Appcircle DMZ server containers.
:::
:::info
Although the Appcircle server and Appcircle DMZ server have the same subnet configuration as the sample above, they are not required to have the same subnet values or to be configured to custom subnet both.
:::
5. Apply the new configuration changes.
```bash
./ac-self-hosted.sh -n spacetech export --dmz
```
6. Compress the Appcircle DMZ server directory into a tarball.
```bash
tar -czf dmz.tar.gz -C projects/spacetech/export/dmz/ .
```
7. Transfer the `dmz.tar.gz` file to the Appcircle DMZ server with a file transfer protocol like `scp` or `ftp`.
8. Log in to your Appcircle DMZ server via SSH or a remote connection.
9. Change to the directory containing the Appcircle DMZ server configuration.
```bash
cd appcircle-server-dmz
```
10. Stop the Appcircle DMZ server.
```bash
./ac-self-hosted-dmz.sh down
```
11. Delete the old Appcircle DMZ server directory.
```bash
cd .. && rm -rf appcircle-dmz-server
```
12. Extract the `dmz.tar.gz` file into a new Appcircle DMZ server directory.
```bash
mkdir -p appcircle-server-dmz && \
tar -xzf dmz.tar.gz -C appcircle-server-dmz
```
13. Change directory into the new directory.
```bash
cd appcircle-server-dmz
```
14. Reconfigure the Appcircle DMZ server.
```bash
./ac-self-hosted-dmz.sh -i
```
15. Start the Appcircle DMZ server.
```bash
./ac-self-hosted-dmz.sh up
```
16. Check the Appcircle DMZ server status.
```bash
./ac-self-hosted-dmz.sh check
```
## Disabling Custom Subnet Configuration
To allow Docker or Podman to automatically manage subnet configurations for your Appcircle server and/or Appcircle DMZ server containers, you can disable the custom subnet settings.
To disable custom subnet configuration:
1. Follow the steps in either:
- [Configuring the Subnet for Appcircle Server](#configuring-the-subnet-for-appcircle-server)
- [Configuring the Subnet for Appcircle DMZ Server](#configuring-the-subnet-for-appcircle-dmz-server)
2. Set the `enabled` parameter to `false` or delete the `networkSettings` or `dmzNetworkSettings` entry in the appropriate configuration section:
- For the Appcircle server:
```yaml
networkSettings:
enabled: false
```
- For the Appcircle DMZ server:
```yaml
dmzNetworkSettings:
enabled: false
```
3. After saving the configuration changes, restart the Appcircle server and/or Appcircle DMZ server to apply the new settings by following the steps in the [Configuring the Subnet for Appcircle Server](#configuring-the-subnet-for-appcircle-server) or [Configuring the Subnet for Appcircle DMZ Server](#configuring-the-subnet-for-appcircle-dmz-server) section.
---
## Advanced Configuration
The Advanced Configuration section is designed to provide additional security measures and system optimization options for your self-hosted Appcircle instance. It ensures that your setup is not only tailored to your needs but also secure and efficient.
### [LDAP Brute Force Protection](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/ldap-brutefore)
Protect your system against unauthorized access attempts with LDAP Brute Force Protection. This feature secures your LDAP authentication process against attackers trying multiple password combinations to gain access to your system.
### [Cache Size Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/cache-size-configuration)
Optimize your server's performance by configuring the cache size. This setting allows you to determine the amount of data your server caches, which can speed up processing times and improve overall efficiency.
### [Command-Line Interface (CLI) Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/appcircle-cli)
Customize the CLI to suit your workflow needs. This includes setting up environment variables, enabling specific commands, and configuring access permissions for a streamlined command-line experience.
### [Container Engine Network Subnet](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/container-engine-network-subnet)
Learn how to configure the network subnets of the container engine for the Appcircle server and Appcircle DMZ server.
### [Enterprise App Store and Testing Distribution in DMZ](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz)
Securely distribute and test enterprise applications by placing your app store and testing environment in a DMZ (Demilitarized Zone). This configuration isolates testing from production, enhances security by acting as a buffer against external threats, and streamlines deployment processes.
---
## LDAP Brute Force Protection
## Overview
Enabling LDAP authentication introduces the risk of brute-force attacks that can originate from external or internal sources.
A sustained LDAP brute-force attack can result in user accounts being locked out of the LDAP directory, preventing access to other applications integrated with the directory.
To mitigate this risk, a self-hosted Appcircle server can be configured to block repeated failed login attempts for a duration before allowing additional attempts.
The Appcircle server's brute-force algorithm is based on successive failed attempts, not failed attempts over a period of time.
:::info
**Minimum Required Version**
If you want to enable LDAP brute-force settings, the Appcircle server version must be `3.10.0` or later.
:::
### Default Configuration
Appcircle server comes with brute-force protection **turned off** by default.
It is completely up to you to set this up. See the following sections for details.
## Brute-Force Arguments
The appropriate blocking threshold and duration are dependent on the account lockout policies enforced on the LDAP server itself.
For example, if the LDAP server locks accounts for 1 hour after 10 failed attempts, Appcircle can be configured to block login attempts for 2 hours after 5 failures to provide an early warning system.
So the users won't be blocked by the LDAP server and can continue to use other applications.
Follow the recommendations below when tuning the brute-force protection mechanisms:
- Review the number of failed login attempts that trigger account lockout and the lockout duration configured on your LDAP server.
- Configure the Appcircle server's maximum retry attempts equal to or lower than your LDAP server's threshold. For example, if LDAP locks accounts after 10 failed logins, set the Appcircle server to block after 5-8 attempts.
- Configure Appcircle's lockout duration to be equal to or greater than LDAP. For instance, if LDAP locks accounts for 1 hour, Appcircle should be 1 hour or more.
- Test updated configurations in a non-production environment first. Validate that the Appcircle server lockouts are triggered before LDAP lockouts when deliberately failing logins.
- Monitor logs for incidents blocked by the Appcircle server to optimize configurations based on real activity targeting your environment.
Following these best practices will allow the Appcircle server to effectively function as an early warning system for brute-force attacks against LDAP infrastructure. Besides, you will prevent a general LDAP lockout, which can block your LDAP users from using other systems on the intranet.
## Configuring the Appcircle Server
We are assuming that you have installed the Appcircle server with version `3.10.0` or later and configured the LDAP settings from the UI.
:::caution
LDAP brute-force settings can be configured for only **Testing Distribution** and **Enterprise App Store** modules.
[Appcircle login with LDAP](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings#appcircle-login-with-ldap) is not supported and is out-of-scope for the brute-force settings.
:::
To configure LDAP brute-force settings on the Appcircle server, you can follow the steps below:
- Log in to Appcircle server with SSH or remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Edit the `global.yaml` file of your project.
:::info
The `spacetech` in the example codes below are example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
```bash
vi ./projects/spacetech/global.yaml
```
- Find the `keycloak` entry and add or edit the missing `bruteForce` key to it.
For the Testing Distribution module, you must use the `distribution` section.
For the Enterprise App Store module, you must use the `store` section.
See the example configuration below:
```yaml
keycloak:
initialUsername: admin@example.com
enabledRegistration: true
bruteForce:
distribution:
maxFailureCount: 10
maxLockDuration: 3600
store:
maxFailureCount: 10
maxLockDuration: 3600
```
:::info
- `maxFailureCount`: The needed count of successive failed attempts to block user.
- `maxLockDuration`: The time in seconds required to unblock the user.
:::
- Shutdown Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Boot Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
:::
---
## Enterprise App Store and Testing Distribution in DMZ
## Overview
A Demilitarized Zone (DMZ) in networking is a segment of an internal network that is exposed to external networks, typically over the internet. By isolating Appcircle DMZ server from the internal network, you ensure that it remains secure.
This is particularly useful when users need to access Testing Distribution and Enterprise App Store but not all features for business operations within the private network.
The Testing Distribution module and Enterprise App Store module hosted on the Appcircle DMZ server can be accessed by users from the internet, ensuring they have secure access to these critical features while keeping sensitive business data within your private network. This setup provides a balance between security and productivity in an organization's IT environment.
We assume that you have already set up an Appcircle server successfully. This document will guide you through creating Appcircle DMZ server and Appcircle server configurations.
In this document:
- We will call the "Appcircle DMZ server" to the server, which is located in the DMZ and host the Appcircle Enterprise App Store and Testing Distribution services.
- We will call the "Appcircle server" to the server, which is located in the private network and host the Appcircle core services.
:::info
The Appcircle DMZ server does not serve any content on port `80`. For more information on the use of `HTTP` port `80` by the Appcircle DMZ server, please refer to the [Firewall Configuration](#firewall-configuration).
:::
:::info
When you convert to the DMZ architecture, both the Enterprise App Store and the Testing Distribution will be transferred to the Appcircle DMZ server. We currently do not support using only one of them in the Appcircle DMZ server.
:::
## Appcircle DMZ Server Pre-requirements
Below are the hardware and OS requirements for self-hosted Appcircle DMZ server installation.
### Supported Linux Distributions
Self-hosted Appcircle DMZ server, can only be installed on Linux operating system.
If you have installed the Appcircle server with Podman:
- CentOS Stream 8 or later
- RHEL 8 or later
If you have installed the Appcircle server with Docker:
- Ubuntu 20.04 or later
- Debian 11 or later
- CentOS 8 or later
- RHEL 8 or later
### Hardware Requirements
Minimum hardware requirements for self-hosted Appcircle can be:
- 20GB or more free disk space
- 4 or more cores CPU
- 8 or more gigabytes (GB) RAM
:point_up: These hardware specs are minimum requirements for basic execution and it can be used only for quick evaluation or development purposes.
:::caution
CPU architecture must be AMD or Intel 64-bit arch (`x86_64`).
:::
:::info
If you have enough RAM and a recent CPU, performance of Appcircle server can be limited by hard drive seek times. So, having a fast drive like a solid state drive (SSD) improves runtime.
:::
Higher numbers will be better especially for increased number of users.
For an enterprise installation, **minimum** hardware requirements are
- 50GB SSD
- 8 CPU
- 16GB RAM
For production environments, **recommended** hardware requirements are
- 50GB SSD
- 32 CPU
- 64GB RAM
:::caution
#### Swap
:::
### Software Requirements
#### Container Engine
You must use the same container engine with on the Appcircle server and the Appcircle DMZ server.
If you have installed the Appcircle server with Podman, you **must** use Podman on the Appcircle DMZ server.
If you have installed the Appcircle server with Docker, you **must** use Docker on the Appcircle DMZ server.
#### Tools
You need to have the following tools installed on your system:
- curl
- tar
- podman
- podman-compose
You can install these dependencies from your package repository depending on your distro.
#### Enabling the Linger Option
#### Overcoming Privileged Port Limitations
#### Podman Network Stack
#### Tools
You need to have the following tools installed on your system:
- curl
- tar
- docker
- docker compose
You can install these dependencies from your package repository depending on your distro.
#### SELinux
You must use the same SELinux mode on the Appcircle server and the Appcircle DMZ server.
You can check the SELinux mode with the command below.
```bash
getenforce
```
### Firewall Configuration
If you are using `Firewalld`, you need to open the ports below according to your server configuration.
- If you plan to run the Appcircle DMZ server with HTTPS:
```bash
sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=443/tcp --permanent
sudo firewall-cmd --reload
```
To check if the ports are open, you can run the following command:
```bash
sudo firewall-cmd --list-ports
```
If you are using `UFW (Uncomplicated Firewall)`, you need to open the 80 and 443 ports for the Appcircle DMZ server.
Check if the `ufw` is active.
```bash
sudo ufw status
```
If you see `Status: active` as the output, you should allow TCP 80 and TCP 443 ports for Appcircle DMZ server to accept connections.
```bash
sudo ufw allow 80 && \
sudo ufw allow 443
```
To check if the ports are open, you can run the following command:
```bash
sudo ufw status verbose
```
:::info
:::
### HTTPS Requirement
Due to this requirement, it is mandatory for the Appcircle DMZ server to be configured with `HTTPS`. For detailed instructions on configuring custom domains and `HTTPS` for the Enterprise App Store and Testing Distribution, please refer to the [SSL Configuration Guide](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration). This guide will help you set up the necessary configurations in your Appcircle server's `global.yaml` file.
### DNS Entries
For Appcircle DMZ server to work successfully, you should configure the DNS records.
For the clients that will connect to the Appcircle DMZ server should resolve 3 domains; Enterprise App Store, Testing Distribution and authentication domains.
These domains should be resolved to the Appcircle DMZ server IP. The domains may vary according to the Appcircle server configuration. To check the current configured domains, you can follow the steps below:
- Login to the Appcircle server with SSH.
- Go to the Appcircle server directory.
```bash
cd appcircle-server
```
- Update the environment variable `PATH` with the required dependencies.
```bash
export PATH=$PATH:$(pwd)/deps/bin
```
---
- Check if your Enterprise App Store custom domain is enabled.
```bash
yq '.storeWeb.customDomain.enabled' ./projects/spacetech/export/.global.yaml
```
- Check the Enterprise App Store custom domain.
```bash
yq '.storeWeb.customDomain.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
store.spacetech.com
```
- Check the Enterprise App Store default domain.
```bash
yq '.storeWeb.external.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
store.appcircle.spacetech.com
```
---
- Check if your Testing Distribution custom domain is enabled.
```bash
yq '.testerWeb.customDomain.enabled' ./projects/spacetech/export/.global.yaml
```
- Check the Testing Distribution custom domain.
```bash
yq '.testerWeb.customDomain.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
dist.spacetech.com
```
- Check the Testing Distribution default domain.
```bash
yq '.testerWeb.external.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
dist.appcircle.spacetech.com
```
---
- Check if your DMZ Authentication custom domain is enabled.
```bash
yq '.keycloak.dmzCustomDomain.enabled' ./projects/spacetech/export/.global.yaml
```
- Check the Appcircle DMZ authentication custom domain.
```bash
yq '.keycloak.dmzCustomDomain.domain' ./projects/spacetech/export/.global.yaml
```
:::tip
You can change the Appcircle authentication domain for the users access from the internet and make it different from the internal domain using a custom domain. See the [FAQ](#how-can-we-change-the-appcircle-authentication-domain-on-the-dmz-server-for-internet-users) below for details.
:::
Output:
```
auth-appcircle.spacetech.com
```
- Check the Appcircle DMZ default authentication domain.
```bash
yq '.keycloak.external.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
auth.appcircle.spacetech.com
```
---
According to the sample outputs above, **when all the custom domains are enabled**, the domains that clients accessing via the internet should use are as follows:
- `store.spacetech.com`: Enterprise App Store custom domain.
- `dist.spacetech.com`: Testing Distribution custom domain.
- `auth-appcircle.spacetech.com`: DMZ Authentication custom domain.
According to the sample outputs above, **when all the custom domains are disabled**, the default domains that clients should use are:
- `store.appcircle.spacetech.com`: Enterprise App Store default domain.
- `dist.appcircle.spacetech.com`: Testing Distribution default domain.
- `auth.appcircle.spacetech.com`: DMZ default authentication domain.
:::tip
It's perfectly acceptable for **some custom domains to be enabled while others are disabled**.
For example, you might have a custom domain for the Enterprise App Store but use the default domain for Testing Distribution or DMZ Authentication.
:::
:::info
#### CodePush (optional)
There is an optional domain name if you want to use the Appcircle server [CodePush](/code-push/) feature in the Appcircle DMZ server. You will configure this domain name in the Appcircle server `global.yaml` file in the following sections.
If you don't want to use the [CodePush](/code-push/) feature, you can skip the CodePush domain name configuration.
:::
---
Also the Appcircle DMZ server should be resolving some of the Appcircle server domains such as authentication, API and monitoring domains.
These domains should be resolved to the Appcircle server IP. The domains may vary according to the Appcircle server configuration.
- Check the authentication domain of the Appcircle server.
```bash
yq '.keycloak.external.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
auth.appcircle.spacetech.com
```
---
- Check the API domain of the Appcircle server.
```bash
yq '.apiGateway.external.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
api.appcircle.spacetech.com
```
---
- Check the monitoring domain of the Appcircle server.
```bash
yq '.grafana.external.domain' ./projects/spacetech/export/.global.yaml
```
Output:
```
monitor.appcircle.spacetech.com
```
According to the sample outputs above, the needed domains that Appcircle DMZ server should know are as follows:
- `api.appcircle.spacetech.com`: Appcircle API domain.
- `auth.appcircle.spacetech.com`: Appcircle authentication domain.
- `monitor.appcircle.spacetech.com`: Appcircle monitoring domain.
:::caution
There is a common domain here. Be aware that the `auth` subdomain that the clients that will access from the internet and the Appcircle DMZ server will connect to should mean two different things.
:::
## Creating the Appcircle DMZ Server Configuration
To create the Appcircle DMZ server configuration, you should login to the Appcircle server.
You will create all the configuration files on the Appcircle server and then move the created configuration files to the Appcircle DMZ server.
To create the Appcircle DMZ server configuration, you can follow the steps below.
:::caution
If you modify the `global.yaml` configuration file for the Appcircle server, you **must** also update the configuration on the Appcircle DMZ server. Otherwise, Appcircle services may exhibit unusual behavior or malfunction.
:::
- Login to the Appcircle server with SSH.
- Go to the Appcircle server directory.
```bash
cd appcircle-server
```
- Stop the running Appcircle server.
```bash
./ac-self-hosted.sh -n spacetech down
```
- (optional) If you want to use the [CodePush](/code-push/) feature in the Appcircle DMZ server, you need to configure the CodePush domain name and its SSL certificate in the Appcircle server `global.yaml` file.
Click to see how to configure the CodePush feature in the Appcircle DMZ server.
:::note
CodePush DMZ server configuration requires Appcircle server `3.28.2` or later.
:::
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add or update the `codepushProxy` key as below.
```yaml
codepushProxy:
enabled: true # Set to true to enable the CodePush feature on the Appcircle DMZ server
external:
port: 8443 # Set to 8443 to use the CodePush feature with HTTPS
scheme: https # Set to https to use the CodePush feature with HTTPS
domain: codepush.spacetech.com # Set the CodePush domain name as you want
publicKey: | # Set the SSL certificate public key for the CodePush domain
-----BEGIN CERTIFICATE-----
MIIDqjCCAzCgAwIBAgISBiQ+pg7gN4ODAcGcxqy6+ZvtMAoGCCqGSM49BAMDMDIx
...
RxFkhGCZddnB9p9x1p+ZJurRu13naXmHPpq+j3X1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw
...
Ig46v9mFmBvyH04=
-----END CERTIFICATE-----
privateKey: | # Set the SSL certificate private key for the CodePush domain
-----BEGIN PRIVATE KEY-----
...
bSo6Ae6pgnQsFYyDGHQxHUwiNT7yXW0fel+k+yEHhXeLcDs40cPzr5c=
-----END PRIVATE KEY-----
```
:::caution
The `codepushProxy.external.port` must be `8443` and `codepushProxy.external.scheme` must be `https` to use the CodePush feature in the Appcircle DMZ server with HTTPS.
Since we forward the `TCP/443` to the `TCP/8443` port with [Socat](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/installation/podman#overcoming-privileged-port-limitations) on the host, you will connect to the CodePush with the `TCP/443` port as usual from the internet.
:::
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add or update the `codepushProxy` key as below.
```yaml
codepushProxy:
enabled: true # Set to true to enable the CodePush feature on the Appcircle DMZ server
external:
port: 443 # Set to 443 to use the CodePush feature with HTTPS
scheme: https # Set to https to use the CodePush feature with HTTPS
domain: codepush.spacetech.com # Set the CodePush domain name as you want
publicKey: | # Set the SSL certificate public key for the CodePush domain
-----BEGIN CERTIFICATE-----
MIIDqjCCAzCgAwIBAgISBiQ+pg7gN4ODAcGcxqy6+ZvtMAoGCCqGSM49BAMDMDIx
...
RxFkhGCZddnB9p9x1p+ZJurRu13naXmHPpq+j3X1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw
...
Ig46v9mFmBvyH04=
-----END CERTIFICATE-----
privateKey: | # Set the SSL certificate private key for the CodePush domain
-----BEGIN PRIVATE KEY-----
...
bSo6Ae6pgnQsFYyDGHQxHUwiNT7yXW0fel+k+yEHhXeLcDs40cPzr5c=
-----END PRIVATE KEY-----
```
:::caution
The `codepushProxy.external.port` must be `443` and `codepushProxy.external.scheme` must be `https` to use the CodePush feature in the Appcircle DMZ server with HTTPS.
:::
- After you have configured the CodePush feature on the Appcircle DMZ server with a new domain name, you need to update the `CodePushServerUrl` in the [CodePush SDK configuration](https://docs.appcircle.io/code-push/code-push-sdk#codepush-configurations-in-project) of your mobile application.
- For example, if you have configured the CodePush feature on the Appcircle DMZ server with the `codepush.spacetech.com` domain name, you need to update the `CodePushServerUrl` in the [CodePush SDK configuration](https://docs.appcircle.io/code-push/code-push-sdk#codepush-configurations-in-project) of your mobile application to `https://codepush.spacetech.com` from the default `https://api.appcircle.spacetech.com/codepush` URL.
:::caution
Please make sure to remove the `/codepush` path from the `CodePushServerUrl`.
:::
- Create the new configuration files for the Appcircle DMZ and the Appcircle server.
```bash
./ac-self-hosted.sh -n spacetech export --dmz
```
:::info
The `--dmz` flag in the `export` subcommand above creates the configuration files according to your `global.yaml` file of your project for the both the Appcircle DMZ server and the Appcircle server.
:::
- Check the exported DMZ directory that contains the required files to create Appcircle DMZ server.
```bash
ls -lah projects/spacetech/export/dmz/
```
- Start the Appcircle server.
```bash
./ac-self-hosted.sh -n spacetech up
```
- Compress the directory into a tarball in the Appcircle server.
```bash
tar -czf dmz.tar.gz -C projects/spacetech/export/dmz/ .
```
- Transfer the `dmz.tar.gz` file to the Appcircle DMZ server with a file transfer protocol like `scp` or `ftp`.
## Creating the Appcircle DMZ Server
### Create Appcircle DMZ Directory
You need to create a directory for the Appcircle DMZ server and extract the transferred configuration files.
- Create a Appcircle DMZ server.
```bash
mkdir -p appcircle-server-dmz
```
- Extract the tarball you transferred from the Appcircle server.
```bash
tar -xzf dmz.tar.gz -C appcircle-server-dmz
```
- Change directory into the new directory.
```bash
cd appcircle-server-dmz
```
### Configure the System
Install the required packages and configurations on the system.
:::caution
You need to have root access on your system for this step. Being able to run `sudo` is sufficient for the following step. (sudoer)
Run the command without `sudo`. The script will ask for the user password if it's required.
:::
```bash
./ac-self-hosted-dmz.sh -i
```
### Starting the Appcircle DMZ Server
After you have configured the system with the steps above, you are ready to run the Appcircle DMZ server.
- Start the Appcircle DMZ server.
```bash
./ac-self-hosted-dmz.sh up
```
- Check the health of the Appcircle DMZ services.
```bash
./ac-self-hosted-dmz.sh check
```
:::caution
Be sure that all the services are running and healthy. If there are connection problems between the Appcircle DMZ server and the Appcircle server, the services won't be healthy.
:::
## Stopping the Appcircle DMZ Server
If you need to stop the Appcircle DMZ server in a case, you can run the the command below:
```bash
./ac-self-hosted-dmz.sh down
```
## Upgrading Appcircle DMZ and Appcircle server
If there is a new Appcircle server version available and you want to update, you can follow the steps below to update the Appcircle server and the Appcircle DMZ server.
:::caution
When upgrading an Appcircle server, it is critical to also update the Appcircle DMZ server. If you don't, Enterprise App Store and Testing Distribution may not function as expected.
:::
- Login to the Appcircle DMZ server.
- Go to the Appcircle DMZ server directory.
```bash
cd appcircle-server-dmz
```
- Stop the Appcircle DMZ Server.
```bash
./ac-self-hosted-dmz.sh down
```
- Delete the Appcircle DMZ server directory.
```bash
cd .. && rm -rf appcircle-server-dmz
```
- Update the Appcircle server by following the [Update document](/self-hosted-appcircle/install-server/linux-package/update).
- Create the updated Appcircle DMZ configuration files by following the [Creating the Appcircle DMZ Server Configuration](#creating-the-appcircle-dmz-server-configuration) section.
- Create the new Appcircle DMZ server by following the [Creating the Appcircle DMZ Server](#creating-the-appcircle-dmz-server) section.
- Re-configure the Appcircle DMZ server by following the [Configure the System](#configure-the-system) section.
- Start the Appcircle DMZ server with the updated configurations by following the [Starting the Appcircle DMZ Server](#starting-the-appcircle-dmz-server) section.
## Appcircle DMZ Server Monitoring
By default, the Appcircle DMZ server will try to send the container logs to the Appcircle server.
You can check the container logs on the Appcircle monitoring page. For more details about checking the logs, you can check the [Monitoring](/self-hosted-appcircle/install-server/linux-package/configure-server/monitoring) page.
## Restarting the Appcircle DMZ Server Host
For Docker users, there are built-in mechanisms that handle container restarts, eliminating the need for manual intervention.
However, Podman users will need to create a systemd unit service to ensure the application starts automatically upon server reboot.
With Docker, you can rely on the built-in restart policies to handle the automatic startup of your Appcircle server.
Docker will automatically restart the server services if the host reboots.
This eliminates the need for any additional steps or configurations to ensure your application restarts upon host restart.
When using Podman, you will need to create a systemd unit service to enable the automatic startup of your application containers.
We have a dedicated section where we explain how to create the systemd file for Appcircle DMZ server services to start automatically when the host reboots.
You can follow the [Restarting Host](../restarting-host) document but there are two things to watch out on the "Restarting Host" document.
You will see the `ExecStart` line in the systemd service file like in the example below:
```bash
ExecStart=/bin/bash ${APPCIRCLE_SERVER_DIR}/ac-self-hosted.sh -n spacetech up
```
For the Appcircle DMZ server:
- The `ExecStart` line should contain Appcircle DMZ server directory and `ac-self-hosted-dmz.sh` as the command.
- There shouldn't be any project name. In the example above, you should remove the `-n spacetech` section.
A full example of `ExecStart` line should be:
```bash
ExecStart=/bin/bash /app/appcircle-server-dmz/ac-self-hosted-dmz.sh up
```
## Troubleshooting & FAQ
### How can we change the Appcircle authentication domain on the DMZ server for internet users?
You can use an additional custom domain for Appcircle authentication so that internet users can access authentication services from the internet without using the internal `auth` [subdomain](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings).
:::caution
The custom domain applies to the Appcircle DMZ server only. When connecting to the Appcircle server located within the private network, you should continue to utilize the default `auth` sudomain for Appcircle authentication services.
:::
Follow the steps below to make relevant configurations on the Appcircle server.
:::info
This feature is supported for Appcircle server version `3.26.1` or later.
:::
- Login to the Appcircle server with SSH.
- Change directory to Appcircle server.
```bash
cd appcircle-server
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add or update the `keycloak.dmzCustomDomain` parameter as below.
:::info
Please keep in mind that the `keycloak` key might already exist in your `global.yaml` file. In that case, find the key to add or update the `dmzCustomDomain` part.
If `keycloak` does not exist, then you can add it to the `global.yaml` file of your project.
:::
:::info
The authentication domain must always operate over HTTPS to ensure secure communication. Providing `.keycloak.dmzCustomDomain.publicKey` and `.keycloak.dmzCustomDomain.privateKey` is optional. You may define a custom SSL certificate specifically for the DMZ custom domain or rely on the existing certificate configured under `.nginx.sslCertificate`, as long as it also covers the DMZ custom domain.
:::
```yaml
keycloak:
dmzCustomDomain:
enabled: true
domain: auth-appcircle.spacetech.com
port: 443
publicKey: |
-----BEGIN CERTIFICATE-----
MIIFOjCCBCKgAwIBAgISBAqWQRxIkc0kW2OZsPY2qH4dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
fLDoKQyylhH5aZgQvRWmvGjAvMCaU4me6rfq7ExudsrImuHZuxv0+mL1OvHsJA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
privateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL0BJ4P5hBrjIf
uDOL6OsB3AvdwTIwCTfpaJOSRi1ZXbxVGXv2f429gqQ4WADxRnLIsmcZtbAyrubO
...
LUBOU4QRP9V6qpS0TrLmIoM=
-----END PRIVATE KEY-----
```
:::caution
The `keycloak.dmzCustomDomain.port` must be `443` for Docker.
:::
```yaml
keycloak:
dmzCustomDomain:
enabled: true
domain: auth-appcircle.spacetech.com
port: 8443
publicKey: |
-----BEGIN CERTIFICATE-----
MIIFOjCCBCKgAwIBAgISBAqWQRxIkc0kW2OZsPY2qH4dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
fLDoKQyylhH5aZgQvRWmvGjAvMCaU4me6rfq7ExudsrImuHZuxv0+mL1OvHsJA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
privateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL0BJ4P5hBrjIf
uDOL6OsB3AvdwTIwCTfpaJOSRi1ZXbxVGXv2f429gqQ4WADxRnLIsmcZtbAyrubO
...
LUBOU4QRP9V6qpS0TrLmIoM=
-----END PRIVATE KEY-----
```
:::caution
The `keycloak.dmzCustomDomain.port` must be `8443` for Podman.
Since we forward the `TCP/443` to the `TCP/8443` port with [Socat](/self-hosted-appcircle/install-server/linux-package/installation/podman#overcoming-privileged-port-limitations) on the host, you will connect to the custom authentication domain with the `TCP/443` port.
:::
:::caution
If you enable the **DMZ custom domain** and configure **Single Sign-On (SSO)**, you must add the DMZ custom domain to your SSO provider's list of authorized redirect URLs.
Without this update, authentication requests from the DMZ domain will be blocked, causing SSO login failures due to unrecognized redirect URIs.
:::
- **[Upgrade](#upgrading-appcircle-dmz-and-appcircle-server)** the Appcircle server and DMZ server for changes to be applied.
---
## Auto-upgrading Server
## Overview
In this document, you will learn how to update the Appcircle server automatically.
The automated update tool streamlines the process of keeping your Appcircle server up-to-date. It takes care of seamlessly downloading the latest release, extracting the necessary files, and applying any new configurations.
In the event of a minor or patch upgrade, the tool will gracefully stop the existing Appcircle server, pull the updated container images, and restart the Appcircle server with the new changes.
This automated approach ensures a smooth transition to the latest version, minimizing downtime and maximizing efficiency.
:::caution
The auto-update tool does not update the Appcircle server in the event of a major Appcircle server update.
:::
:::caution
The auto-update tool does not currently support the handling of proxy environment variables. Therefore, it is not recommended to use this tool on an Appcircle server that use proxy environment variables.
:::
:::caution
The auto-update tool does not currently support Appcircle DMZ server configuration. If you are using the Appcircle DMZ server configuration, please follow the normal update procedure.
:::
:::info
The auto-update tool is included in the Appcircle server package version `3.16.0` or later.
:::
## Updating the Server on Demand
For a manual yet simplified update process of the Appcircle server, you can leverage the auto-update via a single command.
The auto-update will do the following jobs automatically:
- Downloads the latest available Appcircle server package for your organization.
- Checks the package version for a possible major upgrade.
- _If yes, exits gracefully since the major upgrade might require manual jobs. Please check the release notes for detailed information in this case._
- Extracts the downloaded Appcircle server package.
- Stops the Appcircle server.
- Exports the updated configurations.
- Pulls the updated container images.
- Starts the Appcircle server.
:::caution
Please note that this process will cause downtime since it requires a restart of the Appcircle server.
:::
In order to perform above operations with a single command call, follow the steps below.
Change the directory to the Appcircle server.
```bash
cd appcircle-server
```
Run the auto-update tool for your project.
```bash
./helper-tools/auto-update.sh -n "spacetech" update
```
## Updating the Server Scheduled
To fully automate the update process of the Appcircle, you can leverage the auto-update tool to create a cronjob on the Appcircle server.
Crontab is a scheduling utility that enables users to schedule tasks and commands to run at predetermined intervals.
By utilizing crontab, you can seamlessly automate minor or patch updates for the Appcircle server, ensuring your application remains up-to-date without manual intervention.
:::caution
If you are updating the Appcircle server with the [Offline Upgrade](/self-hosted-appcircle/install-server/linux-package/configure-server/offline-installation#upgrade) method, then you can't use auto-update tool since it requires some network access to download the Appcircle server package and up-to-date container images.
:::
### Enable Passwordless Sudo
:::caution
To use the crontab, you **must** enable the passwordless `sudo` commands.
:::
Passwordless `sudo` allows authorized users or scripts to execute commands with superuser privileges without being prompted for a password, enhancing the automation capabilities of administrative tasks.
To activate passwordless `sudo`, you should edit the `sudoers` file.
```bash
sudo visudo
```
Find the line below in the `sudoers` file.
```txt
%wheel ALL=(ALL) ALL
```
:::caution
The **`wheel`** in the example output above is the privileged group name that depends on the Linux distribution you use.
For RHEL or its derivatives, it is generally `wheel`. For Ubuntu or Debian derivatives, it can be one of `admin` or `sudo`.
You can also enable passwordless sudo only for a user. Please refer to your Linux distribution's user manuals for details.
:::
Add `NOPASSWD:` to activate the passwordless sudo.
```txt
%wheel ALL=(ALL) NOPASSWD: ALL
```
### Create the Crontab Job
To create a cronjob, you can simply use the auto-update tool commands.
Change the directory to the Appcircle server.
```bash
cd appcircle-server
```
Create the crontab job with the command below.
```bash
./helper-tools/auto-update.sh -n "spacetech" install
```
Check if crontab job is activated.
```bash
crontab -l
```
You should see the newly added crontab entry in the list of jobs, like below:
```txt
0 3 * * 6 /home/user/appcircle-server/helper-tools/auto-update.sh -n "spacetech" update &>> /home/user/appcircle-server/appcircle-server-auto-update.log
```
:::info
As you can see in the above job definition, the logs will be saved into a file named
- `appcircle-server-auto-update.log`
in the `appcircle-server` directory. You can check the logs if you have any issues with the automated update.
:::
:::tip
By default, the crontab job is defined to check and update the Appcircle server at 3:00 AM every Saturday.
:::
You can remove the crontab job if you don't need it anymore with the below command.
```bash
./helper-tools/auto-update.sh -n "spacetech" remove
```
You can change the crontab schedule if you want to check and update the Appcircle server, for instance, at 3:00 AM every day.
```bash
./helper-tools/auto-update.sh -n "spacetech" install --cron-time "0 3 * * *"
```
Below are some sample crontab schedules that can be used for scheduled upgrades.
- At 3:00 AM every Sunday: `0 3 * * 0`
- At 3:00 AM first day of every month: `0 3 1 * *`
:::tip
If you have enabled automated Appcircle server updates, you might want to consider cleaning the unused old Appcircle server container images since these images will consume the disk and won't be used at runtime.
You can use the below command for this purpose to clean up unused container images. However **it should be called while the Appcircle server is running** smoothly.
```bash
docker image prune -a
```
It will remove all images without at least one container associated with them so that the container images that are used by containers will not be affected.
:::
---
## Domain Verification for Linux Package Installation
# Domain Verification
This document explains how to configure your Appcircle server's domain verification option when adding domains as trusted for Appcircle organizations. By skipping the domain verification process, domains will be automatically marked as verified without the need for TXT records.
Please note, this page does not cover the domain verification feature itself. For more detailed information on domain verification, please refer to the [Domain Verification](/account/my-organization/security/domain-verification) documentation.
By default, domain verification is **disabled** on the Appcircle server, meaning domains are automatically considered verified without the need to add a TXT record to your DNS configuration. However, if you change this option, Appcircle will require the addition of a TXT record to validate the domain.
## Configuring the Appcircle Server
To enable or disable domain verification, follow these steps:
1. Log in to your Appcircle server via SSH or a remote connection.
2. Change to the directory containing the Appcircle server configuration.
```bash
cd appcircle-server
```
3. Open the `global.yaml` file in a text editor.
```bash
vi ./projects/spacetech/global.yaml
```
4. Locate the `keycloak` entry in the configuration file. Add or update the `domainVerification` key with the following settings, depending on your preference.
:::caution
If the `keycloak` entry already exists in your `global.yaml` file, ensure you update the existing key instead of creating a new one.
:::
```yaml
keycloak:
domainVerification:
enabled: true
```
:::note
- **`enabled`**: If this variable is set to `true`, it requires the addition of a TXT record for domain verification. If you want to skip TXT record verification and make the domain automatically considered as verified, then this variable should be set to `false`.
:::
5. After saving the configuration changes, restart your Appcircle server to apply the new settings.
---
## Customize Enterprise App Store
# Customize the Enterprise App Store on Self-hosted Installations
Some additional Enterprise App Store settings can be customized for self-hosted installations in order to make them more tailored to your users.
You can change how your store looks using the **[Customize](/enterprise-app-store/portal-customization)** screen in the Enterprise App Store module, just like you can with Appcircle Cloud.
For self-hosted specific settings, you should follow the documentation below.
## Tab Title Localization
You can change the Enterprise App Store tab title according to the language selected on the self-hosted Appcircle server.
For example, you can set a title for **TR** and a different title for **EN** language selection on browsers.
:::info
Appcircle server version `3.12.1` or later is required for this feature.
:::
:::caution
Be aware that this will cause a downtime on the Appcircle server.
:::
If you set titles from `global.yaml` by following the steps below, your title settings configured from the Enterprise App Store's "Customize" page will be overridden.
- Log in to Appcircle server with SSH or remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
:::info
The `spacetech` in the example codes below are example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
- Shutdown Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add the `lang` parameter to the `storeWeb` entry.
:::caution
The `storeWeb` key should already have been in the `global.yaml` file.
You just need to add the `lang` key and other sub-keys to that section.
The `global.yaml` should have only one `storeWeb` key for proper working.
:::
```yaml
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: store.spacetech.com
lang:
TR_STORE_TITLE: Uygulama Mağazası
EN_STORE_TITLE: App Store
```
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
:::
To see the new configuration updates on the store, follow the steps below:
- Go to the Enterprise App Store page of your organization with a browser.
- For example, `store.spacetech.com`
- Check the tab title. For our sample configuration,
- If the language is **TR** selected, then you should see "Uygulama Mağazası" in the tab title.
- If the language is **EN** selected, then you should see "App Store" in the tab title.
## Placeholder Text Customization
You can change the placeholder texts for the [Enterprise Portal](/enterprise-app-store/enterprise-portal#login) username and password based on the language selected in the language options.
For example, you can set a placeholder text for **TR** and a different placeholder text for the **EN** and **DE** language selections on browsers.
:::info
Appcircle server version `3.12.1` or later is required for this feature.
:::
:::caution
Be aware that this will cause a downtime on the Appcircle server.
:::
- Log in to Appcircle server with SSH or remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
:::info
The `spacetech` in the example codes below are example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
- Shutdown Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add the `lang` parameter to the `storeWeb` entry if it doesn't exist.
:::caution
The `storeWeb` key should already have been in the `global.yaml` file.
You just need to add the `lang` key and other sub-keys to that section.
The `global.yaml` should have only one `storeWeb` key for proper working.
:::
- Add the placeholder texts to the `lang` parameter.
:::tip
You can specify only for the languages you want to customize.
:::
```yaml
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: store.spacetech.com
lang:
TR_LDAP_USERNAME: LDAP kullanıcı adınız
TR_LDAP_PASSWORD: LDAP şifreniz
EN_LDAP_USERNAME: LDAP username
EN_LDAP_PASSWORD: LDAP password
DE_LDAP_USERNAME: LDAP-gebruikersnaam
DE_LDAP_PASSWORD: LDAP-wachtwoord
```
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
:::
To see the new configuration updates on the store, follow the steps below:
- Go to the Enterprise App Store page of your organization with a browser.
- For example, `store.spacetech.com`
- Check the placeholder texts. For our sample configuration,
- If the language is **TR** selected, then you should see "LDAP kullanıcı adınız" in the username placeholder text.
- If the language is **EN** selected, then you should see "LDAP username" in the username placeholder text.
- If the language is **DE** selected, then you should see "LDAP-gebruikersnaam" in the username placeholder text.
---
## External Image Registries
## Overview
In the Appcircle's containerized application ecosystem, users have the flexibility to access container images through various external image registries.
These external repositories serve as integral components, offering users different avenues to retrieve and manage container images based on their preferences and infrastructure requirements.
These services act as intermediaries, facilitating seamless image retrieval, caching frequently accessed images, and providing enhanced security measures for image distribution.
## Appcircle Registry Configuration
For the Appcircle server to work with your own container image registry, you should add an additional setting to the `global.yaml` file of your project.
- Log in to the Appcircle server with SSH or a remote connection.
- Go to the `appcircle-server` directory.
- Edit the `global.yaml` file of your project.
:::info
The `spacetech` in the example codes below is an example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
```bash
vi ./projects/spacetech/global.yaml
```
- Find the `image` key. If it doesn't exist in `global.yaml`, add it.
- The `image` key should be configured with your **registry** details:
- **`url`**: Registry URL. (For our example, "registry.spacetech.com:8083/appcircle").
- **`username`**: Username of the registry.
- **`password`**: Password of the registry.
- **`requiredLogin`**: If this variable is set to `true`, the Appcircle server will use the `username` and `password` variables to login to the registry. If the end-user is logged in to his artifact registry manually, or the registry doesn't need authentication, then this variable should be `false`.
```yaml
image:
registry:
url: registry.spacetech.com:8083/appcircle/docker-registry
username: registryUsername
password: superSecretPassword
requiredLogin: true
```
## Sonatype Nexus Configuration
To use Sonatype Nexus as your proxy registry, you should follow the below steps.
- Create a new repository in Nexus with the type of `docker (proxy)`.
- Set the registry `name` and `port` as you wish.
- Set the `Remote Storage` as `https://europe-west1-docker.pkg.dev`.
- For the authentication section, you should set `Username` as `_json_key` and `Password` as the content of the `cred.json` file. See the sample screenshot [here.](https://cdn.appcircle.io/docs/assets/nexus-proxy-settings-3.png)
- For SSL, the recommended way is to use a reverse proxy in front of Nexus.
:::tip
You can see some sample screenshots below from Nexus UI for a sample configuration.
- [Proxy repository settings](https://cdn.appcircle.io/docs/assets/nexus-proxy-settings-1.png)
- [Remote storage settings](https://cdn.appcircle.io/docs/assets/nexus-proxy-settings-2.png)
- [Authentication settings](https://cdn.appcircle.io/docs/assets/nexus-proxy-settings-3.png)
:::
- After you created the repository, you should add the below section to the `global.yaml` file with your Nexus registry `url`, `username` and `password`.
- If you can access your Nexus repository without authentication, you should leave the `username` and `password` fields empty and set `requiredLogin` to `false`.
```yaml
image:
registry:
url: registry.spacetech.com:8083/appcircle/docker-registry
username:
password:
requiredLogin: false
```
- For more detailed usage about the variables, you can check the [Appcircle Registry Configuration](#appcircle-registry-configuration) section.
:::caution
In order to proxy Appcircle's registry from the Nexus registry, the **`registry.url`** in `global.yaml` must end with
- `/appcircle/docker-registry`
The example `global.yaml` section above is suitable with the example Nexus proxy registry settings shown in the screenshots above.
:::
:::info
If you face any issue about "manifest not found" when you try to run `./ac-self-hosted.sh -n "spacetech" up`, try pulling the images one by one from the Nexus proxy registry.
[Pulling Images On By One](#pulling-images-one-by-one) script below will force Nexus to pull the images from Appcircle's registry one by one, not in parallel.
Nexus has some issues when pulling images in parallel.
:::
## Mirroring Images
You can mirror Appcircle container images from the Google Artifact Registry to your local registry.
Since there are many images to mirror, you can use a bash script to mirror the images instead of pulling, re-tagging, and pushing them back to your local registry.
To mirror images automatically, you can follow the steps below:
As a **pre-requirement**, you need to be authenticated to the Google Artifact Registry.
- You should already have a `cred.json` file, which you should have taken from us.
To authenticate with your container engine, run the command below:
```bash
cat cred.json | docker login -u _json_key --password-stdin europe-west1-docker.pkg.dev/appcircle/docker-registry
```
```bash
cat cred.json | podman login -u _json_key --password-stdin europe-west1-docker.pkg.dev/appcircle/docker-registry
```
You should see the "Login Succeeded" message after the command execution.
You can find all container images in the `docker-images.txt` file, which is in the Appcircle server package.
- If you are on the Appcircle server host, go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Create a bash script to mirror the container images.
```bash
vi mirror-images.sh
```
- Copy and paste the following code into the bash script:
```bash
#!/bin/bash
# Set the source registry URL
SRC_REGISTRY_URL="europe-west1-docker.pkg.dev/appcircle/docker-registry"
# Set the destination registry URL
DEST_REGISTRY_URL="registry.spacetech.com:8083/appcircle"
# Loop through each line of the file and pull, tag, and push the Docker image
while read -r IMAGE_NAME || [ -n "$IMAGE_NAME" ]; do
if [[ ${IMAGE_NAME:0:1} == "#" ]]; then
continue
fi
echo "Pulling image: $IMAGE_NAME"
docker pull $IMAGE_NAME
if [ $? -eq 0 ]; then
echo "Image pulled successfully: $IMAGE_NAME"
# Replace source registry URL with the new registry URL
IMAGE_TAG="${IMAGE_NAME/$SRC_REGISTRY_URL/$DEST_REGISTRY_URL}"
# Tag the image with the destination registry URL and repository name
docker tag $IMAGE_NAME $IMAGE_TAG
# Push the tagged image to the destination registry
docker push $IMAGE_TAG
if [ $? -eq 0 ]; then
echo "Image pushed successfully: $IMAGE_NAME"
else
echo "Failed to push image: $IMAGE_NAME"
fi
else
echo "Failed to pull image: $IMAGE_NAME"
fi
done < docker-images.txt
```
```bash
#!/bin/bash
# Set the source registry URL
SRC_REGISTRY_URL="europe-west1-docker.pkg.dev/appcircle/docker-registry"
# Set the destination registry URL
DEST_REGISTRY_URL="registry.spacetech.com:8083/appcircle"
# Loop through each line of the file and pull, tag, and push the Docker image
while read -r IMAGE_NAME || [ -n "$IMAGE_NAME" ]; do
if [[ ${IMAGE_NAME:0:1} == "#" ]]; then
continue
fi
echo "Pulling image: $IMAGE_NAME"
podman pull $IMAGE_NAME
if [ $? -eq 0 ]; then
echo "Image pulled successfully: $IMAGE_NAME"
# Replace source registry URL with the new registry URL
IMAGE_TAG="${IMAGE_NAME/$SRC_REGISTRY_URL/$DEST_REGISTRY_URL}"
# Tag the image with the destination registry URL and repository name
podman tag $IMAGE_NAME $IMAGE_TAG
# Push the tagged image to the destination registry
podman push $IMAGE_TAG
if [ $? -eq 0 ]; then
echo "Image pushed successfully: $IMAGE_NAME"
else
echo "Failed to push image: $IMAGE_NAME"
fi
else
echo "Failed to pull image: $IMAGE_NAME"
fi
done < docker-images.txt
```
:::caution
The sample value for **`DEST_REGISTRY_URL`** in the script above must be changed with your container image registry.
To find your destination registry URL, please head to your external image registry and check for pull/push command.
For example, if you're using
- `registry.spacetech.com:8083/appcircle/imagename:latest`
template for pull/push, the destination registry URL (**`DEST_REGISTRY_URL`**) should be
- `registry.spacetech.com:8083/appcircle`
Keep in mind that the destination image registry url **must not** end with `/`.
:::
- Make the `mirror-images.sh` script file executable.
```bash
chmod +x mirror-images.sh
```
- Run the script to mirror all the container images.
```bash
./mirror-images.sh
```
:::info
If your registry is not using HTTPS, you may get an error during the Docker/Podman push step.
You need to add your registry as an insecure registry. Please check the [Insecure Registry](#insecure-registry) section to configure an HTTP registry.
:::
## Insecure Registry
By default, Docker tries to connect to the server with HTTPS and from the `443` port.
If your registry is running over HTTP, then you should define your registry as an **insecure registry** in the Docker daemon.
Edit the `daemon.json` file, whose default location is `/etc/docker/daemon.json`.
```bash
sudo vi /etc/docker/daemon.json
```
If the `daemon.json` file does not exist, you should create it. Assuming there are no other settings in the file, it should have the following contents:
```json
{
"insecure-registries": ["registry.spacetech.com:8083"]
}
```
:::info
If you don't specify the port number in the `daemon.json` above, Docker will try to use the default HTTP port, which is `80`.
If your registry runs on a port other than `80`, you must specify it in the `daemon.json` file, like in the example above.
:::
Restart the Docker daemon for the changes to take effect.
```bash
sudo systemctl restart docker
```
By default, Podman tries to connect to the server with HTTPS and from the `443` port.
If your registry is running over HTTP, then you should define your registry as an **insecure registry** in the Podman configuration.
Edit the `registries.conf` file, whose default location is `/etc/containers/registries.conf`.
```bash
sudo vi /etc/containers/registries.conf
```
Copy the template content below, change the `location` to your registry URL, and paste it at the bottom of the `registries.conf` file.
```conf
[[registry]]
location = "registry.spacetech.com:8083"
insecure = true
```
:::info
If you don't specify the port number in the `registries.conf` above, Podman will try to use the default HTTP port, which is `80`.
If your registry runs on a port other than `80`, you must specify it in the `registries.conf` file, like in the example above.
:::
Now you can connect to your registry with HTTP without any errors.
## Pulling Images One By One
If you are having problems pulling all the images in parallel, like happens in `Nexus`, you can use the script below to pull images one by one.
- Create a bash script to to pull images one by one.
```bash
vi pull-images.sh
```
- Copy and paste the following code into the bash script:
```bash
#!/bin/bash
# Don't change this.
SRC_REGISTRY_URL="europe-west1-docker.pkg.dev/appcircle/docker-registry"
# Set the proxy registry URL.
DEST_REGISTRY_URL="registry.spacetech.com:8083/appcircle/docker-registry"
sed -i "s|${SRC_REGISTRY_URL}|${DEST_REGISTRY_URL}|g" docker-images.txt
# Loop through each container image name and pull the container image.
while read -r IMAGE_NAME || [ -n "$IMAGE_NAME" ]; do
if [[ ${IMAGE_NAME:0:1} == "#" ]]; then
continue
fi
echo "Pulling image: $IMAGE_NAME"
docker pull $IMAGE_NAME
if [ $? -eq 0 ]; then
echo "Image pulled successfully: $IMAGE_NAME"
else
echo "Failed to pull image: $IMAGE_NAME"
fi
done < docker-images.txt
sed -i "s|${DEST_REGISTRY_URL}|${SRC_REGISTRY_URL}|g" docker-images.txt
```
```bash
#!/bin/bash
# Don't change this.
SRC_REGISTRY_URL="europe-west1-docker.pkg.dev/appcircle/docker-registry"
# Set the proxy registry URL.
DEST_REGISTRY_URL="registry.spacetech.com:8083/appcircle/docker-registry"
sed -i "s|${SRC_REGISTRY_URL}|${DEST_REGISTRY_URL}|g" docker-images.txt
# Loop through each container image name and pull the container image.
while read -r IMAGE_NAME || [ -n "$IMAGE_NAME" ]; do
if [[ ${IMAGE_NAME:0:1} == "#" ]]; then
continue
fi
echo "Pulling image: $IMAGE_NAME"
podman pull $IMAGE_NAME
if [ $? -eq 0 ]; then
echo "Image pulled successfully: $IMAGE_NAME"
else
echo "Failed to pull image: $IMAGE_NAME"
fi
done < docker-images.txt
sed -i "s|${DEST_REGISTRY_URL}|${SRC_REGISTRY_URL}|g" docker-images.txt
```
:::info
You should replace the `DEST_REGISTRY_URL` variable per your needs.
Let's assume that the URL of your Sonatype Nexus proxy registry is
- `registry.spacetech.com:8083`
and your container image pull command without an image name is
- `registry.spacetech.com:8083/appcircle/docker-registry`
Then the **`DEST_REGISTRY_URL`** should be like below:
- `registry.spacetech.com:8083/appcircle/docker-registry`
:::
- Make the `pull-images.sh` script file executable.
```bash
chmod +x pull-images.sh
```
- Run the script to pull all the container images one by one.
```bash
./pull-images.sh
```
---
## Server Configuration
Explore the essential settings and customizations for maintaining your self-hosted Appcircle servers.
## [Integrations and Access](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access)
Set up and manage integrations with third-party services, and configure access controls to ensure secure and efficient operation.
## [Advanced Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration)
Delve into detailed settings to fine-tune your server performance, including memory management, network configurations, and more.
## [Restarting Host](/self-hosted-appcircle/install-server/linux-package/configure-server/restarting-host)
Learn how to safely restart your Appcircle host server to apply updates or troubleshoot issues without disrupting ongoing processes.
## [Offline Install/Upgrade](/self-hosted-appcircle/install-server/linux-package/configure-server/offline-installation)
Guidelines for installing or upgrading your Appcircle server without an active internet connection, ensuring continuity in restrictive network environments.
## [External Image Registries](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry)
Manage connections to external image registries, allowing you to utilize custom Docker images for your builds and workflows.
## [Testing Distribution](/self-hosted-appcircle/install-server/linux-package/configure-server/testing-distribution)
Configure your server to distribute test versions of your apps, enabling early feedback and iteration in the development cycle.
## [Enterprise App Store](/self-hosted-appcircle/install-server/linux-package/configure-server/enterprise-store)
Set up your private App Store for enterprise app distribution, providing a secure and convenient way to deploy internal applications.
## [Auto-upgrading Server](/self-hosted-appcircle/install-server/linux-package/configure-server/auto-updating)
Discover the process for enabling automatic updates on your Appcircle server, ensuring your system remains up-to-date with the latest features and security enhancements.
## [Domain Verification](/self-hosted-appcircle/install-server/linux-package/configure-server/domain-verification)
Learn how to configure your Appcircle server's domain verification option when adding domains as trusted for Appcircle organizations.
## [Monitoring](/self-hosted-appcircle/install-server/linux-package/configure-server/monitoring)
Learn how to monitor your Appcircle server through the Grafana web interface, enabling you to oversee server performance remotely without the need to access the Appcircle server console directly.
---
## Git Providers
With default installation, self-hosted Appcircle comes with the connection options below:
- Bitbucket
- Azure
- GitLab
- GitHub
- Connect via SSH
- Connect via URL
You can configure the Git providers and use them within your self-hosted Appcircle server, the same as in the cloud.
The following sections will give you more details about how to enable or disable Git providers according to your requirements in your hosted environment.
:::info
We're assuming that previously you reviewed or followed [install self-hosted appcircle](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in docs, understood configuration made there and scenarios told there.
:::
:::caution
Current working directory is assumed `appcircle-server` for following steps. See [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download) for installation details.
:::
:::caution
`global.yaml` configuration file is located under **project** folder.
- `projects/${YOUR_PROJECT}`
You can see an example project configuration from [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure).
:::
## Connect to Bitbucket
To disable the "Bitbucket" option, add the below configuration to `global.yaml`.
```yaml
build:
oauths:
bitbucket:
enabled: false
bitbucketServer:
enabled: false
```
If you want to re-enable "Bitbucket" again, you can set the `enabled` to `true`.
You can configure only the self-hosted or cloud "Bitbucket" options using the relevant keys.
- The `bitbucket` key is used to manage **Bitbucket (Cloud)**.
- The `bitbucketServer` key is used to manage **Bitbucket Server**.
For more details about "Bitbucket" usage, see related docs in the [Connecting to Bitbucket](/build/manage-the-connections/connection-guides/connecting-to-bitbucket) page.
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
## Connect to Azure DevOps
To disable the "Azure DevOps" option, add the below configuration to `global.yaml`.
```yaml
build:
oauths:
azureDevopsServices:
enabled: false
azureDevopsServer:
enabled: false
```
If you want to re-enable "Azure DevOps" again, you can set the `enabled` to `true`.
You can configure only the self-hosted or cloud "Azure DevOps" options using the relevant keys.
- The `azureDevopsServices` key is used to manage **Azure DevOps Services (Cloud)**.
- The `azureDevopsServer` key is used to manage **Azure DevOps Server**.
For more details about "Azure DevOps" usage, see related docs in the [Connecting to Azure DevOps](/build/manage-the-connections/connection-guides/connecting-to-azure) page.
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
## Connect to GitLab
To disable the "GitLab" option, add the below configuration to `global.yaml`.
```yaml
build:
oauths:
gitlab:
enabled: false
gitlabSelfHosted:
enabled: false
```
If you want to re-enable "GitLab" again, you can set the `enabled` to `true`.
You can configure only the self-hosted or cloud "GitLab" options using the relevant keys.
- The `gitlab` key is used to manage **GitLab (Cloud)**.
- The `gitlabSelfHosted` key is used to manage **GitLab Self-Managed**.
For more details about "GitLab" usage, see related docs in the [Connecting to GitLab](/build/manage-the-connections/connection-guides/connecting-to-gitlab) page.
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
## Connect to GitHub
To disable the "GitHub" option, add the below configuration to `global.yaml`.
```yaml
build:
oauths:
githubApp:
enabled: false
githubEnterpriseServer:
enabled: false
```
If you want to re-enable "GitHub" again, you can set the `enabled` to `true`.
You can configure only the self-hosted or cloud "GitHub" options using the relevant keys.
- The `githubApp` key is used to manage **GitHub (Cloud)**.
- The `githubEnterpriseServer` key is used to manage **GitHub Enterprise Server**.
For more details about "GitHub" usage, see related docs in the [Connecting to GitHub](/build/manage-the-connections/connection-guides/connecting-to-github) page.
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
:::info
GitHub Enterprise Server option is available in version `3.28.2` or later.
:::
### GitHub App Cloud
The [GitHub App](https://docs.github.com/en/apps/using-github-apps/about-using-github-apps) option is `disabled` by default since it needs further custom configuration for your setup.
If you want to connect to GitHub Cloud using the GitHub App, you need to **[create your own GitHub App](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps)** for your organization. Below are the key points that you should follow while creating a GitHub App for your Appcircle server.
#### Requirements
:::info
"GitHub App Cloud `OAuth2`" connection option is available in version `3.29.3` or later.
:::
While creating your own GitHub App, you will need some domains from the Appcircle server for URLs. Therefore, before beginning, you should have been gotten the below domains ready for your GitHub App configuration.
- Log in to the Appcircle server with SSH or a remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Update the environment variable `PATH` with the required dependencies.
```bash
export PATH=$PATH:$(pwd)/deps/bin
```
:::info
URL samples in the following steps are based on sample [DNS settings](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings) from the Appcircle server installation.
:::
**1.** Get **dashboard** URL.
```bash
yq '.webApp.external.url' ./projects/spacetech/export/.global.yaml
```
For example, `https://my.appcircle.spacetech.com`
**2.** Get **IAM** URL.
```bash
yq '.keycloak.external.url' ./projects/spacetech/export/.global.yaml
```
For example, `https://auth.appcircle.spacetech.com`
**3.** Get **API** URL.
```bash
yq '.apiGateway.external.url' ./projects/spacetech/export/.global.yaml
```
For example, `https://api.appcircle.spacetech.com`
#### Configuration
Below are the configuration steps you should follow for setting up the GitHub App.
1. Give a name to your GitHub App using the "GitHub App name" field.
1. For example, `MyAwesomeApp`
2. Enter the **dashboard** URL in the "Homepage URL" field.
1. For example, `https://my.appcircle.spacetech.com`
3. Add "Callback URL" using the **API** URL and appending `/build/v1/callback?gitProvider=GithubApp` to the end of the URL.
1. For example, `https://api.appcircle.spacetech.com/build/v1/callback?gitProvider=GithubApp`
4. Add "Callback URL" using the **IAM** URL and appending `/auth/realms/appcircle/broker/githubapp/endpoint?gitProvider=GithubApp` to the end of the URL.
1. For example, `https://auth.appcircle.spacetech.com/auth/realms/appcircle/broker/githubapp/endpoint?gitProvider=GithubApp`
5. The "Request user authorization (OAuth) during installation" option in the "Identifying and authorizing users" section should be in the `checked` state.
6. The "Redirect on update" option in the "Post installation" section should be in the `checked` state.
7. Webhook should be "Active", and enter the **API** URL as "Webhook URL" by appending `/build/v1/hooks/github` at the end.
1. For example, `https://api.appcircle.spacetech.com/build/v1/hooks/github`
8. Select the "Enable SSL verification" option in the "SSL Verification" for better security practices if your SSL certificates can be trusted by GitHub.
9. Select required "Repository" permissions using [permissions for the GitHub integration](https://docs.appcircle.io/build/manage-the-connections/adding-a-build-profile/connecting-to-github#oauth2-and-personal-access-token-permissions-for-github-integration) guide.
10. Select "Webhooks" as "Read and Write" in the "Organization" permissions.
11. Select the below events in the "Subscribe to events" to be triggered from GitHub:
1. `Create`
2. `Commit comment`
3. `Delete`
4. `Pull request`
5. `Push`
6. `Repository`
7. `Status`
When you complete your GitHub App configuration on GitHub, you are ready to move on to using it in the Appcircle.
---
In order to **activate your GitHub App on the Appcircle server**, you should fill in the below settings in your `global.yaml` using your GitHub App properties.
```yaml
build:
oauths:
githubAppOauth:
enabled: true
clientId:
clientSecret:
authorizeUrl:
```
You can find all the required values in the "About" page under the "General" tab at the GitHub App configuration page.
- **`clientId`**: It's the "Client ID" of your GitHub App.
- For example, `Iv2***qEI***x8H***ys`
- **`clientSecret`**: "Create a new client secret" for your GitHub App.
- For example, `222***a8f***2a1***4a0***5f3***b8a***b8a8`
- **`authorizeUrl`**: Use "Public link", appending `/installations/new` to the end.
- For example, `https://github.com/apps/myawesomeapp/installations/new`
:::caution
As in the example above, replace the `{app_name}` with your actual GitHub App name;
- `https://github.com/apps/{app_name}/installations/new`
:::
According to the sample GitHub App properties above, your `global.yaml` settings should be like below.
```yaml
build:
oauths:
githubAppOauth:
enabled: true
clientId: "Iv2***qEI***x8H***ys"
clientSecret: "222***a8f***2a1***4a0***5f3***b8a***b8a8"
authorizeUrl: "https://github.com/apps/myawesomeapp/installations/new"
```
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
After successfully applying, the "GitHub App Cloud `OAuth2`" option will be visible under "GitHub Cloud Connection" options when you create a new connection for a build profile.
:::info
"GitHub App Cloud `OAuth2`" connection option is available in version `3.29.3` or later.
:::
:::caution
Currently, GitHub App connection is **supported for only GitHub Cloud** (github.com) connections.
You cannot use the GitHub App for a GitHub Enterprise Server connection.
:::
## Connect via SSH
To disable the "Connect via SSH" option, add the below configuration to `global.yaml`.
```yaml
build:
oauths:
ssh:
enabled: false
```
If you want to re-enable "Connect via SSH" again, you can set the `enabled` to `true`.
For more details about "Connect via SSH" usage, see related docs in the [Connect via SSH](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) page.
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
## Connect via URL
To disable the "Connect via URL" option, add the below configuration to `global.yaml`.
```yaml
build:
oauths:
publicRepository:
enabled: false
```
If you want to re-enable "Connect via URL" again, you can set the `enabled` to `true`.
For more details about "Connect via URL" usage, see related docs in the [Connect via URL](/build/manage-the-connections/connection-guides/connecting-to-public-repository) page.
To apply the changes, please follow the [Applying Git Provider Changes](#applying-git-provider-changes) section at the end.
## Applying Git Provider Changes
You can add or remove git providers at [installation](/self-hosted-appcircle/install-server/linux-package/installation/docker) steps or later when you need. Following sections will explain how to apply changes especially after installation.
Let's assume we want to disable both "Connect via SSH" and "Connect via URL" options. Then we need to add below configuration to our `global.yaml`.
```yaml
build:
oauths:
ssh:
enabled: false
publicRepository:
enabled: false
```
:::caution
You should have only one `build.oauths` key in your `global.yaml` file.
Keep in mind that if you have multiple `build.oauths` keys in `global.yaml`, then the last one will be used in the Appcircle server runtime.
Be careful while configuring different connection options at the same time. Union them under one `build.oauths` key in the `global.yaml`.
:::
If we **do** this at installation time then there is no extra step to take. These options will be disabled on first boot without any extra effort.
If we **don't do** the configuration at installation, then after editing `global.yaml`, we need to apply below steps to activate changes.
:::info
We're assuming that previously you reviewed or followed [install self-hosted appcircle](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in docs and applied example scenario.
Following steps are using example project as project naming, which was told there.
:::
1. Shutdown Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
2. Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
3. Boot Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
On complete, refresh your browser and login to Appcircle with your account. You should see that "Connect via SSH" and "Connect via URL" option is disabled on the connection page. :tada:
---
## Integrations and Access
A crucial part of setting up your self-hosted Appcircle environment involves configuring various integrations and access controls. This section provides detailed guides for connecting your Appcircle instance with external services and setting up the necessary access configurations.
### [Git Providers](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/git-providers)
Connect with popular Git providers like GitHub, GitLab, Bitbucket, etc., to seamlessly integrate your code repositories with your CI/CD pipeline.
### [Integrations](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration)
Manage additional service integrations to enhance the functionality of your self-hosted instance with tools for monitoring, logging, analytics, and more.
### [SSL Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration)
Ensure secure communications by configuring SSL, which is vital for protecting your data and maintaining trust with users interacting with your server.
### [Network Access](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access)
Set up network access rules to define how your server communicates with other networks and services, including firewall settings and access permissions.
### [Login Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/login-configuration)
Customize login settings for your server to determine how users will authenticate and gain access to the Appcircle platform.
### [Proxy Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration)
Configure proxy settings for your server to route traffic through a proxy server, which can be crucial for complying with network policies or enhancing security.
### [LDAP Settings](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings)
Integrate with LDAP (Lightweight Directory Access Protocol) for centralized user management, allowing users to sign in with their enterprise credentials.
---
## Integrations
There are mainly two integrations to be filled by the user
- Email
- SSO
## Email
Appcircle provides two methods to configure SMTP settings.
:::info
`spacetech` is an example organization name used in the example values below. It should be replaced with your own organization name.
:::
### Configure via Dashboard (recommended)
Starting from the version `3.28.2`, SMTP settings can be configured and updated directly from the Appcircle Dashboard. This is the recommended approach for managing SMTP settings as it allows you to update the configuration at any time without requiring server reset.
:::caution
The "SMTP Configuration" page is located under the **Admin** menu. This menu is only visible when you are logged in as the **Initial User** (the user defined in the `global.yaml`/`values.yaml` file).
:::
- To reach the "SMTP Configuration" section, navigate to the "Admin > Self-Hosted Settings" page using the left menus.
- Press the "Manage" button next to "SMTP Configuration".
- You will see the SMTP configuration page.
- Fill in the SMTP settings according to your mail server. See the details below for configuration options:
| Settings | Description | Example |
|----------|-------------|---------|
| FROM | The default email address used in the "From" field for outgoing emails. | noreply@spacetech.com |
| FROM DISPLAY NAME | The display name that appears alongside the default from address in outgoing emails. | Spacetech |
| HOST | The hostname or IP address of the SMTP server. | email-smtp.spacetech.com |
| PORT | The port number to connect to on the SMTP server (typically 25, 465, or 587). | 587 |
| Use SSL | Specifies whether SSL encryption should be used for the SMTP connection. | Off |
| Start TLS | Determines whether to enable STARTTLS, which upgrades a plain connection to a secure one. | On |
| Validate Server Cert | Specifies whether the SMTP server's SSL certificate should be validated. It is recommended to keep this as turned on for security purposes. | On |
| Auth | Indicates whether SMTP authentication is required. It should be turned on if both username and password are necessary for the SMTP server authentication. | On |
| USERNAME | The username for SMTP server authentication. | your_username |
| PASSWORD | The password for authenticating with the SMTP server. | your_password |
| TO (optional) | The email address that will receive the test email when you use the "Test Connection" button. This address is only used for testing SMTP connectivity and does not affect regular outgoing emails. | mobile-team@spacetech.com |
- Click the "Test Connection" button to verify that the connection to your SMTP server is successful. If the test fails, check your settings and try again.
- If your settings are correct, click the "Save" button to apply the settings.
:::info
Email notifications use the "FROM DISPLAY NAME" as the sender name (or from name).
However, when you [share a binary](https://docs.appcircle.io/testing-distribution/create-or-select-a-distribution-profile#share-binary) using the **Testing Distribution** module, the **profile name** will be displayed as the sender, as shown in the example email provided in the linked documentation.
:::
### Configure via `global.yaml`
If you prefer to configure the SMTP settings via `global.yaml` for initial installation, you can edit the `global.yaml` file and change SMTP settings according to your mail server.
See the example below for configuration options:
```yaml
smtpServer:
password: your_password
user: your_username
from: noreply@spacetech.com
host: email-smtp.spacetech.com
fromDisplayName: Spacetech
port: '587'
ssl: 'false'
auth: 'true'
starttls: 'true'
verifyCertificate: 'true'
```
:::tip
Even if you initially configure SMTP using `global.yaml`, you can still use the Appcircle Dashboard for subsequent updates.
But **keep in mind that** beforehand you should remove the relevant settings from the `global.yaml` effectively, which requires you to apply configuration changes and restart the Appcircle server. Otherwise, the settings that came from the static config will be non-editable in the Appcircle Dashboard "SMTP configuration" form.
:::
Explanation of each key:
| Key | Explanation |
|-------------------|-----------------------------|
| password | Password of the SMTP server |
| username | Default user name for SMTP |
| from | Sender address of the emails |
| host | The SMTP server to connect to |
| fromDisplayName | Sender Display Name |
| port | The SMTP server port to connect |
| ssl | If set to `true`, use SSL to connect |
| auth | If set to `true`, attempt to authenticate the user using the AUTH command. |
| starttls | If set to `true`, enables the use of the STARTTLS command |
| verifyCertificate | If set to `false`, disables validation of the SMTP server's SSL certificate. The value is `true` by default, shouldn't be disabled in production environments. |
:::info
The `verifyCertificate` option is available in version `3.23.1` or later.
:::
:::info
Email notifications use the `fromDisplayName` as the sender name (or from name).
However, when you [share a binary](https://docs.appcircle.io/testing-distribution/create-or-select-a-distribution-profile#share-binary) using the **Testing Distribution** module, the **profile name** will be displayed as the sender, as shown in the example email provided in the linked documentation.
:::
## SSO
Appcircle supports both OpenID and SAML Identity providers. You can follow the below documents to connect your identity providers. If your Identity Provider is not on the list, you can follow any OpenID or SAML integration guide from the below list to find out the parameters.
- [Auth0 OpenID](https://docs.appcircle.io/account/sso/auth-openid/)
- [Auth0 SAML](https://docs.appcircle.io/account/sso/auth-saml/)
- [Azure AD SAML](https://docs.appcircle.io/account/sso/azure-saml/)
- [Okta OpenID](https://docs.appcircle.io/account/sso/okta-openid/)
- [Okta SAML](https://docs.appcircle.io/account/sso/okta-saml/)
- [OneLogin SAML](https://docs.appcircle.io/account/sso/onelogin-saml/)
---
## LDAP Settings
## User Lookup Decision Settings
The LDAP (Lightweight Directory Access Protocol) user lookup decision strategy is a crucial aspect of user authentication in applications that utilize LDAP for user management.
When Appcircle receives a user login request from the Enterprise App Store or Testing Distribution, it needs to determine which LDAP configuration to use for the user lookup and authentication process.
In scenarios where a user exists in multiple LDAP configurations, a decision must be made on which configuration to use for authentication.
This documentation provides insights into the LDAP user lookup decision strategy and how it can be configured to handle scenarios where a user has multiple usernames and passwords across different LDAP configurations.
### Editing User Lookup Decision Strategy
To configure LDAP lookup decision settings, you can follow the steps below.
:::info
We're assuming that previously you reviewed or followed [install self-hosted appcircle](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in docs and applied example scenario.
Following steps are using example project as project naming, which was told there.
:::
- Go to the Appcircle server directory.
```bash
cd appcircle-server
```
- Edit the `global.yaml` of the project.
```bash
vi projects/spacetech/global.yaml
```
- Find the keycloak entry and add the `userLookupDecisionStrategy` entry to it. For example;
```yaml
keycloak:
initialUsername: admin@spacetech.com
enabledRegistration: true
userLookupDecisionStrategy: affirmative
```
:::info
The `userLookupDecisionStrategy` variable can have three options: `affirmative` , `decisive` or `tolerant`.
If you don't define it or it has an unknown value, it is assumed to be `decisive` by default.
#### Affirmative
When `userLookupDecisionStrategy` is set to "affirmative", the LDAP authentication process will check all LDAP settings, even if the user is found on a particular LDAP configuration. This means that if a user has multiple accounts on different LDAP configurations with different passwords, they will be able to login successfully. The authentication system will search across all LDAP configurations to find a matching username or email and validate the user's password, allowing the user to access the system.
#### Decisive
On the other hand, when `userLookupDecisionStrategy` is set to "decisive", the LDAP authentication process will check a specific LDAP configuration for the user's username or email. If the authentication system finds the username on a particular LDAP, it will verify the user's password only on that specific LDAP configuration. If the provided password is incorrect, the authentication system will not check other LDAP configurations and will immediately return invalid credentials, denying access to the user.
#### Tolerant
When `userLookupDecisionStrategy` is set to "tolerant", similar to the "affirmative" strategy, it retrieves the list of LDAP providers where the user is found and checks the password sequentially. If the password is correct, the process ends. If it is incorrect, the search continues until the last LDAP provider. Unlike "affirmative", if an LDAP provider is unreachable or an error occurs, the process continues, and the faulty provider is ignored.
:::
### Applying Changes
After you configure the `global.yaml` of the project, you should restart the Appcircle server for the settings to take effect.
- Stop the server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Apply the configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start the server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
- Check the health of the services.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
### Testing the LDAP Auth
#### 1. Configure multiple LDAPs on server
Ensure that multiple LDAP settings are properly configured on your Appcircle server's [LDAP Authentication Settings](/account/my-organization/security/authentications).
#### 2. Create users with the same username
In each of the configured LDAPs, create user accounts with the same username but different passwords.
For example, you can create users with the username "spacetechuser" in both LDAP configurations, each with unique passwords.
This setup will mimic the scenario where a user has multiple accounts on different LDAPs.
#### 3. Test LDAP authentication with users
Use the "spacetechuser" credentials to attempt a login to the application. For example, enterprise app store or testing distribution
The `affirmative` LDAP authentication strategy will kick in during this test.
#### Verification
If the "spacetechuser" provides the correct password that matches the user's credentials in one of the configured LDAPs, the authentication system will grant access to the Enterprise App Store or Testing Distribution profile.
The `affirmative` strategy ensures that the authentication process checks all LDAP configurations to find a matching username and validate the user's password.
If the "spacetechuser" provides an incorrect password that does not match the user's credentials in any of the LDAP configurations, the authentication process will continue checking all the other LDAPs.
If it finds a matching username with the correct password in any of the other LDAP configurations, the user will be granted access.
## Appcircle Login with LDAP
Appcircle login with LDAP aims to provide an alternative authentication solution via the LDAP server. Appcircle's LDAP integration allows businesses to integrate existing directory services, especially Active Directory, directly into the Appcircle login process. This integration simplifies user management.
The LDAP distinguished name (DN) is associated with existing Appcircle registered users when:
- The existing user signs in to Appcircle with LDAP for the first time.
- The LDAP email address is the email address of an existing Appcircle user.
If the LDAP email attribute isn’t found in the Appcircle user database, a new user is created.
If existing Appcircle users want to enable LDAP to sign in for themselves, they should:
- Check that their Appcircle user email address matches their LDAP user email address.
- Sign in to Appcircle by using their LDAP credentials.
:::caution
This feature only provides a solution for self-hosted Appcircle server installations. Appcircle Login with LDAP is not possible for Appcircle Cloud users.
:::
### Attribute Configuration Settings
Appcircle requires users to log in using an email address.
For LDAP integrations, all users must have a valid email address, even if that email isn’t used for signing in to other applications.
Appcircle uses these LDAP attributes to create an account for the LDAP user.
| Settings | Description | Required | Examples |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------- |
| Name | Descriptive name for your LDAP configuration. | Yes | ldap-europe, ldap-support |
| Order | Priority number for LDAP connections. Lower numbers have higher priority. | Yes | 1, 2, 3 |
| Vendor | Type of LDAP server vendor. Used to apply vendor-specific defaults (e.g., AD, OpenLDAP). | Yes | Active Directory, OpenLDAP, Other |
| User Mail LDAP Attribute | Name of LDAP attribute, which is mapped as user mail. For many LDAP server vendors it can be 'mail'. | Yes | mail,email |
| RDN LDAP Attribute | The attribute used as the Relative Distinguished Name (RDN) when building user DNs. Often `uid` or `cn`. | Yes | cn, uid |
| UUID LDAP Attribute | Unique identifier for LDAP users. Commonly `entryUUID` or `uid`. For Active Directory it should be 'objectGUID'. | Yes | objectGUID, entryUUID, uid |
| User Object Classes | Comma-separated list of LDAP object classes to be considered user entries. | Yes | person, organizationalPerson, user |
| Connection URL | LDAP server connection URL. Must include the scheme (`ldap://` or `ldaps://`) and host (optionally with port). | Yes | ldap://openldap:389 |
| Users DN | Full DN of the LDAP tree where your users exist. This DN is the parent of LDAP users. It could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have a DN such as 'uid='john',ou=users,dc=example,dc=com'. | Yes | ou=users,dc=example,dc=com |
| Custom User LDAP Filter | Additional LDAP filter for filtering searched users. Leave this empty if you don't need an additional filter. Make sure that it starts with '(' and ends with ')'. | No | (objectClass=inetOrgPerson) |
| Phone Number LDAP Attribute | The LDAP attribute that stores the user’s phone number. | No | telephoneNumber, mobile |
| Search Scope | For one level, the search applies only for users in the DNs specified by User DNs. For subtree, the search applies to the whole subtree. | Yes | One Level, Subtree |
| Bind Type | Type of the authentication method used during LDAP bind operation. It is used in most of the requests sent to the LDAP server. Currently only 'none' or 'simple' (bind credential + bind password authentication) mechanisms are available. | Yes | Simple, None |
| Bind DN | DN of the LDAP admin, which will be used by Appcircle to access LDAP server. | Yes | cn=admin,dc=io |
| Bind Credential | Password of LDAP admin. | Yes | ******** (hidden) |
| Enable StartTLS | Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling. | No | |
| Connection Timeout | LDAP connection timeout in milliseconds. | No | |
| Read Timeout | LDAP read timeout in milliseconds. This timeout applies for LDAP read operations. | No | |
| Pagination | Enables retrieving LDAP users and groups in smaller batches instead of all at once. This improves performance for large directories by reducing memory and network load. | No | |
| Test Connection | Tests if the LDAP connection can be successfully established using the provided configuration and credentials. | - | |
| Test Authentication | Tests if LDAP authentication works correctly with the configured Bind DN and credentials. | - | |
| Group Mapper | Defines how LDAP groups are mapped to internal groups. Used in LDAP mapping for importing or synchronizing group memberships. | No | |
| Role Mapper | Defines how LDAP roles are mapped to internal roles. Used in LDAP mapping for importing or synchronizing group or attribute-based roles. | No | |
:::info
Common LDAP distinguished name (DN) attributes and their abbreviations used in LDAP configurations:
* **DC:** domainComponent
* **CN:** commonName
* **OU:** organizationalUnitName
* **O:** organizationName
* **STREET:** streetAddress
* **L:** localityName
* **ST:** stateOrProvinceName
* **C:** countryName
* **UID:** userid
:::
### Adding LDAP Configuration
- To get started, click on the "Admin" button from the left menu.
- Go to the "Self-Hosted Settings" screen.
- And press the "Connect" button next to "LDAP Login".
- Click on the "Create" button to create your LDAP configuration.
- Enter the details of your LDAP configuration.
:::caution
After you fill out the LDAP configuration form, it's strongly recommended that you test the configuration using the test buttons below.
- Test Connection
- Test Authentication
:::
:::info
Appcircle supports multiple LDAP configurations. If you are using multiple LDAP configurations and a user exists in both LDAPs, user authentication will look at the LDAP order.
The "Order" field when adding a LDAP configuration is required to do this ordering.
LDAP configuration with an order value of `1` will be used before LDAP configuration with an order value of `2` in user authentication.
:::
:::warning LDAP Connection Timeout
When the LDAP server is unreachable, login attempts by admin users not linked to LDAP may experience a delay.
The authentication process will wait for the LDAP connection to time out before proceeding, after which the login will be successful. By default, this timeout is set to 2 minutes but can be adjusted in the LDAP configuration settings.
:::
### Remove User From LDAP Server
If the user is deleted via LDAP, users coming from LDAP or previously connected users cannot log in to the system. And users who are logged in are automatically logged out.
### Remove LDAP Configuration
You can quickly remove your saved LDAP configuration from Appcircle Login.
- To delete a LDAP configuration, press the "Manage" button next to the "LDAP Login" option on the "Self-Hosted Settings" page.
- Select the LDAP configuration you want to delete and click on the "Remove" button.
After confirmation, the LDAP configuration will be deleted from Appcircle.
:::info
If a user is logged in to Appcircle with an LDAP configuration and that LDAP configuration is removed, the user will not be able to register in Appcircle.
This user is also removed from the organization in Appcircle.
:::
## LDAP Mapping
LDAP Mapping in Appcircle allows you to synchronize user groups and roles from your LDAP directory to your Appcircle environment seamlessly. This guide provides a step-by-step approach to setting up and managing LDAP mappings, ensuring your user and role integrations are as efficient as possible.
### Group And Role Mapper Configuration
Group and role mapper configuration must be completed before starting the LDAP mapping configuration. The LDAP group and role mapper define how groups and roles are retrieved from LDAP.
You can configure it using the following steps:
1. To get started, click on the **Admin** button from the left menu.
2. Go to the **Self-Hosted Settings** screen.
3. And press the **Manage** button next to **LDAP Login**.
4. Click the **Set Up LDAP Configuration**, then click **Edit** button in your LDAP provider.
5. In the **LDAP Connection screen**, scroll down to find the **Group Mapper** and **Role Mapper** sections.
6. Click the **Add** button next to the Group Mapper to create a proper group mapper configuration for retrieving groups and members from LDAP.
7. Click the **Add** button next to the Role Mapper to create proper role mapper configuration for retrieving roles and members from LDAP.
### Accessing LDAP Settings
To configure LDAP Mapping, follow these steps:
1. Navigate to the **Admin** section on your dashboard.
2. Select **Self-Hosted Settings** and click on **LDAP Login** to access the LDAP configuration options.
### Configuring LDAP Mapping
#### Setting Up LDAP Configuration
- **Select LDAP Configuration**: Begin by selecting your LDAP configuration from the dropdown menu. This is where you define and select the LDAP source to be used for mapping.
- **LDAP Groups and Appcircle Organizations**: Choose an LDAP group and the corresponding Appcircle organization you want to synchronize.
#### Associating LDAP Groups with Appcircle Organizations
- **Mapping LDAP Groups**: After selecting the LDAP group, map it to an Appcircle organization by clicking **Add**. This establishes a link where users from the LDAP group are automatically mapped to the corresponding organization in Appcircle.
:::caution
- Appcircle Organizations must be created manually before using them with LDAP Mapping.
:::
### Managing LDAP Groups and Mappings
- **View Configurations**: All active LDAP mappings can be viewed under the LDAP Mapping section. You can modify or delete each mapping as needed by using the **Config** option.
### LDAP Role Mapping
LDAP Role Mapping allows you to assign specific roles to users based on their LDAP group memberships. This feature streamlines user management by automatically assigning roles to users based on their LDAP role associations.
#### Configuring Role Mappings
- Navigate to the **LDAP Role Mapping** section where you can assign specific Appcircle roles based on the LDAP roles assigned to users.
- **Add a New Role**: Select a role from the available LDAP roles and assign it to users within the specified Appcircle organization. Roles such as administrator, developer, or custom group roles can be mapped accordingly.
#### Role and Permissions Management
- Each role can have varied permissions across different modules such as Build, Deploy, and Admin settings. Configure these permissions to ensure users have appropriate access levels based on their role.
### LDAP Synchronization
You can synchronize users from LDAP groups to Appcircle organizations using LDAP Synchronization. This process involves adding new users and removing unnecessary ones.
:::info
If you configure an Appcircle organization for synchronization, the synchronization task will override any manual configurations.
Please note that the synchronization is one-way from LDAP to Appcircle, meaning changes made in Appcircle do not affect LDAP.
:::
:::caution
- The sync operation does not fetch all users. If a user has not logged in before, they will join the organization with the assigned roles as soon as they log in, provided LDAP Mapping is enabled.
- If a user does not exist in Appcircle (has not been imported yet), they will be ignored by the synchronization task.
- The synchronization operation also does not affect the admin user. Even if the admin user is not in the LDAP group, they remain a member of the Appcircle organization.
- Appcircle Root Organizations must have at least one owner. The synchronization operation will not remove a user if they are the last owner of the root organization.
- You need to run the synchronization task once for users who are already in Appcircle and linked to LDAP.
:::
#### Enabling and Managing Synchronization
- **Activate Synchronization**: Toggle the LDAP Synchronization option to enable automatic syncing between LDAP and Appcircle.
- **Manual Sync and Interval Settings**: Use the **Sync Now** button to manually trigger a sync or set a synchronization interval to automate the process at regular intervals.
### Conclusion
Setting up LDAP Mapping streamlines user management by automating the synchronization of user roles and groups from LDAP into Appcircle. This guide should assist you in effectively managing user access and roles within your organization, ensuring security and efficiency in your app development processes.
## Troubleshooting
:::info
If the LDAP configuration is incorrect or the LDAP server cannot be accessed for some reason, you can always login with the "initial username" and "initial password" that were configured while installing the server.
See the [configure](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in the installation page for the `global.yaml` details.
:::
---
## Login Configuration
## Overview
Self-hosted Appcircle server `3.9.0` or later versions support enabling or disabling "User Registration" and "Forgot Password" from the "Self-Hosted Settings" admin page.
If your organization has configured LDAP or SSO authentication for the Appcircle users, you may want to disable the email signup flow.
Allowing email signup could result in having users registered both through LDAP/SSO and through email.
This can create duplicate users and make user management more difficult. Disabling email signup ensures all users are created through your centralized LDAP or SSO provider, avoiding duplication.
Just keep in mind that disabling email signup means new users will need to be created directly in your LDAP or SSO provider first before they can sign in to Appcircle.
Disabling email signup also prevents unwanted or unknown users from signing up for accounts through the email flow.
With LDAP or SSO, only users explicitly added to those systems can gain access, keeping tighter control over who can login to Appcircle.
Also, keeping the forgotten password flow open allows users to reset their password. But keep in mind that if a user resets his or her password, the user will no longer be an LDAP user.
It will be better to disable forgotten password flow after you enable LDAP or SSO for authentication.
## Login Settings
In this area, you can manage the creation of new users using the "Sign up with e-mail" button and the renewal of passwords using the "Forgot Password?" button.
You can reach "Login Settings" by navigating to "Admin > Self-Hosted Settings" page.
### User Registration
If this setting is `on`, your users can register to Appcircle and perform operations with this user except LDAP or other authentication methods. If you want only your LDAP users to log in to the system, you need to keep this setting `off`.
Click on the "Save" button to apply the settings.
:::info
If this setting is `off`, the "Sign up with e-mail" button will not appear on the Appcircle login page.
:::
#### Configure Emails That Can Be Used for Registration
With the Appcircle server version `3.13.0`, Appcircle disables users from registering with disposable (temporary) emails and common emails like Gmail, Outlook, etc. by default.
If you want to change this behavior, you can configure it in the `global.yaml` file of your project by following the steps below.
:::caution
Keep in mind that this action will cause a downtime in the Appcircle dashboard.
:::
- Log in to Appcircle server with SSH or remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
:::info
The `spacetech` in the example codes below are example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
- Shutdown Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Find the `keycloak` key and append the `allowDisposableEmails` key into that section.
The **allowDisposableEmails** key can be `true` or `false`. `false` is the default value, so it disables users from registering with disposable or common emails.
If you want to enable disposable or common emails, change this value to `true`.
You can see a sample part of a configured `global.yaml` below.
```yaml
keycloak:
initialUsername: admin@spacetech.com
enabledRegistration: true
allowDisposableEmails: true
```
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
:::
Now, the users can register with disposable or common emails.
If you want to re-disable that behavior, as in the default configuration, you can change the **allowDisposableEmails** value to `false` by following the same steps above.
### Forgot Password
If this setting is `on`, your users can renew their passwords themselves. If you want your users' password management operations to be done via LDAP or other authentication methods, you should keep this setting `off`.
Click on the "Save" button to apply the settings.
:::info
If this setting is `off`, the "Forgot Password?" button will not appear on the Appcircle login page.
:::
### Edit Username
If this setting is set to `on`, then your users will be able to change their own email addresses.
:::tip
The login username for Appcircle is an email address.
:::
In order to prevent users from changing their email addresses by themselves, you should keep this setting `off`.
Click on the "Save" button to apply the settings.
---
## Network Access
# Overview
This page provides guidance on configuring and enabling external network access for a self-hosted Appcircle server and runner.
When deploying a self-hosted Appcircle server and runner, there are scenarios where the application needs to establish connections to external resources over the network. These connections are required to download operating system dependencies, pull Docker images from registries, or access external services such as mobile application build dependencies.
Enabling external network access is essential to ensuring the smooth operation and functionality of self-hosted applications. By establishing connections to external resources, self-hosted applications can access the necessary components, data, and services that are vital for their execution.
You can see different scenarios below according to how you want to install the Appcircle server and runner.
:::info
If you are hosting a yum or apt package repository locally on your network, you do not need to allow external domains for RHEL and Ubuntu repos.
:::
## Appcircle Server Install and Update
Below you can find the network access details required when installing or upgrading a self-hosted Appcircle server.
This section covers the external resource domains during the installation process of the Appcircle Server on the RHEL distribution using Podman.
##### `podman-compose` tool:
- You must download the podman-compose tool from python pip repositories.
```access_list
pypi.python.org/simple/podman-compose
pypi.org/simple/podman-compose/
pypi.python.org/simple/python-dotenv/
pypi.org/simple/python-dotenv/
pypi.python.org/pypi/pip/json
pypi.org/pypi/pip/json
files.pythonhosted.org/packages/
```
##### System tools:
- The Appcircle server requires some tools to be installed.
- These tools are `tar`, `curl`, `unzip`, `socat`, `netavark` and `Podman`.
- If you are hosting a `yum` repository locally on your network, you don't need these URLs.
```access_list
subscription.rhsm.redhat.com
cdn.redhat.com
```
This section covers the external resource domains during the installation process of the Appcircle Server on the RHEL distribution using Docker.
##### Offline docker install script and docker `rpm` files:
- If you want to install `Docker` on your RHEL from Appcircle resources, then the Appcircle server host needs to access these URLs.
```access_list
storage.googleapis.com/appcircle-dev-common/self-hosted
```
##### System tools:
- The Appcircle server requires some tools to be installed.
- These tools are `tar`, `curl` and `unzip`.
- If you are hosting a `yum` repository locally on your network, you don't need these URLs.
```access_list
subscription.rhsm.redhat.com
cdn.redhat.com
```
This section covers the external resource domains during the installation process of the Appcircle Server on the Ubuntu distribution using Docker.
##### `docker` installation:
- If you want to install `Docker` on your Ubuntu, then the Appcircle server host needs to access these URLs.
```access_list
download.docker.com
archive.ubuntu.com
```
##### System tools:
- The Appcircle server requires some tools to be installed.
- These tools are `tar`, `curl` and `unzip`.
- If you are hosting an `apt` repository locally on your network, you don't need these URLs.
```access_list
archive.ubuntu.com
```
##### If you are an enterprise-licensed or PoC customer, Appcircle server `zip` package:
- If you are an enterprise-licensed or PoC customer and want to install or update the Appcircle server, the Appcircle server host needs to access this URL to download the Appcircle server `zip` package.
- If you want to download the `zip` package and copy it manually (with `scp` or `ftp`), then the Appcircle server host doesn't need this access.
```access_list
cdn.appcircle.io
storage.googleapis.com/storage/v1/b/appcircle-self-hosted
www.googleapis.com/oauth2/v4/token
```
##### If you don't have a proxy registry like `Harbor` or `Nexus`, and want to use container images directly from Appcircle:
- If you have your own proxy registry and want to mirror the Appcircle container images, then your Appcircle server doesn't need to access the origin container image registry directly.
- If you don't have an image registry, the Appcircle server needs to access this URL.
```access_list
europe-west1-docker.pkg.dev/appcircle/docker-registry
```
##### If you want to install the Appcircle server using offline packages:
- If you want to install the Appcircle server without an internet connection, a `zip` package should be downloaded and transferred to the Appcircle server host.
- This `zip` package can be downloaded from another host and transferred to the actual Appcircle server. If you plan to do that, the Appcircle server doesn't need to access these URLs.
```access_list
storage.googleapis.com/appcircle-self-hosted
www.googleapis.com/oauth2/v4/token
```
## Appcircle Runner Install as Ready-to-Use MacOS Virtual Machine
This section covers the external resource domains during the installation process of the Appcircle runner using an Appcircle-provided [virtual machine](/self-hosted-appcircle/self-hosted-runner/installation#macos-vm).
- `homebrew` tool (required):
```access_list
raw.githubusercontent.com
github.com
api.github.com
api.apple-cloudkit.com
formulae.brew.sh
swcdn.apple.com
xp.apple.com
pancake.apple.com
gdmf.apple.com
swdist.apple.com
swscan.apple.com
ocsp2.apple.com
```
:::info
Homebrew installs the latest version of Xcode Command Line Tools as a dependency. `*.apple.com` domains are used for that purpose.
:::
- `tart` tool (required):
_Tart is a registered trademark of Cirrus Labs, Inc._
```access_list
github.com
api.github.com
objects.githubusercontent.com
api.apple-cloudkit.com
google-analytics.com
europe-west1-1.gcp.cloud2.influxdata.com
```
:::info
Homebrew gathers anonymous analytics using InfluxDB. The below domains are related to Homebrew analytics when installing a package via the `brew` command.
- google-analytics.com
- europe-west1-1.gcp.cloud2.influxdata.com
If you don't want to enable these URLs or you aren’t comfortable with this, you can opt out of Homebrew analytics by following the instructions [here](https://docs.brew.sh/Analytics#opting-out).
:::
- macOS VM image and the runner starter script (required):
```access_list
storage.googleapis.com/appcircle-dev-common/self-hosted
```
- macOS VM install script (_required if you prefer automatic installation_):
```access_list
cdn.appcircle.io
storage.googleapis.com/storage/v1/b/appcircle-dev-common
```
## Appcircle Server Runtime
### Store APIs
Although Appcircle runners are responsible for the submission of the apps to the mobile application stores, the server also has some features that need access to the application store APIs, like runners.
For example, verify uploaded API keys, get devices from the App Store, get certificates or provisioning profiles, verify the uploaded certificates, etc.
So, you should enable the below API access on the server for each store you want to publish your apps.
#### Google Play Store
- `oauth2.googleapis.com`
- `androidpublisher.googleapis.com`
#### Huawei AppGallery
- `connect-api.cloud.huawei.com`
#### App Store
- `api.appstoreconnect.apple.com`
:::info
If you are using an Enterprise API Key as detailed in the [App Store Connect API Key](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key) documentation, ensure that network access is also permitted to the following address:
- `api.enterprise.developer.apple.com`
:::
## Appcircle Runner Runtime
This section addresses the utilization of external resources during the build, publish, and other processes on the Appcircle runner.
### Appcircle Server
Appcircle runners should access the self-hosted Appcircle server to get jobs and send artifacts.
:::caution
Be aware that the URLs below should be the URLs of the self-hosted Appcircle server in your organization.
Below are the sample URLs that show the required subdomains compatible with the sample configuration in the installation documents.
:::
- `api.appcircle.spacetech.com`
- `resource.appcircle.spacetech.com`
- `redis.appcircle.spacetech.com`
Appcircle runners connect to the self-hosted Appcircle server over the ports below:
If your self-hosted server is configured as HTTPS:
- `443`
If your self-hosted server is configured as HTTP:
- `80`
- `6379`
### Build
Appcircle’s workflow components are hosted on GitHub and they're `git` cloned while running the pipeline.
- `github.com/appcircleio/`
Some of the dependencies such as `CocoaPods` and `Fastlane` use Ruby Gems.
- `rubygems.org`
- `index.rubygems.org`
The Gradle wrapper needs access to the below URL to download Gradle.
- `services.gradle.org`
Android Build Tools need access to the following URLs to download new build tools and NDKs:
- `dl-ssl.google.com/android/repository`
- `dl.google.com/android/repository`
All the maven repositories inside `build.gradle` must be added to the allow-list.
For example;
- `maven.google.com`
- `repo.maven.apache.org/maven`2`
If you’re using CocoaPods and if your `Podfile` is using another spec repository, they also must be allowed.
- `cdn.cocoapods.org`
- `github.com/CocoaPods/Specs`
### Testing Distribution
#### Firebase:
- `firebaseappdistribution.googleapis.com`
### Publish
**Disclaimer:** The URLs provided below were last verified on 3 June 2025, and are subject to change by the respective services. Please consult official documentation of the stores for the most up-to-date information.
#### Google Play Store
- `www.googleapis.com`
- `androidpublisher.googleapis.com`
#### Huawei AppGallery
- `connect-api.cloud.huawei.com`
- `nsp-appgallery-agcfs-dre.obs.eu-de.otc.t-systems.com` (dynamic)
:::caution
The second domain starting with `nsp-appgallery-`, may vary depending on your region. It is dynamically returned by the AppGallery Connect API.
To determine the exact URL used in your case, monitor your network traffic during the publishing process.
:::
#### App Store
- `contentdelivery.itunes.apple.com`
- `api.appstoreconnect.apple.com`
- `appstoreconnect.apple.com`
:::info
If you are using an Enterprise API Key as detailed in the [App Store Connect API Key](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key) documentation, ensure that network access is also permitted to the following address:
- `api.enterprise.developer.apple.com`
:::
:::caution
The Apple App Store connects to several endpoints during upload. It is important to allow access to all of them.
Those endpoints are documented at [here](https://help.apple.com/itc/transporteruserguide/en.lproj/static.html). The endpoints may change in the future.
:::
| **Server** | **TCP Port** |
| --------------------------------------- | ------------ |
| contentdelivery.itunes.apple.com | 443 |
| idmsa.apple.com | 443 |
| northamerica-1.object-storage.apple.com | 443 |
| store-037.blobstore.apple.com | 443 |
| store-036.blobstore.apple.com | 443 |
| store-035.blobstore.apple.com | 443 |
| store-033.blobstore.apple.com | 443 |
| store-032.blobstore.apple.com | 443 |
| store-030.blobstore.apple.com | 443 |
| store-028.blobstore.apple.com | 443 |
| store-026.blobstore.apple.com | 443 |
| store-025.blobstore.apple.com | 443 |
| store-004.blobstore.apple.com | 443 |
| transporter.amp.apple.com | 443 |
## Appcircle DMZ Server Install & Update
Below you can find the network access details required when installing or upgrading a self-hosted Appcircle DMZ server.
This section covers the external resource domains during the installation process of the Appcircle DMZ Server on the RHEL distribution using Podman.
##### `podman-compose` tool:
- You must download the podman-compose tool from python pip repositories.
```access_list
pypi.python.org/simple/podman-compose
pypi.org/simple/podman-compose/
pypi.python.org/simple/python-dotenv/
pypi.org/simple/python-dotenv/
pypi.python.org/pypi/pip/json
pypi.org/pypi/pip/json
files.pythonhosted.org/packages/
```
##### System tools:
- The Appcircle DMZ server requires some tools to be installed.
- These tools are `tar`, `curl`, `unzip`, `socat`, `netavark` and `Podman`.
- If you are hosting a `yum` repository locally on your network, you don't need these URLs.
```access_list
subscription.rhsm.redhat.com
cdn.redhat.com
```
This section covers the external resource domains during the installation process of the Appcircle DMZ Server on the RHEL distribution using Docker.
##### System tools:
- The Appcircle DMZ server requires some tools to be installed.
- These tools are `tar`, `curl` and `unzip`.
- If you are hosting a `yum` repository locally on your network, you don't need these URLs.
```access_list
subscription.rhsm.redhat.com
cdn.redhat.com
```
This section covers the external resource domains during the installation process of the Appcircle DMZ Server on the Ubuntu distribution using Docker.
##### `docker` installation:
- If you want to install `Docker` on your Ubuntu, then the Appcircle server host needs to access these URLs.
```access_list
download.docker.com
archive.ubuntu.com
```
##### System tools:
- The Appcircle DMZ server requires some tools to be installed.
- These tools are `tar`, `curl` and `unzip`.
- If you are hosting an `apt` repository locally on your network, you don't need these URLs.
```access_list
archive.ubuntu.com
```
### Appcircle Server
Appcircle DMZ server should access the self-hosted Appcircle server to get required information for Enterprise App Store and Testing Distribution services.
:::caution
Be aware that the URLs below should be the URLs of the self-hosted Appcircle server in your organization.
Below are the sample URLs that show the required subdomains compatible with the sample configuration in the installation documents.
:::
- `api.appcircle.spacetech.com`
- `auth.appcircle.spacetech.com`
- `monitor.appcircle.spacetech.com`
Appcircle DMZ server connect to the self-hosted Appcircle server over the ports below:
If your self-hosted Appcircle server is configured as HTTPS:
- `443`
If your self-hosted Appcircle server is configured as HTTP:
- `80`
---
## Proxy Configuration
In this document, we will explore the configuration of a proxy server to enable internet connectivity from your Appcircle containers for accessing external resources.
We will cover Docker and Podman, providing step-by-step instructions to set up and utilize the proxy server effectively.
Using proxies on Appcircle containers ensures smooth connectivity to external resources.
:::info
We're assuming that previously you reviewed or followed [install self-hosted appcircle](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in docs and applied example scenario.
Following steps are using example project as project naming, which was told there.
:::
## 1. Stop Appcircle Server
At first, you must shut down your server and configure it when it is stopped for the overall stability of the host machine.
- Go to the `appcircle-server` folder.
```bash
cd appcircle-server
```
- Stop the server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
## 2. Configure Proxy for the Server
For a typical proxy configuration, you need to know the arguments for these parameters:
- Username if the proxy has authentication. For example, `user`
- Password if the proxy has authentication. For example, `password`
- Hostname or IP of the proxy server. For example, `proxy.spacetech.com`
- Port of the proxy server. For example, `8080`
:::info
If your proxy server has no authentication, you should ignore the `user` and `password` values in the below sample codes and configurations.
:::
:::info
You can also use the IP of the proxy server if it does not have a dedicated domain name.
:::
Next, you should enable proxy settings on the host server.
To do that you can follow the steps below:
- For non-shell processes, edit the `/etc/environment`.
```bash
sudo vi /etc/environment
```
- Add the content below to the `/etc/environment` file.
```env
HTTP_PROXY=http://user:password@proxy.spacetech.com:8080/
HTTPS_PROXY=http://user:password@proxy.spacetech.com:8080/
NO_PROXY=localhost,127.0.0.1
http_proxy=http://user:password@proxy.spacetech.com:8080/
https_proxy=http://user:password@proxy.spacetech.com:8080/
no_proxy=localhost,127.0.0.1
```
:::tip
### `no_proxy` Configuration
`no_proxy` and `NO_PROXY` should be used for your corporate intranet services that should be kept away from the proxy.
You can add all the required domains or IPs separated by a comma. Below are some example cases that are common for a typical enterprise installation.
- Git provider (GitLab, Bitbucket, etc.) For example, `gitlab.spacetech.com`
- Proxy Repository (Nexus, Harbor, etc.) For example, `registry.spacetech.com`
:::
- For shell processes, edit the `/etc/profile.d/proxy.sh`.
```bash
sudo vi /etc/profile.d/proxy.sh
```
- Add the content below to the `/etc/profile.d/proxy.sh` file.
```env
export HTTP_PROXY=http://user:password@proxy.spacetech.com:8080/
export HTTPS_PROXY=http://user:password@proxy.spacetech.com:8080/
export NO_PROXY=localhost,127.0.0.1
export http_proxy=http://user:password@proxy.spacetech.com:8080/
export https_proxy=http://user:password@proxy.spacetech.com:8080/
export no_proxy=localhost,127.0.0.1
```
:::caution
For system integrity, the proxy settings in here should be the same as the above settings in `/etc/environment`.
Also see the `no_proxy` tip explained [there](#no_proxy-configuration).
:::
- Close the terminal and open a new session.
:::caution
To make the changes take effect, please open a brand new terminal session.
Otherwise, you won't succeed in the following steps.
:::
:::info
Don't forget to change `user`, `password`, proxy `host`, proxy `port`, and `no_proxy` settings for your needs while copying from above.
:::
:::tip
If your proxy server has its own self-signed certificate, you should add it to the Appcircle server configuration file (`global.yaml`) in order to make it trusted for the Appcircle services.
Since the proxy usage is also considered to be an external service, you should follow the **[external services](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration#external-services)** document for the relevant settings.
Keep in mind that, after you configure the Appcircle server, you should apply the configuration changes using the following steps.
- Go to the `appcircle-server` folder.
```bash
cd appcircle-server
```
- Apply up-to-date server configuration.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
:::
### Edit `no_proxy` for Internal Container Network
In order not to break the connection of the containers with each other, we must add the service names to the `no_proxy` and `NO_PROXY` environment variables.
You can follow the steps below to edit these variables correctly.
- Go to the `appcircle-server` folder.
```bash
cd appcircle-server
```
Inside the `helper-tools` directory, there is a bash script file called `no-proxy.sh`.
:::caution
The `no-proxy.sh` helper tool exists in self-hosted server versions `3.7.1` or later.
If you have an older version installed, please [upgrade](/self-hosted-appcircle/install-server/linux-package/update) your self-hosted server to a newer version. If upgrading is not possible, you should contact us for support.
:::
- Execute the script with sudo privileges and give your project as argument.
```bash
sudo ./helper-tools/no-proxy.sh ${YOUR_PROJECT}
```
For example if your project name is "spacetech", you should run the command like below.
```bash
sudo ./helper-tools/no-proxy.sh spacetech
```
:::caution
You must run the script from the parent directory of the `no-proxy.sh` script.
Be aware that if you run the script like `./no-proxy spacetech`, it will fail.
:::
- Restart your terminal session.
:::caution
Don't forget to start a new terminal session after you run command above for the changes to take effect.
:::
## 3. Enable Settings on the Container Engine
After you enable proxy settings on the host server, you must also edit the Docker's configuration file to notify the container runtime engine that there are proxy settings to use.
You can follow the steps below to enable proxy settings on the Docker:
- Print the value of the `no_proxy` variable to the terminal and copy it.
```bash
echo $no_proxy
```
- Edit the Docker configuration file. It creates if it does not exist.
```bash
vi ~/.docker/config.json
```
- Add the proxy settings to the configuration file like below. Paste the copied `no_proxy` variable to the `noProxy` section on the configuration file.
```json
{
"proxies": {
"default": {
"httpProxy": "http://user:password@proxy.spacetech.com:8080",
"httpsProxy": "http://user:password@proxy.spacetech.com:8080",
"noProxy": "localhost,127.0.0.1"
}
}
}
```
:::caution
The Docker file `config.json` might exist on the system. If that's the case, then you should **only add the `proxies` section** of the JSON above to the configuration file.
:::
:::caution
For system integrity, the proxy settings in here should be the same as the above settings in `/etc/environment`.
Also see the `no_proxy` tip explained [there](#no_proxy-configuration).
:::
The configuration becomes active after saving the file, you don’t need to restart Docker. However, the configuration only applies to new containers, and doesn’t affect existing containers.
So, if you stop the server as the first step in this document, then you can go on with the next step. If not, it's time to [stopping the server](#1-stop-appcircle-server) before going on.
If you followed until here, you don't need to take extra actions for the Podman container engine.
## 4. Start Appcircle Server
After configuring the proxy settings on the host, you can start your Appcircle server.
- Go to the `appcircle-server` folder.
```bash
cd appcircle-server
```
- Start the server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
Your containers will be able to connect to external resources through the proxy now.
## Maintenance of `no_proxy` Variables
The Appcircle server is getting updates regularly, and there might be a new container service in the `compose.yaml` file.
To maintain the stability of the system, you should go back to the [Edit `no_proxy` for Internal Container Network](#edit-no_proxy-for-internal-container-network) step and re-apply the operations done there on every upgrade.
---
## SSL Configuration
# Overview
Although auto-generated `global.yaml` template has "HTTPS enabled" by default, in our sample scenario and configuration it was "HTTPS disabled" to keep it simple to understand. Refer [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) for sample configuration told at installation.
SSL configuration has some specific details for its own use cases and it should have a dedicated section.
So, in this section we will document all the details about configuring HTTPS with your own certificates for your own domain.
:::caution
Self-hosted Appcircle server does not support using a proxy, load balancer or some other external device to terminate SSL. You should do it inside Appcircle instance with configuration told in below sections.
:::
:::info
For now, self-hosted Appcircle server does not have Let’s Encrypt integration or an automated way of renewing certificates.
You should manage certificates from configuration file manually and renew them with same method when expired.
:::
:::info
If your cert format `PKCS#7` (known as p7b or p7c) , you can convert it to pem format with openssl.
See the example command below:
```bash
openssl pkcs7 -print_certs -in cert.p7b -out cert.pem
```
:::
:::info
If your cert format is `PFX` (known as p12), you can convert it to pem format with openssl.
See the example commands below:
- Extract the cert from archive.
```bash
openssl pkcs12 -in cert.p12 -clcerts -nokeys -out cert.pem
```
- Extract the key without password.
```bash
openssl pkcs12 -in cert.p12 -nocerts -nodes -out key.pem
```
- Extract the key with password.
```bash
openssl pkcs12 -in cert.p12 -nocerts -out key.pem
```
:::
:::info
When configuring Appcircle with HTTPS, you have the option to use self-signed or untrusted root certificates. However, if you choose to do so, it is essential to add the certificate or the root CA certificate to the trusted certificates. Failure to do this may result in connection errors. For detailed instructions about adding trusted CA certificates, refer to the [External Services](#external-services) section.
:::
## Configure HTTPS
First of all, you need to set `external.scheme` as `https` at `global.yaml` to enable HTTPS for all [subdomains](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings).
```yaml
external:
scheme: https
```
:::caution
`global.yaml` configuration file is located under **project** folder.
- `projects/${YOUR_PROJECT}`
You can see an example project configuration from [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure).
:::
:::caution
Changing `external.scheme` from `http` to `https` or from `https` to `http` after using Appcircle server some time, requires configuration reset which results with data cleanup.
So, we suggest you to be sure with your configuration before using it in production environment.
Refer to [reset configuration](/self-hosted-appcircle/install-server/linux-package/installation/docker#reset-configuration) section for more details.
:::
Set your private key and public certificate to `nginx` environment variables in `global.yaml` as below.
```yaml
nginx:
sslCertificate: |
-----BEGIN CERTIFICATE-----
MIIFLTCCBBWgAwIBAgISBB5v1NxtkwmxzOryHdHkWuwoMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
sslCertificateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDWkSbzuxqDY9hb
giZbOvH6ZEWJNgk5x+jsocsH+f2nsi6IsmnZqm5z068IxV4o7u2NtPQ1Yl4v4F7y
...
J8lYxh0PCOmuCZ02FAvoi0r8
-----END PRIVATE KEY-----
```
- `sslCertificate` is the public certificate. (content of `.crt` file)
- `sslCertificateKey` is the private key. (content of `.key` file)
:::caution
You must use the full certificate chain, in the correct order, to prevent SSL errors when clients connect. For example, you may get an _"unable to verify the first certificate"_ error on a missing case.
Order should be like this: first the server certificate, then all intermediate certificates, and finally the root CA.
:::
:::info
If you want to hide these secrets from human-readable `global.yaml`, you can use base64 encoded `user-secret` file for the same environment variables.
Refer to [installation](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) docs for details of `user-secret` usage.
:::
:::caution
For now, self-hosted Appcircle does not support usage of password protected private keys.
:::
### Sample Configuration
:::info
We're assuming that previously you reviewed or followed [install self-hosted appcircle](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in docs and applied example scenario.
Following steps are using example project as project naming, which was told there.
Current working directory is assumed `appcircle-server` for following steps. See [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download) for installation details.
:::
Let's assume we have `_wildcard.appcircle.spacetech.com.key` as private key file for our sample domain.
```bash
$ cat _wildcard.appcircle.spacetech.com.key
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDWkSbzuxqDY9hb
giZbOvH6ZEWJNgk5x+jsocsH+f2nsi6IsmnZqm5z068IxV4o7u2NtPQ1Yl4v4F7y
...
J8lYxh0PCOmuCZ02FAvoi0r8
-----END PRIVATE KEY-----
```
And we have `_wildcard.appcircle.spacetech.com.crt` as public certificate file for our sample domain. It's a full chain certificate file which has server certificate, all intermediate certificates, and finally the root CA.
```bash
$ cat _wildcard.appcircle.spacetech.com.crt
-----BEGIN CERTIFICATE-----
MIIFLTCCBBWgAwIBAgISBB5v1NxtkwmxzOryHdHkWuwoMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
hXg7TJ+Y8MmrBmw4il+i4GfwZN4h7TMuRm17w9+EfVgw
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
```
HTTPS related settings in `global.yaml` file should be like this.
```yaml
---
environment: Production
enableErrorHandling: "true"
external:
scheme: https
mainDomain: ".appcircle.spacetech.com"
...
...
nginx:
sslCertificate: |
-----BEGIN CERTIFICATE-----
MIIFLTCCBBWgAwIBAgISBB5v1NxtkwmxzOryHdHkWuwoMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
hXg7TJ+Y8MmrBmw4il+i4GfwZN4h7TMuRm17w9+EfVgw
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
sslCertificateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDWkSbzuxqDY9hb
giZbOvH6ZEWJNgk5x+jsocsH+f2nsi6IsmnZqm5z068IxV4o7u2NtPQ1Yl4v4F7y
...
J8lYxh0PCOmuCZ02FAvoi0r8
-----END PRIVATE KEY-----
```
After running server, open your browser and go to `https://my.appcircle.spacetech.com`.
You should see "Connection Secure" icon in browser's address bar which shows successful HTTPS connection.
:::info
#### Redirect HTTP requests to HTTPS
By default, when you enable HTTPS for `external.scheme`, NGINX listens for unencrypted HTTP traffic on port 80 but redirects them as HTTPS with 301 response code automatically.
You don't need to do any manual configuration to redirect HTTP requests to HTTPS.
:::
:::tip
In order to keep your configuration simple, we're suggesting to use wildcard certificate for `external.mainDomain`.
For our sample scenario, we used certificate signed for `*.appcircle.spacetech.com` domain.
Wildcard certificate created for main domain will cover all subdomains listed in [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings).
Although you can create and use dedicated certificates for all subdomains, in our opinion it won't be useful. It will be harder to configure and maintain lots of certificates.
:::
## Configure TLS Versions
The Appcircle server by default accepts connections over `TLSv1` and above. You can choose which TLS versions to support based on your security requirements. To restrict the TLS versions used by the Appcircle server, you can set the `.nginx.sslProtocols` variable in the `global.yaml` of the project.
:::info
When configuring TLS versions for your Appcircle server, keep in mind that this setting applies to all services, including the Dashboard, Testing Distribution, Enterprise App Store, Authentication, and others, including the [Appcircle DMZ Server](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz) if you are using Appcircle in DMZ mode.
:::
:::info
Configurable TLS version support requires Appcircle server `3.23.0` or later.
:::
To make Appcircle server to work with `TLSv1.2` and above:
- Login to the Appcircle server with SSH.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add or update the `nginx.sslProtocols` parameter as below.
:::info
Please keep in mind that the `nginx` key might already exist in your `global.yaml` file. In that case, just add the `sslProtocols` key. If `nginx` does not exist you can add it to the `global.yaml` file of your project.
:::
:::caution
#### TLSv1.2 is Required for MacOS Runners 🚫
It is important to note, however, that if macOS runners are included in a self-hosted runner pool, `TLSv1.2` support should remain enabled. Currently, .NET on macOS does not support the latest TLS protocol versions, and disabling `TLSv1.2` will disrupt communication with macOS-based runners.
:::
```yaml
nginx:
sslProtocols: TLSv1.2 TLSv1.3
```
## Enterprise App Store
`global.yaml` configuration has its own dedicated section for Enterprise App Store domain settings. Below we will explain some use cases for Enterprise App Store, when you enable HTTPS.
:::info
After installation, you can view domain settings from "Enterprise App Store > Settings > Store Domain" page in web UI. But you can not change settings from there.
If you want to change domain settings, you should take the same steps told below and make changes from `global.yaml`.
:::
### Default Domain
You can use Enterprise App Store with its default domain without any custom domain configuration.
`global.yaml` section should be like this for default domain.
```yaml
storeWeb:
external:
subdomain: store
customDomain:
enabled: false
```
When you use wildcard certificate for main domain, you don't need to create an extra certificate for enterprise app store domain.
Although your wildcard certificate does not include "Store Prefix", on self-hosted Appcircle server installations "Store Prefix" is not used actively since there is only one organization.
Prefixed web requests will always be redirected to default store subdomain. And store subdomain is covered by your wildcard certificate.
- `${PREFIX}.store` :arrow_right: `store`
For our sample scenario, an example redirection will be like this,
- `5bgnsirt10fj.store.appcircle.spacetech.com` :arrow_right: `store.appcircle.spacetech.com`
For this reason, you can only use `store.appcircle.spacetech.com` for all your needs.
### Custom Domain
It's possible to use a custom domain for the Enterprise App Store. In this case we need to make extra configuration for our custom domain.
Most likely, our custom domain won't be covered by main domain certificate. So we may need to create new public certificate and private key pair for the custom domain.
Even if the main domain certificate covers the custom domain, you still need to explicitly configure the store’s custom domain certificate under `storeWeb.customDomain`. Because, when the store custom domain is enabled, the HTTPS certificate defined in the `storeWeb.customDomain` section is used for the Enterprise App Store instead of the certificate defined in `nginx.sslCertificate`.
Custom domain settings are available for both HTTP and HTTPS configurations.
Let's assume we want to use `apps.spacetech.com` as custom domain for our sample scenario.
#### HTTPS Configuration
Custom domain HTTPS settings are similar to the main domain conceptually. After enabling HTTPS for the main domain, it won't be hard to enable HTTPS for the Enterprise App Store custom domain.
Configure the `storeWeb` section in your `global.yaml` as follows:
```yaml
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: apps.spacetech.com
port: 443
enabledTls: true
publicKey: |
-----BEGIN CERTIFICATE-----
MIIFOjCCBCKgAwIBAgISBAqWQRxIkc0kW2OZsPY2qH4dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
fLDoKQyylhH5aZgQvRWmvGjAvMCaU4me6rfq7ExudsrImuHZuxv0+mL1OvHsJA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
privateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL0BJ4P5hBrjIf
uDOL6OsB3AvdwTIwCTfpaJOSRi1ZXbxVGXv2f429gqQ4WADxRnLIsmcZtbAyrubO
...
LUBOU4QRP9V6qpS0TrLmIoM=
-----END PRIVATE KEY-----
```
:::caution
The `storeWeb.customDomain.port` must be `443` if the `enabledTls` option is set to `true`.
:::
```yaml
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: apps.spacetech.com
port: 8443
enabledTls: true
publicKey: |
-----BEGIN CERTIFICATE-----
MIIFOjCCBCKgAwIBAgISBAqWQRxIkc0kW2OZsPY2qH4dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
fLDoKQyylhH5aZgQvRWmvGjAvMCaU4me6rfq7ExudsrImuHZuxv0+mL1OvHsJA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
privateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL0BJ4P5hBrjIf
uDOL6OsB3AvdwTIwCTfpaJOSRi1ZXbxVGXv2f429gqQ4WADxRnLIsmcZtbAyrubO
...
LUBOU4QRP9V6qpS0TrLmIoM=
-----END PRIVATE KEY-----
```
:::caution
The `storeWeb.customDomain.port` must be `8443` if the `enabledTls` option is set to `true`.
Since we forward the `TCP/443` to the `TCP/8443` port with [Socat](/self-hosted-appcircle/install-server/linux-package/installation/podman#overcoming-privileged-port-limitations) on the host, you will connect to the Enterprise App Store with the `TCP/443` port.
:::
- `publicKey` is the public certificate. (content of `.crt` file)
- `privateKey` is the private key. (content of `.key` file)
You should use the full certificate chain for `publicKey` similar to main domain `sslCertificate`, to prevent SSL errors when clients connect.
:::caution
For now, self-hosted Appcircle does not support usage of password protected private keys for Enterprise App Store custom domains.
:::
#### HTTP Configuration
If you want to use HTTP for your Enterprise App Store custom domain, you can configure it by setting `enabledTls` to `false` and using the appropriate HTTP port.
Configure the `storeWeb` section in your `global.yaml` as follows:
```yaml
storeWeb:
customDomain:
enabled: true
domain: apps.spacetech.com
port: 80
enabledTls: false
# No publicKey or privateKey
```
:::caution
The `storeWeb.customDomain.port` must be `80` when using HTTP with Docker.
:::
```yaml
storeWeb:
customDomain:
enabled: true
domain: apps.spacetech.com
port: 8080
enabledTls: false
# No publicKey or privateKey
```
:::caution
The `storeWeb.customDomain.port` must be `8080` when using HTTP with Podman.
Since we forward the `TCP/80` to the `TCP/8080` port with [Socat](/self-hosted-appcircle/install-server/linux-package/installation/podman#overcoming-privileged-port-limitations) on the host, you will connect to the Enterprise App Store with the `TCP/80` port.
:::
:::info
When `enabledTls` is set to `false`, no certificate configuration is needed or used. Connections will be unencrypted and HTTP only.
:::
## Testing Distribution
`global.yaml` configuration has its own dedicated section for [Testing Distribution](/testing-distribution) domain settings. Below, we will explain some use cases for Testing Distribution, when you enable HTTPS.
### Default Domain
By default, Testing Distribution has a **[dist](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings)** subdomain under the main domain on self-hosted Appcircle servers.
For example, if your `external.mainDomain` in the `global.yaml` file is `.appcircle.spacetech.com`, then the default Testing Distribution domain name should be `dist.appcircle.spacetech.com`.
If you have configured the Appcircle server as HTTPS using the `external.scheme` as explained [here](#configure-https), the certificate of the Appcircle server also includes the default Testing Distribution subdomain, and it works with HTTPS.
### Custom Domain
It's possible to use a custom domain for the Testing Distribution. In this case, you need to make extra configurations for our custom domain.
:::caution
Please be aware that, after you change the Testing Distribution domain or the SSL settings, the links in the **emails that were sent to the testers with the previous domain and previous SSL settings will be invalid.**
:::
Most likely, our custom domain won't be covered by the main domain certificate. In this case, we need to create a new public certificate and private key pair for the custom domain.
Custom domain HTTPS settings are similar to the main domain configuration conceptually. After enabling HTTPS for the main domain, it won't be hard to enable HTTPS for the Testing Distribution custom domain.
Let's assume we want to use `dist.spacetech.com` as a custom domain for our sample scenario. Then the `global.yaml` section should be like below for this case.
:::note
If you don't have the `testerWeb` section defined in the `global.yaml` file, you should add it as below.
If you have a `testerWeb` section previously defined in the `global.yaml` file for some reason, you should update that section with the `customDomain` settings below instead of adding a new one.
:::
```yaml
testerWeb:
customDomain:
enabled: true
domain: dist.spacetech.com
port: 443
enabledTls: true
publicKey: |
-----BEGIN CERTIFICATE-----
MIIFOjCCBCKgAwIBAgISBAqWQRxIkc0kW2OZsPY2qH4dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
fLDoKQyylhH5aZgQvRWmvGjAvMCaU4me6rfq7ExudsrImuHZuxv0+mL1OvHsJA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
privateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL0BJ4P5hBrjIf
uDOL6OsB3AvdwTIwCTfpaJOSRi1ZXbxVGXv2f429gqQ4WADxRnLIsmcZtbAyrubO
...
LUBOU4QRP9V6qpS0TrLmIoM=
-----END PRIVATE KEY-----
```
:::caution
The `testerWeb.customDomain.port` must be `443` if the `enabledTls` option is set to `true`.
:::
```yaml
testerWeb:
customDomain:
enabled: true
domain: dist.spacetech.com
port: 8443
enabledTls: true
publicKey: |
-----BEGIN CERTIFICATE-----
MIIFOjCCBCKgAwIBAgISBAqWQRxIkc0kW2OZsPY2qH4dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
...
fLDoKQyylhH5aZgQvRWmvGjAvMCaU4me6rfq7ExudsrImuHZuxv0+mL1OvHsJA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
privateKey: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDL0BJ4P5hBrjIf
uDOL6OsB3AvdwTIwCTfpaJOSRi1ZXbxVGXv2f429gqQ4WADxRnLIsmcZtbAyrubO
...
LUBOU4QRP9V6qpS0TrLmIoM=
-----END PRIVATE KEY-----
```
:::caution
The `testerWeb.customDomain.port` must be `8443` if the `enabledTls` option is set to `true`.
Since we forward the `TCP/443` to the `TCP/8443` port with [Socat](/self-hosted-appcircle/install-server/linux-package/installation/podman#overcoming-privileged-port-limitations) on the host, you will connect to the Testing Distribution with the `TCP/443` port.
:::
- `publicKey` is the public certificate. (content of `.crt` file)
- `privateKey` is the private key. (content of `.key` file)
You should use the full certificate chain for `publicKey`, similar to the main domain `sslCertificate`, to prevent SSL errors when clients connect.
:::caution
For now, self-hosted Appcircle does not support the usage of password-protected private keys for the Testing Distribution custom domains.
:::
## External Services
If you are using external services that have self-signed SSL certificates, you will need to add their public certificate to the `global.yaml` file. These external services can be self-hosted git providers like GitLab, Azure Devops Server, Bitbucket, or LDAP servers used for authentication.
You can add **multiple** certificates to the `external.ca` section. If you are using multiple services, you will need to add each certificate to this section.
:::info
A certificate included in `external.ca` must be in PEM form.
A PEM-formatted certificate is human-readable in base64 format, and starts with the lines ----BEGIN CERTIFICATE----.
:::
:::caution
If your external service has **Subordinate CA** (sub CA) in certificate chain, it should also be included in `external.ca` along with **Root CA**.
:::
```yaml
external:
scheme: https
mainDomain: ".appcircle.spacetech.com"
ca: |
-----BEGIN CERTIFICATE-----
MIIEvTCCAyWgAwIBAgIQNVqUQw+7fmeXJBAtns5HyjANBgkqhkiG9w0BAQsFADB3
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExJjAkBgNVBAsMHW9zYm94
...
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
```
:::caution
When editing the yaml file, pay close attention to the indentation level to ensure the file is properly formatted. Wrong indentation will cause runtime issues.
:::
---
## MinIO Migration
## Overview
Older versions of the Appcircle server utilized MinIO in a multi-node single drive (**`mnsd`**) setup, which resulted in increased disk usage. By default, the Appcircle server utilizes MinIO in a single-node single drive (**`snsd`**) configuration with the Appcircle server version `3.14.0` or later.
With the transition to Appcircle server `3.14.0` and the adoption of single-node single drive (**`snsd`**) MinIO, disk consumption is anticipated to decrease by approximately 20%.
This documentation provides comprehensive instructions on migrating from a multi-node single drive MinIO configuration to a single-node single drive MinIO configuration that can be applied to recent versions of the Appcircle server.
:::caution
Please note that this process will cause downtime since it requires a restart of the Appcircle server.
:::
:::tip
Fresh self-hosted server installations do not require any manual intervention for the MinIO configuration.
The single-node single drive MinIO configuration is applied by default on fresh installations.
:::
## Prerequisites
For a successful migration from multi-node single drive MinIO to single-node single drive MinIO, it's essential to ensure adequate free disk space on the Appcircle server.
To determine the required disk space, follow the steps below:
- Log in to Appcircle server with SSH or remote connection.
- Get information about the "Used" and "Available" disk spaces where your container engine data is stored.
```bash
df -h
```
Below is a sample output for the command above.
```bash
Filesystem Size Used Avail Use% Mounted on
devtmpfs 5.7G 0 5.7G 0% /dev
tmpfs 5.8G 0 5.8G 0% /dev/shm
tmpfs 5.8G 20M 5.8G 1% /run
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
/dev/vda3 80G 21G 60G 26% /
/dev/vda2 100M 5.8M 95M 6% /boot/efi
tmpfs 1.2G 0 1.2G 0% /run/user/1000
```
- Get information about the disk usage of the container engine.
```bash
docker system df
```
```bash
podman system df
```
Below is a sample output for the command above.
```bash
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 39 38 12.77GB 1.081GB (8%)
Containers 45 41 12.08MB 4.055kB (0%)
Local Volumes 576 29 7.431GB 4.649GB (62%)
Build Cache 38 0 831.5MB 831.5MB
```
- Make sure you have half of the "Local Volumes" size of "Available" (free) disk space.
- In our example above, we have 60 GB of "Available" (free) disk space, which should be sufficient for the migration since the "Local Volumes" have a size of 7.4 GB.
:::caution
If you don't have enough free disk space, the migration may fail, be interrupted, and stop.
Your data before the migration will be untouched and safe. So you can add some more free disk space and run the migration command again to migrate.
:::
## Migration
### Download Latest
Download the latest self-hosted Appcircle package.
To download the licensed Appcircle Server package for your organization, you must copy the `cred.json` file to the directory where you want to install the package.
:::info
Without the `cred.json` file, you will not be able to access the licensed Appcircle Server package.
If you have not yet obtained the `cred.json` file, please contact us for assistance.
:::
Download the latest self-hosted Appcircle package.
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-server.sh | bash
```
Extract self-hosted Appcircle package into folder.
```bash
unzip -o -u appcircle-server-linux-x64-${version}-${build}.zip -d appcircle-server
```
:::info
You should use the downloaded `zip` archive while extracting so that the actual `${version}` and `${build}` will come from there. You can find the relevant data in the previously executed download command output.
:::
Change directory into extracted `appcircle-server` folder for following steps.
```bash
cd appcircle-server
```
Shutdown the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
### Update Packages
Although it's rare, updates may have new packages or package updates. Those are the tools that the self-hosted Appcircle depends on. So they should be kept up-to-date, just like the Appcircle server.
:::caution
You need to have root access to your system for this step. Being able to run `sudo` is sufficient for the following step. (sudoer)
:::
In order to update packages, execute the script using the `-i` argument as shown below.
```bash
sudo ./ac-self-hosted.sh -i
```
### Update Configuration
Migrating to a single-node single drive MinIO does not necessitate any additional configuration adjustments in the `global.yaml` file of the project.
Execute the below command to apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
### Update Images
In order to get container image updates for Appcircle server services, you need to pull them from the remote artifact repository.
:::caution
If you are updating the Appcircle server with the [Offline Upgrade](/self-hosted-appcircle/install-server/linux-package/configure-server/offline-installation) method, you should `load` the new container images before the MinIO migration.
For more details, please head to the [Offline Upgrade](/self-hosted-appcircle/install-server/linux-package/configure-server/offline-installation#upgrade) documentation and follow the steps before the MinIO migration.
:::
- Upgrade the container images.
```bash
./ac-self-hosted.sh -n "spacetech" upgrade
```
### MinIO Migration
:::info
You must apply one of the options below while updating the self-hosted Appcircle server.
:::
Migration from multi-node single drive (**`mnsd`**) to single-node single drive (**`snsd`**) configuration can be accomplished seamlessly with a single command.
```bash
./ac-self-hosted.sh -n "spacetech" minio-migrate "mnsd" "snsd"
```
Upon successful completion of the migration process, you should see an output like in the example:
```text
...
Migration logs are being saved into the minio-migration-20240329082833.log file.
...
...
The migration command was completed successfully.
```
Detailed migration logs are being saved into a file named `minio-migration-${datetime}.log` where the `datetime` part is the current system date time in a format like `20240329082833`.
You can access and review the comprehensive migration logs from this file for further insights into the migration process.
:::caution
If you are using a proxy on the Appcircle server, then you should update the `no_proxy` variables.
Please follow the [No Proxy for Internal Container Network](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration#edit-no_proxy-for-internal-container-network) to update your proxy configuration for the new SNSD MinIO service.
:::
:::note
Although that's not recommended, you can prefer to stay with a multi-node single drive MinIO.
Keep in mind that this type of MinIO usage is **deprecated**, and later versions of the self-hosted Appcircle server might drop support for multi-node single drive MinIO.
:::
In order to stay with the multi-node single drive (**`mnsd`**) MinIO configuration and not proceed with migration, it's necessary to specify the MinIO type in the `global.yaml` file of the project.
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add the below section to `global.yaml` and specify the `mnsd` value as the `minio.type`.
```yaml
minio:
type: mnsd
```
- Then execute the below command to apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
### Start the Server
- Start the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
:::
## Troubleshooting & FAQ
### There is no space left on disk while migrating
If you can connect to the server via SSH, you can delete the **newly created** single-node single drive MinIO volume to free up disk space for stable system operations.
- List and filter the **`snsd`** volume from container volumes.
```bash
docker volume ls | grep -i "snsd"
```
```bash
podman volume ls | grep -i "snsd"
```
- Remove the your project's **`snsd`** volume. For example;
```bash
docker volume rm spacetech_minio_snsd_data
```
```bash
podman volume rm spacetech_minio_snsd_data
```
After that, you can cleanup the disk or add some more disk space for a successful migration.
Check the **[prerequisites](#prerequisites)** section for the required disk space.
If you want to go on without any migration and stay with an older configuration, you should follow the **[Staying with MNSD MinIO](#update-configuration)** section for configuration details.
### Possible checks that can be done after migration
In order to check if the migration is successful and the data is consistent, you can check some modules on the Appcircle dashboard.
Below is a short list of common modules that can be checked.
- [ ] Open a "Build Profile" and check the build logs.
- [ ] Open a "Publish Profile" and check the publish logs.
- [ ] Open a "Testing Distribution Profile" and check the app icons.
- [ ] Open "Enterprise App Store" module and check the app icons.
The migration command also prints output about the result of the migration operation on the command line.
### When you get an error while or after migrating
The migration operation does not delete the old MinIO volumes automatically. Your data before the migration is untouched and safe.
So if you face any error while migrating or after migrating to the SNSD MinIO, you can revert to the old MNSD MinIO configuration.
In this case follow the steps below to stay with MNSD MinIO configuration.
- Log in to Appcircle server with SSH or remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Stop the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add the below configuration section to `global.yaml`, or change the value as below if the `minio` section existed before.
```yaml
minio:
type: mnsd
```
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
### Deleting the unused MinIO volumes after migration
If there are no errors while migrating and you are satisfied with the results after migration, you can delete the obsolete MinIO volumes to save free disk space.
In order to delete the unused MinIO volumes that were left from MNSD MinIO configuration, run the command below.
```bash
docker volume rm \
spacetech_minio_data1 \
spacetech_minio_data2 \
spacetech_minio_data3 \
spacetech_minio_data4
```
```bash
podman volume rm \
spacetech_minio_data1 \
spacetech_minio_data2 \
spacetech_minio_data3 \
spacetech_minio_data4
```
Have questions? [Contact us here.](https://appcircle.io/support/)
---
## Monitoring
## Overview
This document provides instructions on how to access and use the monitoring system implemented for the self-hosted Appcircle server.
The monitoring system is designed to provide visibility into the application logs, enabling you to troubleshoot issues, monitor performance, and gain insights into the application's behavior.
The subsequent sections of this document will guide you through the process of accessing the Grafana web interface, navigating the log data.
:::info
To access and use the monitoring capabilities, you must be running Appcircle server version `3.15.0` or later.
:::
:::caution
The log monitoring system is for viewing the logs of the running Appcircle Server services. If you are having issues about starting the Appcircle Server services, you should use other CLI tools for troubleshooting and resolving the issues.
You may not access to the monitoring UI if services are not running healthy.
:::
## Accessing to Grafana Web UI
:::info
We will use `.appcircle.spacetech.com` example URLs below. You should change this domain with your own Appcircle domain.
:::
The Grafana monitoring UI is accessible by default through the `monitor` subdomain. In our example, the full domain URL is `monitor.appcircle.spacetech.com`.
:::caution
You can face SSL errors while connecting to the `monitor` URL like `ERR_CERT_COMMON_NAME_INVALID`. That error indicates the SSL certificate of the Appcircle server doesn't include the `monitor` subdomain.
The recommended solution is to update the SSL certificate of the Appcircle server.
:::
Upon navigating to the Grafana login page, you should authenticate using the initial username and password specified in the global.yaml file of your project. To verify these credentials, you can execute the following command on the Appcircle server:
Change directory to Appcircle server.
```bash
cd appcircle-server
```
- Update the environment variable `PATH` with the required dependencies.
```bash
export PATH=$PATH:$(pwd)/deps/bin
```
Print the Keycloak authentication credentials.
```bash
yq '.keycloak.initialUsername' ./projects/spacetech/export/.global.yaml && \
yq '.keycloak.initialPassword' ./projects/spacetech/export/.global.yaml
```
The example output below displays the `initialUsername` on the first line and `initialPassword` on the second line. These credentials serve as your login information for the Grafana monitoring interface.
```text
admin@spacetech.com
SuperSecretPassword
```
## Retention Period of Logs
Retention period refers to the duration for which log data is stored before being deleted or archived. It's used to manage storage space, optimize system performance, and ensure compliance with regulatory requirements.
### Retention Period on Loki
The Appcircle server logs will be stored in the Loki. So the queries and filters that you run from the Grafana UI will run on the Loki side.
The logs in the loki should be cleaned automatically. By default, the retention period for the Appcircle server logs on the Loki side are 720 hours (30 days).
If you want to change this, you can edit the `global.yaml` of your project.
```bash
vi ./projects/spacetech/global.yaml
```
Add or change the retention period variable.
```yaml
loki:
retentionPeriod: 168h # 7 days
```
### Retention on Systemd
The Appcircle server and other system services also transmit their logs to the Journald log driver. However, once Appcircle server logs are successfully forwarded to Loki, the local server logs become redundant and can be safely deleted.
If you wish to configure a maximum size limit for automatic log deletion on the Journald, you can modify the relevant configuration settings.
:::info
Modifying the Journald configuration requires elevated privileges with `sudo` permissions, as it involves altering system-level settings.
:::
Edit the Journald config file.
```bash
sudo vi /etc/systemd/journald.conf
```
Uncomment or add the `SystemMaxUse` variable in the configuration file and assign it the desired value, such as `200M` for a 200 megabyte limit.
```bash
SystemMaxUse=200M
```
Restart the Systemd journal service to apply the changes.
```bash
sudo systemctl restart systemd-journald
```
With this configuration change, the Journald log driver will now utilize a maximum of 200 megabytes of disk space for storing logs.
## Filtering Logs
After successfully authenticating with the Grafana user interface, you can commence filtering and exploring log data by navigating to the "Explore" menu.
To filter and view logs for a specific service, follow the steps outlined below. For instance, if you wish to examine the log entries pertaining to the `build` service:
1. Select `container` as label from `1`. box.
2. Select `spacetech-build-1` as value from `2`. box.
3. Select the date time you want to query from `3`. box.
4. After you set the query parameters, hit "Run query" button to see the logs.
5. Additionally, if you want to "follow" the logs in realtime, you can hit "Live" button.
Upon executing the query by clicking the "Run query" button, the log entries generated by the `spacetech-build-1` service will be displayed.
You can also filter words. For example you can filter any log line that contain "error" word.
1. Select the `container` and relevant container.
2. Change filter to `Line contains case insensitive` for a case insensitive search.
3. Write "error" to the input.
4. Select the date time and hit "Run query" button.
## Downloading and Sharing the Logs
If you want to download and share the logs after you [filter](#filtering-logs), you can the same UI.
1. Filter the logs according to your needs.
2. Hit the "Download" button from upper right corner of the logs.
3. Select `txt` as the format.
A file that contains the filtered logs will be downloaded to your local computer.
You can share that log file to troubleshoot the problems.
## Grafana User Management
It is important to note that the user accounts for the Appcircle Server and the Grafana monitoring interface are entirely separate and unrelated entities. There is no direct association or shared credentials between these two user management systems.
If you require additional users beyond the initial user account to have access to view log data, you can create new user accounts within the Grafana user management system.
To create a new user account, navigate to the "Administration" section of the Grafana interface, then access the "Users" menu. From there, click on the "New user" button to initiate the process of adding a new user.
Provide the necessary user information in the respective fields, and then click the "Create user" button to save and create the new user account.
To grant administrative privileges to the user, click the "Change" button and toggle the "Grafana Admin" switch to the "Yes" position. Click "Change" again to confirm and save the updated permissions.
For more detailed information, you can check the official [Grafana User Management](https://grafana.com/docs/grafana/latest/administration/user-management/) documentation.
## Disable the Monitoring Services
The monitoring services have been activated in the default configuration. However, you can disable them when you need to and then re-enable them again.
If you need to disable the monitoring services of the Appcircle server, edit the `global.yaml` file of your project and set the `monitoring.enabled` parameter to `false`.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
- Add or update the `monitoring.enabled` parameter as below.
```yaml
monitoring:
enabled: false
```
:::tip
If you can't find the `monitoring` parameter in the `global.yaml` file, you can add it manually at the end of the `global.yaml`.
:::
When you run the `check` command, you should see that the logging service is not running, as below:
```text
Appcircle logging service is not running.
All services are running successfully. Project name is spacetech
```
When you need to re-enable the monitoring services again, you can remove `monitoring` from `global.yaml` or set its value to `true`. After that, you should follow the Appcircle server restart steps above to apply the configuration changes.
:::info
Disabling the Appcircle monitoring services does not disable the Appcircle logging.
You can always access the container logs from container engine (`docker` or `podman`).
The container logs are also sent to the `systemd` journal. So the log entries can be retrieved using the `journalctl` command through the journal API. For more information, see the [`journald` logging driver](https://docs.docker.com/config/containers/logging/journald/) page.
:::
## FAQ
### Filtering "Error" Logs for All Containers
To query case-insensitive "error" logs for all containers using the Grafana Explore menu, follow these steps:
- **Select the `service_name` Label:** In the query builder, ensure the `service_name` label is selected to filter logs by service name.
- **Use the Matches Regex Operator (`=~`):** Instead of using the equals operator (`=`), choose the matches regex operator (`=~`). This allows for more flexible pattern matching.
- **Set the Target to `.+`:** In the regex field, enter `.+` to match any service name, effectively including all containers in the query.
- **Add a "Line Contains Case Insensitive" Filter:** Add a filter for log lines that contain the term "error" in a case-insensitive manner by entering `error` in the search field.
- **Enable the "Unique Labels" Toggle:** Enable the "Unique labels" toggle to display which service each log entry originates from, providing clearer insight into your log data.
If you face any error on the Appcircle, you can effectively search for logs containing the term "error" across all services by performing these steps.
### Missing Container Logs in Grafana UI
If container logs are not visible in the Grafana UI, this may be caused by either the Appcircle logging service not running or insufficient user permissions. Follow these steps to resolve the issue:
1. Log in to the Appcircle server with SSH.
2. Go to the Appcircle server directory.
```bash
cd appcircle-server
```
3. Start the Appcircle server.
```bash
./ac-self-hosted.sh -n spacetech up
```
4. Verify the Appcircle logging service status:
:::info
After you start the Appcircle server, `appcircle-logging` service will be running with the `active` status.
:::
```bash
systemctl --user status appcircle-logging
```
```bash
systemctl status appcircle-logging
```
5. If the logging service is running but container logs are still not visible in the Grafana UI, this may indicate insufficient permissions, especially for the non-root user. To resolve this:
1. Check the groups of the user who runs the Appcircle server.
```bash
groups $USER
```
2. Add the user to the necessary system groups if the user is not in the `adm` or `systemd-journal` groups.
:::info
The users who belong to these groups can access the journal logs or system logs without root privileges.
:::
```bash
sudo usermod -aG adm $USER
```
```bash
sudo usermod -aG systemd-journal $USER
```
3. Stop the Appcircle server:
```bash
./ac-self-hosted.sh -n spacetech down
```
4. Terminate the current user session:
```bash
loginctl terminate-user $USER
```
5. Start the Appcircle server:
```bash
./ac-self-hosted.sh -n spacetech up
```
---
## Offline Install/Upgrade
# Overview
Offline container images provide a solution for scenarios where an internet connection may not be readily available or reliable.
The primary purpose of providing offline container images is to enable seamless and efficient Appcircle server installations and updates in situations where connectivity to online container registries is limited or restricted.
Here you will find how to use the Appcircle server's offline container images.
## Requirements
### Software Requirements
To use the `download` or `load` commands, the self-hosted Appcircle server version must be `3.9.0` or later.
You need some tools for offline installation or upgrade. These are already installed if you followed one of the installation pages (Docker or Podman) and ran the command below.
```bash
sudo ./ac-self-hosted.sh -i
```
#### For Downloading From Another Machine
- curl
#### For Loading Images On Appcircle Server Machine
- curl
- unzip
- docker | podman
:::caution
You must follow one of the Appcircle server installation methods (Docker or Podman) and [configure](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) `global.yaml` as your project's needs until the [run server](/self-hosted-appcircle/install-server/linux-package/installation/docker#6-run-server) section.
Before running the server, you can install container images offline and then run the server.
:::
### Auth Requirement
During the installation of the self-hosted Appcircle server, it is essential to have the `cred.json` file provided to you upon purchasing the license. This `cred.json` file is necessary to access offline container images.
Without this file, you will not be able to access the offline container images required for the installation.
### Configuration Requirement
You must configure your project before using offline container images.
Please refer to [configuration section](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) from our installation pages.
After you have configured your project, you can refer to this page to run your server with offline container images.
## Installation
### Install on a Server With No Internet Access
If your Appcircle server does not have access to any container registry and does not have internet access, you can still install the Appcircle server.
In this scenario, you should download the Appcircle server container images to another Linux machine that should have active internet access and copy them to the Appcircle server with any desired method, like `ftp` or `scp`.
For downloading the Appcircle server offline container images, you should download the latest Appcircle server package.
:::caution
You should follow these steps on a Linux server that should have an active internet connection until you copy the `container-images` directory to the Appcircle server.
After copying the `container-images` directory to the actual Appcircle server, follow the remaining steps on the Appcircle server.
:::
- Go to the Appcircle server [installation](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download) page.
- Download the zip file and `unzip` it according to the [instructions](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download) there.
- Your organization should have a `cred.json` file. Copy that `cred.json` file inside the `appcircle-server` directory that you just unzipped.
- Run the `ac-self-hosted.sh` script with the `download` subcommand.
```bash
./ac-self-hosted.sh download
```
- A file download process should start.
- After the file download process has finished, you will see a directory named `container-images` in the `appcircle-server` directory.
- You should copy this directory to the actual Appcircle server with any method you want, like `ftp` or `scp`.
- After this step, you should login to the actual Appcircle server and go to the `appcircle-server` directory.
- Now you should see the `container-images` directory, which is copied from the other machine, in the `appcircle-server` directory on the Appcircle server.
- To import the container images into your project, run the `load` subcommand with the project argument.
:::caution
The `spacetech` value in the code below is an example project name.
Please check your project name by listing the `./projects` directory, and **don't forget** to replace the "spacetech" value with your project name.
:::
```bash
./ac-self-hosted.sh -n "spacetech" load
```
After the load process completes, you should see the imported container images with your container engine.
If you are using Docker as container engine;
```bash
docker image ls
```
If you are using Podman as container engine;
```bash
podman image ls
```
Now you are ready to `up` (start) the Appcircle server. You can refer back to the [Run Server](/self-hosted-appcircle/install-server/linux-package/installation/docker#6-run-server) section for details.
### Install on a Server With Internet Access
If the container registry that your organization has is not reliable or has connection issues, you can download and install offline container images directly with internet access.
For this scenario to work, you should have an internet access on the Appcircle server.
Run the below command to install all required container images to your container engine.
```bash
./ac-self-hosted.sh -n "spacetech" load
```
:::info
If you have configured a custom registry url in `global.yaml`, downloaded images will be re-tagged with your custom registry url.
So the offline installation step is compatible with your custom registries.
:::
:::info
This command will download container images and load them into the container engine that you use in your system. (Docker or Podman)
:::
Now you are ready to `up` (start) the Appcircle server. You can refer back to the [Run Server](/self-hosted-appcircle/install-server/linux-package/installation/docker#6-run-server) section for details.
## Upgrade
If you installed a self-hosted Appcircle server before and you want to upgrade your self-hosted Appcircle server but you can't somehow download container images, you can update your container images with this method too.
:::caution
If you are using the Appcircle DMZ structure and upgrading an Appcircle server, it is critical to also update the Appcircle DMZ server. If you don't, Enterprise App Store and Testing Distribution may not function as expected.
For more information about the DMZ structure, you can check the [Appcircle DMZ documentation](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz).
:::
:::info
You don't need to change your `global.yaml` or reset your data.
Upgrading your Appcircle server with offline container images is fully compatible with your already-installed Appcircle server.
:::
First, you need to update your self-hosted Appcircle server package. After you [download and unzip](/self-hosted-appcircle/install-server/linux-package/update#1-download-latest) the Appcircle server package, you can return to this page and follow the instructions below.
- Go into the self-hosted Appcircle server directory.
```bash
cd appcircle-server
```
- You can check the server version. So you will see which Appcircle server version images will be downloaded and loaded into the container engine.
```bash
./ac-self-hosted.sh --version
```
- Shutdown the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
:::caution
You should change the "spacetech" value in above command with your project name.
:::
- Get the offline container images and update your local images.
- If your Appcircle server has no internet access, follow the instructions at [Install on a Server With No Internet Access](#install-on-a-server-with-no-internet-access) section.
- If your Appcircle server has internet access, follow the instructions at [Install on a Server With Internet Access](#install-on-a-server-with-internet-access) section.
- Start the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
- Check that your services are healthy and the Appcircle server is ready-to-use.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
- Check your image IDs and digests.
```bash
./ac-self-hosted.sh -n "spacetech" version
```
:::caution
Those steps above will result in system downtime.
It is recommended to perform those operations during a maintenance window when users have been notified and there is no active usage of the system.
Ideally, scheduling the update for a time such as 03:00 am, when user activity is typically minimal, will minimize service disruptions.
:::
---
## Restarting Host
# Overview
In this section, we will discuss how to enable automatic startup of your Appcircle server.
For Docker users, there are built-in mechanisms that handle container restarts, eliminating the need for manual intervention.
However, Podman users will need to create a systemd unit service to ensure the application starts automatically upon server reboot.
## Docker
With Docker, you can rely on the built-in restart policies to handle the automatic startup of your Appcircle server.
Docker will automatically restart the server services if the host reboots.
This eliminates the need for any additional steps or configurations to ensure your application restarts upon host restart.
## Podman
When using Podman, you will need to create a systemd unit service to enable the automatic startup of your application containers.
By creating a systemd unit file and configuring it to launch your Appcircle server, you can ensure that your application starts automatically upon host reboot.
To create a systemd unit service for automatic startup of the Appcircle server, you can follow these steps:
:::caution
You need to have root access on your system for the steps below. Being able to run `sudo` is required. (sudoer)
:::
- Create a unit service file.
```bash
sudo vi /etc/systemd/system/appcircle-server.service
```
- Add the following content to the file.
```systemd
[Unit]
Description=Appcircle Server
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
User=${USER}
Group=${GROUP}
ExecStartPre=/usr/bin/loginctl enable-linger ${USER}
ExecStart=/bin/bash ${APPCIRCLE_SERVER_DIR}/ac-self-hosted.sh -n spacetech up
Type=oneshot
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
```
As seen above, some fields have variables(`${.}`) that **must be replaced with the exact values**, according to your runtime environment.
:::caution
You must edit the fields in the service file before enabling the service.
:::
- **User:** Replace `${USER}` with your logged in user which is expected to be the owner of the Appcircle server directory.
```bash
stat -c "%U" appcircle-server
```
- **Group:** Replace `${GROUP}` with your logged in user's group which is expected to be the owner of the Appcircle server directory.
```bash
stat -c "%G" appcircle-server
```
- **PreStart:** Replace `${USER}` with your logged in user. It should have the same value as **User** field above.
- **ExecStart:** Replace `${APPCIRCLE_SERVER_DIR}` with the absolute path of the Appcircle server directory.
```bash
realpath appcircle-server
```
Also, do not forget to **change the project name to your project**, since "spacetech" is our sample project in the documents.
You can get a list of your projects in Appcircle server directory with the command below.
```bash
ls -d -1 appcircle-server/projects/*/ | xargs -n 1 basename
```
When the systemd unit file is ready, we need to enable it with the commands below:
- Reload the systemd daemon to make it aware that a new service exists.
```bash
sudo systemctl daemon-reload
```
- Enable the service.
```bash
sudo systemctl enable appcircle-server.service
```
Now, the service is supposed to start on boot, and it should start the Appcircle server when triggered.
---
## Testing Distribution Customization
# Customize the Testing Distribution on Self-hosted Installations
Some additional Testing Distribution settings can be customized for self-hosted installations in order to make them more tailored to your users.
For self-hosted specific settings, you should follow the documentation below.
## Testing Portal Logo
By default, if the shared app link in the emails is expired or not available, users will be redirected to the Testing Portal homepage. And on this homepage, users will see the Appcircle logo, as you can see in the example below.
You can change this logo with your company's assets using SVG or PNG files of the logo as you want.
To configure the testing portal logo, you need to SSH into the Appcircle server and edit the `global.yaml` file of the project.
Also, you need to copy the logo file to the Appcircle server before starting configuration.
:::caution
Be aware that this will cause a downtime on the Appcircle server.
:::
- Log in to Appcircle server with SSH or remote connection.
- Locate the image file on the Appcircle server and find out the full path of the logo file.
For example, assume that your logo file is `spacetech-logo.svg`, and it is in the current working directory.
You should run the `realpath` command to get absolute path of the file as below.
```bash
realpath spacetech-logo.svg
```
Sample output can like below:
```bash
/home/ubuntu/appcircle-server/spacetech-logo.svg
```
We will use that path in the `global.yaml` file.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
:::info
The `spacetech` in the example codes below are example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
- Shutdown Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
Check for the `testerWeb` key. If it does not exist in the `global.yaml`, you should add it.
You should create a `logoSvg` key under the `testerWeb` and enter the path of the logo (SVG) file that we got before.
See the example `global.yaml` section below that's compatible with our sample logo file.
```yaml
testerWeb:
logoSvg: /home/ubuntu/appcircle-server/spacetech-logo.svg
```
If your logo is a PNG file, then you should set the file path to the `logoPng` key, like in the example below.
```yaml
testerWeb:
logoPng: /home/ubuntu/appcircle-server/spacetech-logo.png
```
:::info
If you declare both of the `logoPng` and `logoSvg` in the `global.yaml`, then the **PNG** image will be used as the logo on the Testing Portal.
:::
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
:::
To see the new configuration updates on the Testing Portal, follow the steps below:
- Navigate to the Appcircle server's `dist` URL in your browser.
- For example, `https://dist.appcircle.spacetech.com`
You can get more information about `dist` subdomain from the [DNS Settings](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings) document.
---
## Troubleshooting & FAQ for Appcircle Server and Runner
# Overview
This section is designed to help you quickly find answers to common questions and provide you with a better understanding of Appcircle server and runner.
## Appcircle Server FAQ
### Can I change the password of the initial user?
For now, you shouldn't change the initial user password you defined in the `global.yaml`.
### Does Appcircle support LDAP login?
Appcircle supports LDAP login on the Testing Distribution and Enterprise App Store modules. For more details about enabling the LDAP, you can head over to the [Enterprise App Store](/account/my-organization/security/authentications/store-ldap-authentication) and [Testing Distribution](/account/my-organization/security/authentications/distribution-ldap-authentication) LDAP settings documents.
Appcircle also supports LDAP login on the Appcircle dashboard, where you log in to create build profiles and other developer-related jobs. For more details about enabling LDAP on the Appcircle dashboard, you can head over to the [Appcircle Login with LDAP](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ldap-settings) document.
### We can't send mail to outside domains.
Let's say your company's domain is `spacetech.com`. And you can send mail from Appcircle to `user@spacetech.com`, but you can't send mail to `user@gmail.com`.
You should check the SMTP configuration and allow SMTP server to send mail to outside domains.
### While installing the Appcircle server with Podman, `minio` containers can't get healthy status.
The podman network backend should be `netavark`. You can check the current settings with the command below:
```bash
podman info | grep -i networkBackend
```
If you need to use a proxy on the Appcircle server, you should configure proxy settings according to the [Proxy Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration) document.
### We are facing "manifest not found" error when we run the `up` command.
If you are using the Nexus registry and are facing a "manifest not found" error, this is an expected case to occur. Nexus proxy has a known bug while pulling multiple container images. You should pull images one by one as a workaround.
To pull images one by one, you can see the [Pulling Image One By One](./configure-server/external-image-registry#pulling-images-one-by-one) document. Then you can pull images one by one with this script. So you won't face "manifest not found" error any more.
### Where should we download the zip package while we are updating?
Download the zip package of the appcircle server and extract it to the same folder as the already existing Appcircle server folder. Your data and configuration will be saved while updating.
### How do I change Docker or Podman's data location?
For more details on changing the location of Docker data, refer to the [Change the Docker Data Location](/self-hosted-appcircle/install-server/linux-package/installation/docker#change-the-docker-data-location) page.
For more details on changing the location of Podman data, refer to the [Change the Podman Data Location](./installation/podman#change-the-podman-data-location) page.
### I'm offline on the Appcircle dashboard on my browser.
You should trust the Appcircle's or your organization's root CA certificate on your computer.
### We are getting the "potentially insufficient UIDs or GIDs" error while using Podman.
You should check the user ID and group ID of your current account.
```bash
id
```
The user ID and group ID should be four-digit numbers. (For example, 1000, 1002, etc.)
If your user ID and group ID are very large, you may get this error. In this case, you should create a new user and group with regular IDs.
### We want to change the Enterprise App Store custom domain. What should we do?
You can change the custom domain settings of Enterprise App Store from the `global.yaml` configuration file.
:::caution
We are assuming that you have installed the Appcircle server with version `3.11.0` or later for this operation.
:::
- Log in to the Appcircle server with SSH or a remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
:::info
The `spacetech` in the example codes below are example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
- Shutdown Appcircle server. Keep in mind that, this will cause downtime.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Edit the `global.yaml` file of your project.
```bash
vi ./projects/spacetech/global.yaml
```
```yaml
storeWeb:
customDomain:
enabled: true
domain: store.spacetech.com
```
:::caution
If the certificate of the custom store domain is not defined in the `global.yaml` file, the Enterprise App Store will listen on HTTP by default. It will not use the server-wide certificate defined in `.nginx.sslCertificate` for the Enterprise App Store.
To enable HTTPS for the Enterprise App Store, you must provide `.storeWeb.customDomain.publicKey` and `.storeWeb.customDomain.privateKey` values. For details, refer to the [SSL Configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration#custom-domain) docs.
:::
- Apply configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Boot Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::tip
You should check the status of the Appcircle server after boot for any possible errors.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
:::
Now you can access the Enterprise App Store with the new store domain settings.
### How can we change the default sub-domains?
:::caution
This operation needs **[reset](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/installation/docker#reset-configuration)** which deletes all your data like "Build Profiles", "Signing Identities", etc on the Appcircle server.
:::
:::tip
If you only want to change the URL of the **Testing Distribution** or **Enterprise App Store**, you should follow the [custom domain](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration#custom-domain) configuration document to assign a custom domain without resetting the Appcircle server.
:::
You can change the default subdomains as per your needs at the first installation time of the Appcircle server.
If you have already installed the Appcircle server and want to change the subdomains, you must **[reset](https://docs.appcircle.io/self-hosted-appcircle/install-server/linux-package/installation/docker#reset-configuration)** the server before applying a new configuration.
For example, to change `my.appcircle.spacetech.com` to `my-appcircle.spacetech.com` along with other subdomains, you should follow the steps below:
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
:::info
The `spacetech` in the example codes below is an example project name.
Please find your own project name and replace `spacetech` with your project name.
To see projects, you can check the `projects` directory.
```bash
ls -l ./projects
```
:::
- Edit the `global.yaml` of your project for subdomain changes.
```bash
vi ./projects/spacetech/global.yaml
```
```yaml
keycloak:
external:
subdomain: auth-appcircle
webApp:
external:
subdomain: my-appcircle
apiGateway:
external:
subdomain: api-appcircle
testerWeb:
external:
subdomain: dist-appcircle
webEvent:
external:
subdomain: hook-appcircle
minio:
external:
subdomain: resource-appcircle
storeWeb:
external:
subdomain: store-appcircle
webEventRedis:
external:
subdomain: redis-appcircle
grafana:
external:
subdomain: monitor-appcircle
```
:::caution
If the keys already exist in the `global.yaml`, you should just update or add the missing keys.
For example, if you already have the `keycloak` key in global.yaml, you must just add the `keycloak.external.subdomain` section there.
:::
- Edit the `mainDomain` of your project in the `global.yaml` file.
```yaml
external:
mainDomain: ".spacetech.com"
```
:::caution
The subdomains will be concatenated to the **`mainDomain`**.
For this reason, `external.mainDomain` in the configuration file must always begin with a `.` character as a prefix.
:::
:::tip
After you change the main domain and the subdomains, you can merge them yourself to see the up-to-date URLs for Appcircle modules.
For example;
- when `mainDomain` is `.spacetech.com`
- and `webApp` `subdomain` is `my-appcircle`
then the Appcircle dashboard URL will be `my-appcircle.spacetech.com`.
:::
:::danger
If you have configured the Appcircle server as HTTPS, as an extra step, it may be required to change the SSL certificates in the `global.yaml` if they are not compatible with your new subdomains.
See the **[SSL configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration)** document for details.
:::
When the `global.yaml` changes are ready to apply, follow the below steps:
- Stop the server.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
- Cleanup server data.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
:::info
The `reset` step is optional. If you are installing for the first time, which means that you have never run the `up` command and used the system, then you don't need to cleanup anything.
For details, you can see the [reset configuration](./installation/docker#reset-configuration) section in the documentation.
:::
- Apply the configuration changes.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
- Start the server.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
- Check the health of the services.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You should see the message: _"All services are running successfully."_
### While connecting to a repository from GitLab, we can list the projects, but binding is failing.
The first thing you should check is **PAT** permissions.
If you are sure that **PAT** has the required permissions, you should check the **Outbound Requests** configuration of your GitLab server.
For more details about configuring the outbound requests, you can refer to the [Outbound Requests](/build/manage-the-connections/connection-guides/connecting-to-gitlab#outbound-requests) section.
### What should be done after upgrading the hardware resources (CPU & memory) of the Appcircle server?
When you upgrade the hardware resources (CPU & memory) of the Appcircle server, it's important to update the **resource limits** accordingly.
Appcircle sets these limitations with the `export` command and configures CPU and memory limits for the services. If you don't run the `export` command again after updating the CPU and memory of the Appcircle host machine, the Appcircle services will continue to use the old resource limits.
To ensure the new resource limits are applied, follow these steps:
- Log in to the Appcircle server with SSH or a remote connection.
- Go to the `appcircle-server` directory.
```bash
cd appcircle-server
```
### How can we restrict the TLS versions used by the Appcircle server?
To restrict the TLS versions used by the Appcircle server, you can follow the [Configure TLS Versions](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration#configure-tls-versions) section in the **SSL Configuration** documentation.
---
## Install the Self-Hosted Appcircle Server
This document provides an overview of the steps required to install the self-hosted Appcircle on your infrastructure. It's a summary of the overall journey and gives you an idea of the big picture.
For detailed instructions, please refer to the corresponding pages mentioned below.
## Server Installation
### Supported Linux Distributions
Before proceeding with the installation, it is essential to verify the compatibility of the targeted operating system version.
If you're planning to use **Docker** as the container runtime engine, you should check for compatible OS versions [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#supported-linux-distributions)
If you're planning to use **Podman** as the container runtime engine, you should check for compatible OS versions [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#supported-linux-distributions)
### Hardware Requirements
Check CPU, memory, swap, and disk space requirements.
You can check the hardware requirements [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#hardware-requirements)
### Dependencies for Download
To download and extract the application installation zip package, you need to install the necessary dependencies.
You can see the dependencies [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download).
### Download and Extract the Package
Obtain the application's zip file and extract its contents.
You should follow the download and extract processes [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download)
### Install Server Dependencies
Install additional dependencies and packages required by the self-hosted Appcircle server.
If you're planning to use **Docker** as the container runtime engine, you can check application dependencies and how to install them [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#2-packages)
If you're planning to use **Podman** as the container runtime engine, you can check application dependencies and how to install them [here.](/self-hosted-appcircle/install-server/linux-package/installation/podman#2-packages)
#### Configure Podman Specific Settings
:::info
You should skip this step if you are installing the application with Docker.
:::
If you are installing the server with Podman, you must configure Podman's network settings. And also need to install an additional application to use podman rootless.
You can check the port forwarding settings [here.](/self-hosted-appcircle/install-server/linux-package/installation/podman#podman-requirements)
You can check the Podman network stack settings [here.](/self-hosted-appcircle/install-server/linux-package/installation/podman#podman-network-stack)
### Configure Server Settings
You need to edit the default `global.yaml` file for your requirements and infrastructure.
You can see the detailed configuration steps [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure)
#### HTTP and HTTPS Settings
You can utilize the Appcircle server in either HTTP or HTTPS mode, which can be configured in the `global.yaml` settings file.
After following the general configuration steps above, see the SSL configuration details [here.](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration)
#### Domain Settings of the Modules
You need to set a main domain for the Appcircle server. Also, you should decide the domain configurations for the Enterprise App Store and Testing Distribution modules.
#### SMTP Settings for Email Notifications
To utilize email services such as registration or testing distribution notifications, it is necessary to define SMTP settings in the Dashboard (recommended) or `global.yaml` configuration file.
#### Initial Username and Password
The initial user will be the owner or administrator of the organization on the Appcircle server. So, you should configure it in `global.yaml` properly.
### DNS Settings for Subdomains
The Appcircle server has some subdomains for different services. They should be configured according to the network infrastructure.
You can see the DNS configuration details [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings)
### Pull the Container Images
The Appcircle server is a containerized application composed of microservices.
Prior to running the server, it is necessary to pull the images from the Appcircle image repository. You don't need to perform an additional step to pull container images, as the Appcircle install script will automatically handle the image retrieval process.
If you're planning to use a proxy repository to access the origin repository, it should be defined in the `global.yaml` configuration file.
You can check the required steps on how to define a custom image registry [here.](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry)
:::caution
You need `cred.json` file to pull the container images. Only the enterprise customers who have self-hosted Appcircle license can have `cred.json`.
For details about the `cred.json`, see [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#artifact-registry-credentials-credjson)
:::
### Initialize Vault
Before starting the Appcircle server, you should initialize the [vault](/self-hosted-appcircle/install-server/linux-package/installation/docker#vault).
You can check out how to initialize the vault [here.](/self-hosted-appcircle/install-server/linux-package/installation/docker#5-initialize-vault)
### Run the Appcircle Server
At the end, you are ready to start the Appcircle server. 🎉
Start the server and verify its [health.](/self-hosted-appcircle/install-server/linux-package/installation/docker#6-run-server)
## Runner Installation
To build and distribute mobile applications, you need self-hosted Appcircle runners that are connected to the server.
You can check out how to install a self-hosted runner [here.](/self-hosted-appcircle/self-hosted-runner/installation)
### Connect Runner to the Server
You need to connect your self-hosted runner to the server. So the server can share builds and distribute jobs with the runner.
You can check how to connect runner to server [here.](/self-hosted-appcircle/self-hosted-runner/installation#2-register)
## Build a Sample App
To test overall functionality and system stabilization, you can build example mobile applications.
If you don't have one, you can use the sample repositories of Appcircle mobile applications.
To build sample applications, create a build profile. After that, you can click Quick start using the sample repository" button to import sample Appcircle repositories.
If you're on a restricted network and cannot reach Appcircle's GitHub repository, you can import the sample apps to your git provider on your private network and use them from there.
Below is a list of sample apps that you can use for demoing or testing:
- [iOS sample app](https://github.com/appcircleio/appcircle-sample-ios)
- [Android sample app](https://github.com/appcircleio/appcircle-sample-android)
- [Flutter sample app](https://github.com/appcircleio/appcircle-sample-flutter)
- [React Native sample app](https://github.com/appcircleio/appcircle-sample-react-native)
:::info
Please note that this overview serves as a high-level roadmap, and detailed instructions for each step can be found in the associated pages.
For more detailed instructions to install the server, please refer to installation page.
Click [here](/self-hosted-appcircle/install-server/linux-package/installation/docker) to see Appcircle server installation on **Docker**.
Click [here](/self-hosted-appcircle/install-server/linux-package/installation/podman) to see Appcircle server installation on **Podman**.
:::
---
## Install Appcircle on Amazon Web Services (AWS)
## Overview
An Appcircle server Amazon Machine Image (AMI) is a pre-configured template used to create virtual servers, known as instances, in the [Amazon Web Services (AWS)](https://aws.amazon.com/marketplace/seller-profile?id=seller-qo4qliw4g7f6k) environment.
Think of it as a snapshot of a server that includes the operating system, necessary tools, applications, and any additional services needed to run the Appcircle server.
## Pre-requirements
### Appcircle Requirements
If you don't apply a license, you can go on with the package located in the AMI and use the Appcircle server as a "Starter Plan" user. But it's recommended to purchase a license from Appcircle that will increment the license limits and enable you to access the Appcircle resources for future upgrades.
If you are a licensed user, you should [contact us](https://appcircle.io/support/) about the licensed Appcircle server package that includes your actual license.
### Technical Requirements
Before using the Appcircle server AMI, there are a couple of things that you need to handle.
#### AWS Account
You must have an active AWS account with appropriate permissions to launch EC2 instances and work with other related services.
#### Understanding of AWS Services
A basic understanding of Amazon Web Services (AWS) services, particularly EC2 (Elastic Compute Cloud), is beneficial.
You should be familiar with instance creation, networking, security groups, and storage configurations.
##### 1. Networking and Security Configuration
You might need to configure networking aspects such as Virtual Private Cloud (VPC), subnets, route tables, and security groups to properly integrate the instance within the network environment and manage access controls.
##### 2. SSH Key Pairs for Secure Access
You need an SSH key pair to access to the server that you will create securely.
##### 3. Linux System Configuration
Basic familiarity with Linux system configurations and commands is essential since this document will use Linux commands.
## Creating an Appcircle Server from the AMI
After you meet all the requirements discussed above, you can follow the steps below to create an Appcircle server from the AMI.
- Log in to the AWS console with your account.
- Select the region from the right upper corner.
- Head to the EC2 menu to create an EC2 instance.
- Click on the "Launch Instance" button from the EC2 dashboard.
You should fill out the required fields as per your needs. Please follow the below steps for a sample instance configuration.
- Enter an instance name in the "Name and Tags" field. For example, "My Appcircle Server".
- In order to select the AMI, click on the "Browse more AMIs" button and search for the Appcircle server AMI.
- Search for "Appcircle" in the "AWS Marketplace AMIs" tab and click on the "Select" button for the AMI.
- Click "Continue" to select Appcircle server AMI.
- We will use the `t3.2xlarge` instance type for our sample configuration since it meets the minimum requirements for the vCPU count.
:::info
For the details about minimum hardware requirements, you should see the [Hardware Requirements](/self-hosted-appcircle/install-server/linux-package/installation/docker#hardware-requirements) section.
:::
- Select an existing key pair or click on the "Create new key pair" button if you don't have any on the AWS console.
- For the network settings:
- We will use the default VPC created on the form.
- Allow HTTP and HTTPS traffic from the internet.
- This is **required** for accessing the Appcircle server dashboard.
- Allow SSH traffic.
- **SSH is also required** to access the server from the command line.
- You can restrict the SSH connection by specifying the source IP addresses.
:::tip
If you want to also send `ping` requests to the instance for health check purposes, you can also add another rule with the type "All ICMP-IPv4" while editing the inbound rules of the security group after the instance and security group are created.
:::
- For storage, you can select a minimum 100-GB disk for a PoC setup or testing purposes.
:::info
You should see the recommended storage sizes and other disk requirements in the [Hardware Requirements](/self-hosted-appcircle/install-server/linux-package/installation/docker#hardware-requirements) section.
:::
:::caution
Keep in mind that the pre-configured swap also consumes disk space, and its size is as large as the memory size.
So, although a minimum 100-GB disk is enough to run the Appcircle server, we recommend a minimum 200-GB disk space for long-term usage.
:::
Now you're ready to click on the **Launch Instance** button to create the instance with the configuration you made.
:::info
The instance creation may take some time due to the AWS AMI subscriptions.
Please wait patiently while AWS creates your Appcircle server instance. If the instance is not created within 2 hours, you can follow the steps above and launch it again.
You can check the subscription in the "AWS Marketplace Subscriptions" service in the AWS console.
:::
You can head to the EC2 **Instances** page to see if your server is up and running.
## Configuring the Appcircle Server Instance
### Connect via SSH
After you have successfully created an EC2 instance from the Appcircle server AMI, you can follow the steps below to configure it.
- Get the IP address of the instance from EC2 dashboard.
- Networking > Networking Details > Public IPv4 address
- Or, Instance > Details > Public IPv4 address
- Locate the SSH key pair, especially the private key, that you've created or used while configuring the instance.
- Get an SSH connection tool like `putty` on Windows or `ssh` on macOS and Linux to connect to the instance.
:::info
The `ssh` command below is for macOS and Linux. The other commands are the same after you connect to the instance.
:::
Using **private key** and **IP address**, you can connect to the instance with SSH as seen below.
```bash
ssh -i "/path/to/your/private/key" ubuntu@ip-address-of-the-instance
```
:::info
The default user for the Appcircle AMI is `ubuntu`.
So, let's assume that your instance IP address is `34.205.139.17` and your private SSH key path is `/home/spacetech/.ssh/id_rsa`.
You can connect to the instance using the below command on macOS or Linux.
```bash
ssh -i "/home/spacetech/.ssh/id_rsa" ubuntu@34.205.139.17
```
:::
:::tip
When you "Create new key pair" while creating the instance from Appcircle AMI, the downloaded private key might cause a permission error when you try to connect to the instance. For instance;
> ... Permissions 0644 for 'MyCICDSSHKey.pem' are too open.
> It is required that zour private key files are NOT accessible by others.
> This private key will be ignored. ...
In this case, you need to change the permissions of the private key using the below command before connecting.
```bash
chmod 600 "/path/to/your/private/key"
```
It will be a one-time-operation that should be done once per private key.
:::
:::info
The SSH command may ask you to add this server to the list of known hosts. You should write `yes` and hit enter.
:::
### Configure Server
## Connecting Runners
When you complete installation successfully by following the above steps, you're ready for your first build. :tada:
But in order to run build pipelines, you need to install and connect self-hosted runners. We have a dedicated section for the installation and configuration of self-hosted runners. Follow and apply related the guidelines [here](/self-hosted-appcircle/self-hosted-runner/installation).
:::tip
Appcircle also supports the installation and execution of the runners on AWS.
You can see the details about how to configure a runner on AWS **[here](/self-hosted-appcircle/self-hosted-runner/cloud-providers/aws)**.
:::
The self-hosted runner section in the documents has all the details about runners and their configuration.
:::caution
By default, self-hosted runner package has pre-configured `ASPNETCORE_BASE_API_URL` for Appcircle-hosted cloud.
- `https://api.appcircle.io/build/v1`
:point_up: You need to change its value with your self-hosted Appcircle server's API URL.
Assuming our sample scenario explained in [configuration](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure), its value should be
- `http://api.appcircle.spacetech.com/build/v1`
for our sample scenario.
:reminder_ribbon: After [download](/self-hosted-appcircle/self-hosted-runner/installation#1-download), open `appsettings.json` with a text editor and change `ASPNETCORE_BASE_API_URL` value according to your configuration.
Please note that you should do this before [registering](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
:::
Considering system performance, it will be good to install self-hosted runners on other machines. A self-hosted Appcircle server should run on a dedicated machine itself.
You can install any number of runners according to your needs and connect them to a self-hosted Appcircle server.
Have questions? [Contact us here.](https://appcircle.io/support/)
---
## Install Appcircle on Microsoft Azure
## Overview
An Appcircle server image is a pre-configured template used to a create virtual server, known as "virtual machines", in the [Microsoft Azure](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/appcircleinc1727251401364.acserverv0?tab=Overview) environment.
Think of it as a snapshot of a server that includes the operating system, necessary tools, applications, and any additional services needed to run the Appcircle server.
This documentation provides step-by-step instructions for configuring and setting up Appcircle Server on Microsoft Azure. Follow these guidelines to ensure a successful deployment.
## Prerequisites
### Appcircle Requirements
### Technical Requirements
Before using the Appcircle server image, there are a couple of things that you need to handle.
#### Microsoft Azure Account
You should have an active Azure account with appropriate permissions to launch virtual machines and work with other related services.
#### Understanding of Azure Services
A basic understanding of Azure services, particularly Virtual Machines, is beneficial.
You should be familiar with virtual machine creation, networking, security groups, and storage configurations.
##### 1. Networking and Security Configuration
You might need to configure networking aspects such as virtual networks, subnets, route tables, and security groups to properly integrate the instance within the network environment and manage access controls.
##### 2. SSH Key Pairs for Secure Access
You need an SSH key pair to access the server that you will create securely.
##### 3. Linux System Configuration
Basic familiarity with Linux system configurations and commands is essential since this document will use Linux commands.
## Creating an Appcircle Server from the server image
After you meet all the requirements discussed above, you can follow the steps below to create an Appcircle server from the server image.
- Log in to Microsoft Azure with your account.
- Head to the Virtual machines menu to create a virtual machine.
- Click on the "+ Create" button and "Azure virtual machine" from the virtual machines dashboard.
You should fill out the required fields as per your needs. Please follow the steps below for a sample instance configuration.
- Select the Subscription and Resource group for your needs.
- Enter a virtual machine name in the "Instance details" field. For example, "My-Appcircle-Server".
- Choose which region you want the server to be in.
- Select the "Standard" option as the security type.
:::note
The Appcircle server currently **only supports the "Standard" option** as a security type, and other security types are not planned for the short term.
:::
- In order to select the Appcircle server image, click on the "See all images" button and search for the Appcircle server image.
- Search for "Appcircle" in the "Marketplace" tab and click on the "Select" button for the server image and select "Plan BYOL - x64 Gen2".
:::info
Although we recommend selecting the **Gen2** image for the Appcircle server by default, if you don’t need any additional features such as Secure Boot or TPM, you can also select the **Gen1** image, and it will be compatible. Both options can be used for the Appcircle server.
However, please note that you cannot change the generation after the VM is created. For a detailed comparison between Gen1 and Gen2, visit the [Microsoft documentation](https://learn.microsoft.com/en-us/azure/virtual-machines/generation-2).
:::
- We will use the `Standart_D4s_v4` size for our sample configuration since it meets the minimum requirements for the vCPU count and memory size.
- Use the dropdown menu to view the recommended instance types for this image.
- To choose a different configuration, click on **"See all sizes"** to browse all available instance types.
:::info
For the details about minimum hardware requirements, you should see the [Hardware Requirements](/self-hosted-appcircle/install-server/linux-package/installation/docker#hardware-requirements) section.
:::
- We highly recommend changing the username to `ubuntu`.
:::warning
We strongly recommend using the default username `ubuntu` for the Appcircle server setup since the VM image and its associated documentation are configured with the username `ubuntu`.
If you choose to change the username, please be aware that **[additional steps](#custom-username)** are required **after the image is created**.
:::
- Select an existing key pair or click on the "Generate new key pair" button if you don't have any on Azure. In the sample configuration, we will use an existing key stored in Azure by selecting from the dropdown menu.
- Click "Next: Disks >"
- From the Disks menu, configure the OS disk size. By default, the image comes with 100 GiB of disk space. You can increase that size for your needs.
:::info
You should see the recommended storage sizes and other disk requirements in the [Hardware Requirements](/self-hosted-appcircle/install-server/linux-package/installation/docker#hardware-requirements) section.
:::
- Click "Next: Networking >"
- We will use the default Virtual network that Azure provides. You can customize the network according to your needs, such as limiting incoming traffic to known IP addresses for SSH connections.
Now you're ready to create the virtual machine with the configuration you made. Click on the **Review + create**, then click **Create** on the next page.
After the deployment is completed, you can click **Go to resource** button or head to the **Virtual machines** service to see the deployed instance.
:::tip
By default, `80`, `443`, and `22` ports are allowed on the firewall.
If you want to send `ping` requests to the instance for health check purposes, you should add an inbound port rule with the protocol "ICMPv4" from the networking tab of the virtual machine.
:::
:::info
If you plan to use the Appcircle server over HTTP, please note that TCP port `6379` is required for proper functionality.
Depending on your deployment, ensure that TCP port `6379` is open for inbound traffic.
:::
## Configuring the Appcircle Server Instance
### Connect via SSH
After you have successfully created a virtual machine from the Appcircle server image, you can follow the steps below to configure it.
- Get the IP address of the instance from the virtual machines dashboard.
- Locate the SSH key pair, especially the private key, that you've created or used while configuring the virtual machine.
- Get an SSH connection tool like `putty` on Windows or `ssh` on macOS and Linux to connect to the instance.
:::info
The `ssh` command below is for macOS and Linux. The other commands are the same after you connect to the instance.
:::
Using the **private key** and **IP address**, you can connect to the instance with SSH as seen below.
```bash
ssh -i "/path/to/your/private/key" ubuntu@ip-address-of-the-instance
```
:::info
The **default user** for the Appcircle server image is **`ubuntu`** if you have followed the [Creating Virtual Machine](#creating-an-appcircle-server-from-the-server-image) section above. If you used a custom username while creating the VM, please use that user for the following steps.
So, let's assume that your instance IP address is `34.205.139.17` and your private SSH key path is `/home/spacetech/.ssh/id_rsa`.
You can connect to the instance using the command below on macOS or Linux.
```bash
ssh -i "/home/spacetech/.ssh/id_rsa" ubuntu@34.205.139.17
```
:::
:::tip
When you "Create new key pair" while creating the instance from the Appcircle server image, the downloaded private key might cause a permission error when you try to connect to the instance. For instance;
> ... Permissions 0644 for 'MyCICDSSHKey.pem' are too open.
> It is required that your private key files are NOT accessible by others.
> This private key will be ignored. ...
In this case, you need to change the permissions of the private key using the below command before connecting.
```bash
chmod 600 "/path/to/your/private/key"
```
It will be a one-time operation that should be done once per private key.
:::
:::info
The SSH command may ask you to add this server to the list of known hosts. You should write `yes` and hit enter.
:::
### Configure Server
:::warning
#### Custom Username
If you have changed the username of the VM during its creation instead of using the default one in the document (`ubuntu`), these are the additional steps you need to follow before server configuration:
1. Create a directory at your desired location for the Appcircle server. For instance, `/app`.
```bash
sudo mkdir /app
```
2. Move the `appcircle-server` directory to the new location.
```bash
sudo mv /home/ubuntu/appcircle-server /app/
```
3. Update the ownership of the directory with current the `$USER`.
```bash
sudo chown -R $USER:$USER /app
```
4. Add the current user to the `docker` group for the Docker runtime.
```bash
sudo usermod -a -G docker $USER
```
5. In order to activate group change, log out and re-login to the instance using an SSH connection or run the command below to go on with the current terminal session.
```bash
sudo chown $USER /var/run/docker.sock
```
Keep in mind that, **for all subsequent configuration steps**, the `appcircle-server` directory will be located at your new location, for instance `/app`, instead of the default `$HOME` directory.
:::
## Connecting Runners
When you complete installation successfully by following the above steps, you're ready for your first build. :tada:
But in order to run build pipelines, you need to install and connect self-hosted runners. We have a dedicated section for the installation and configuration of self-hosted runners. Follow and apply the related the guidelines [here](/self-hosted-appcircle/self-hosted-runner/installation).
:::tip
You can install the Appcircle runner on another Azure VM by ensuring the VM size meets the runner's requirements. Check the Appcircle runner installation page for detailed requirements.
:::
The self-hosted runner section in the documents has all the details about runners and their configuration.
:::::caution
By default, self-hosted runner package has pre-configured `ASPNETCORE_REDIS_STREAM_ENDPOINT` and `ASPNETCORE_BASE_API_URL` for Appcircle-hosted cloud.
- `webeventredis.appcircle.io:6379,ssl=true`
- `https://api.appcircle.io/build/v1`
:point_up: You need to change these values with your self-hosted Appcircle server's Redis and API URL.
Assuming our sample scenario explained above, these values should be:
- `redis.appcircle.spacetech.com:6379,ssl=false`
- `http://api.appcircle.spacetech.com/build/v1`
for our example configuration.
:::info
If your Appcircle server is running with `HTTPS`, then Redis and API URL should be like this:
- `redis.appcircle.spacetech.com:443,ssl=true`
- `https://api.appcircle.spacetech.com/build/v1`
:::
:reminder_ribbon: After [download](/self-hosted-appcircle/self-hosted-runner/installation#1-download), open `appsettings.json` with a text editor and change the `ASPNETCORE_REDIS_STREAM_ENDPOINT` and the `ASPNETCORE_BASE_API_URL` values according to your configuration.
Please note that, you should do this before [register](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
:::::
Considering system performance, it will be good to install self-hosted runners on other machines. A self-hosted Appcircle server should run on a dedicated machine itself.
You can install any number of runners according to your needs and connect them to a self-hosted Appcircle server.
Have questions? [Contact us here.](https://appcircle.io/support/)
---
## Cloud Providers
Leverage the power of cloud computing within your Appcircle builds by integrating with Cloud Providers. This section details how to connect with Amazon Web Services (AWS), allowing you to scale your build infrastructure on-demand and access a wide range of cloud resources.
## [Amazon Web Services (AWS)](/self-hosted-appcircle/install-server/linux-package/installation/cloud-providers/aws)
Enhance your building and testing capabilities by integrating Amazon Web Services (AWS) into your workflow. Follow the step-by-step guide to set up AWS with your Appcircle environment for improved performance and flexibility.
## [Microsoft Azure](/self-hosted-appcircle/install-server/linux-package/installation/cloud-providers/azure)
Expand your Appcircle build capabilities by integrating with Microsoft Azure. Follow the detailed instructions to connect your Appcircle environment with Azure and access to Azure's extensive cloud services.
---
## Docker
# Overview
Following sections give you detailed information about system requirements, installation and configuration steps. After following directives successfully, you will get a running Appcircle instance on your infrastructure.
## Prerequisites
Below are the hardware and OS requirements for self-hosted Appcircle installation.
### Supported Linux Distributions
Self-hosted Appcircle server utilizing Docker, can only be installed on Linux operating system.
- Ubuntu 20.04 or later
- Debian 11 or later
- CentOS 8 or later
- RHEL 8 or later
### Hardware Requirements
Minimum hardware requirements for self-hosted Appcircle can be:
- 100GB or more free disk space
- 4 or more cores CPU
- 8 or more gigabytes (GB) RAM
:point_up: These hardware specs are minimum requirements for basic execution and it can be used only for quick evaluation or development purposes.
:::caution
CPU architecture must be AMD or Intel 64-bit arch (`x86_64`).
:::
:::info
If you have enough RAM and a recent CPU, performance of Appcircle server can be limited by hard drive seek times. So, having a fast drive like a solid state drive (SSD) improves runtime.
:::
Higher numbers will be better especially for increased number of users.
For an enterprise installation, **minimum** hardware requirements are
- 500GB SSD
- 8 CPU
- 16GB RAM
For production environments, **recommended** hardware requirements are
- 1TB SSD
- 32 CPU
- 64GB RAM
:::caution
#### Swap
Using **swap** file lets self-hosted Appcircle server exceed the size of available physical memory. On memory pressure system will go on its operations with minimal degradation, when SSD used as hardware.
So, we are recommending **swap** file usage on Linux.
Its size should be minimum half of the RAM size. For example if you have 64 GB RAM, then you should choose minimum 32 GB swap file size. 64 GB will be better.
#### Swappiness
The `swappiness` parameter configures how often your system swaps data out of RAM to the swap space. So, it's an important setting for swap usage and affects performance.
`10` is recommended value for `swappiness`.
:books: For details on how to configure **swap** and `swappiness` parameter, follow guide in [here](https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-22-04).
:::
## Installation
### 1. Download
You need to have the following tools installed on your system:
- curl
- unzip
To download the licensed Appcircle Server package for your organization, you must copy the `cred.json` file to the directory where you want to install the package.
:::info
Without the `cred.json` file, you will not be able to access the licensed Appcircle Server package.
If you have not yet obtained the `cred.json` file, please contact us for assistance.
:::
Download the latest self-hosted Appcircle package.
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-server.sh | bash
```
Extract self-hosted Appcircle package into folder.
```bash
unzip -o -u appcircle-server-linux-x64-${version}-${build}.zip -d appcircle-server
```
:::info
You should use the downloaded `zip` archive while extracting so that the actual `${version}` and `${build}` will come from there. You can find the relevant data in the previously executed download command output.
:::
Change directory into extracted `appcircle-server` folder for following steps.
```bash
cd appcircle-server
```
### 2. Packages
You need to have the following tool(s) installed on your system.
- docker
The good news is that the ac-self-hosted.sh script installs all the necessary tools if they are not already installed on your system.
:::caution
You need to have root access on your system for this step. Being able to run `sudo` is sufficient for the following step. (sudoer)
:::
To do this, execute the script using the `-i` argument as shown below.
```bash
sudo ./ac-self-hosted.sh -i
```
You can also use the long option `--install-package` for the same purpose.
Make sure the script was executed without any error. Script will print installed and required packages when executed. Some packages may need manual installation on some linux distributions. Check command output for warnings and follow directives given in the output.
:::info
Docker engine is one of our major dependencies. So, its version is also important for Appcircle server runtime.
Older docker versions may be incompatible for our operations. Docker versions above `20.10.11` should be preferred to eliminate any compatibility issues.
If your linux distribution has an out of date docker version, please update distribution's package repository or install latest docker from [here](https://docs.docker.com/engine/install/).
:::
:::caution
#### Docker Engine Installation
Self-hosted Appcircle server is only compatible with official installation methods listed in [here](https://docs.docker.com/engine/install/).
On some Linux distributions you can select docker engine at setup stage, but it's not recommended since some distributions have unofficial installation methods.
For instance, when you select docker engine at setup on Ubuntu installation, Ubuntu installs docker engine via [snap](https://snapcraft.io/install/docker/ubuntu) which will result with an incompatible docker installation.
In this case, you should not include docker engine to Ubuntu installation. If you want, you can install docker engine later with official [installation](https://docs.docker.com/engine/install/ubuntu/) steps.
Or, as a better choice, you can leave docker engine installation to self-hosted Appcircle server installation script since we have automated installation for Debian derivatives which include `apt` package manager.
:::
:::info
You can install docker on RHEL 8.6 and later with the command below:
```bash
curl -sSL -o install-docker.sh "https://storage.googleapis.com/appcircle-dev-common/self-hosted/rpm-packages/install-docker.sh" && \
chmod +x install-docker.sh && \
./install-docker.sh
```
:::
:::info
Self-hosted Appcircle server is only compatible with [docker compose V2](https://docs.docker.com/compose/compose-v2/) and the new `docker compose` command.
The new compose V2, which supports the compose command as part of the docker CLI, is available with latest docker versions.
If you installed docker previously by yourself to the system, please verify that docker compose plugin is also installed correctly by checking the version.
```bash
docker compose version
```
If `docker-compose-plugin` is missing in your system, follow its [docs](https://docs.docker.com/compose/install/linux/) to install docker compose V2 manually.
:::
#### Change the Docker Data Location
In certain scenarios, you may encounter situations where the available free space on the root directory (`/`) is limited. However, you might have ample free space in a different directory, such as `$HOME` or `/opt`.
In such cases, you can modify the Docker data location path to utilize the available space in the desired directory.
These are the steps to change docker data location path:
- Stop the docker engine.
```bash
sudo systemctl stop docker
```
- Move the existing Docker data directory to the new location.
```bash
sudo mv /var/lib/docker $HOME/docker
```
- Create a softlink from default location to the new location.
```bash
sudo ln -s $HOME/docker /var/lib/docker
```
- Start the docker engine.
```bash
sudo systemctl start docker
```
### 3. Configure
First we need to find a name to our self-hosted Appcircle installation. It will be the unique project name.
```bash
./ac-self-hosted.sh -n "${YOUR_PROJECT}" export
```
Let's assume we have company named as Space Tech. Then our project name can be "spacetech". For following steps, we will give examples based on this fictive company for better understanding.
Then our command to execute will be:
```bash
./ac-self-hosted.sh -n "spacetech" export
```
On `ac-self-hosted.sh` execution complete, the folder contains `global.yaml`, `user-secret` files and `export` folder.
```txt
projects
└── spacetech
├── export
├── generated-secret.yaml
├── global.yaml
└── user-secret
```
At this point, the `compose.yaml` file is generated in `projects/${YOUR_PROJECT}/export` path. But some custom environment variables are not configured for your environment. So we need to configure them.
`global.yaml` and `user-secret` files are standard yaml files to configure custom variables for your environment.
`global.yaml` file is in human-readable form but `user-secret` is in base64 encoded form.
You can keep all your environment variables in `global.yaml` but if you don't want to keep some secrets visible in `global.yaml`, you should keep them in `user-secret`.
:::caution
`user-secret` is a complementary file for `global.yaml`. Although it's usage is optional, it's used actively when it has defined values.
So, keep in mind that values kept in `user-secret` always overrides same values in `global.yaml`.
If you want a secret used from `global.yaml`, then it should not be in `user-secret`. You should remove its definition from `user-secret`.
:::
#### Configuring `global.yaml`
`global.yaml` has some initial and example values preset when it's generated.
```yaml
---
environment: Production
enableErrorHandling: "true"
external:
scheme: http
mainDomain: ".example.com"
smtpServer: # Optional
user:
from:
host:
fromDisplayName:
port:
ssl:
auth:
starttls:
keycloak:
initialUsername: admin@example.com
enabledRegistration: true
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: store.example.com
```
:::caution
In later steps, other system subdomains will be concatted to main domain. For this reason, `external.mainDomain` in configuration file must always begin with `.` character as prefix.
You can see a list of these subdomains in [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings).
:::
As an example, we can change some variables like below according to our fictive company setup.
```yaml
---
environment: Production
enableErrorHandling: "true"
external:
scheme: http
mainDomain: ".appcircle.spacetech.com"
smtpServer: # Optional
user: o***y*****@v******.net
from: o***y*****@v******.net
host: smtp.v******.net
fromDisplayName: Space Tech
port: "587"
ssl: "false"
auth: "true"
starttls: "true"
keycloak:
initialUsername: admin@spacetech.com
enabledRegistration: true
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: store.spacetech.com
```
For our example, we configured below values:
- `external.scheme` is configured as `http` for our case. When we set as `https` we also need to configure other SSL options. See related section in online docs for [SSL configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration) details.
- `external.mainDomain` is set as a subdomain of our example company's main domain. See [DNS Settings](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings) for more details.
- `smtpServer` settings are set for e-mail notifications. We choose not to set SMTP password as plain text in here. Recommended methods will be explained in the next section. But if it's acceptable for you, then you can set `smtpServer.password` variable in here.
- `keycloak.initialUsername` will be appcircle's default organization's admin user. Its username is set to `initialUsername`. We choose not to set its password as plain text in here. We will put it to `user-secret` on next steps. But if it's acceptable for you, then you can set `keycloak.initialPassword` variable in here.
- `storeWeb.customDomain.domain` is set with our example company's store domain. It's used for enterprise app store URL.
:::caution
Starting from the version `3.28.2`, SMTP settings can be configured directly from the Appcircle Dashboard. This is the recommended approach for managing SMTP settings. To use this method, you can remove the `smtpServer` part from your `global.yaml` file, and configure SMTP settings on the Dashboard after installation.
See [Email Integration docs](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) for more details.
:::
:::caution
#### Initial Password
`keycloak.initialPassword` value can not be empty since default organization's admin user will login with that password.
Same as in cloud, it must be compatible with Appcircle password policy;
- minimum character **length must be at least 6**
- must contain at least **one lower** case character
- must contain at least **one upper** case character
- must contain at least **one numerical** digit
#### Troubleshooting
If `keycloak.initialPassword` value is not compatible with password policy, you will get below error on service start while [running Appcircle server](/self-hosted-appcircle/install-server/linux-package/installation/docker#6-run-server).
```txt
service "keycloak_migration" didn't completed successfully: exit 1
```
In this case, before updating initial password in `global.yaml`, you need to **stop** partially started docker services with below command. See [reset configuration](/self-hosted-appcircle/install-server/linux-package/installation/docker#reset-configuration) section for more details.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
After updating initial password, to activate changes, you need to do fresh export.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
Then, make sure you initialize the [vault](/self-hosted-appcircle/install-server/linux-package/installation/docker#5-initialize-vault) again.
```bash
./ac-self-hosted.sh -n "spacetech" init
```
Now you can run services again. It should complete without any error.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::
#### Configuring Secrets
As seen in previous section, we left some secrets out of the `global.yaml` to set them in `user-secret` file. So we need to take additional steps to complete configuration. If you set them as plain text in `global.yaml` then you don't need to take `user-secret` steps.
:::caution
As described in the previous section, SMTP settings can now be configured directly from the Appcircle Dashboard. With this method SMTP password will be stored as an encrypted secret which is secure unlike a plain text or `base64` encoding. To use this method:
1. Remove the `smtpServer.password` part from the `secret.yaml` file in the next steps here. Therefore, it will not be included in the `user-secret` file that you will generate, and won't effect the Appcircle server configuration.
2. Configure SMTP settings on the Dashboard after installation. See [Email Integration docs](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) for more details.
:::
First create your `secret.yaml` configuration as plain text like below.
```yaml
smtpServer:
password: 4NZ**********
keycloak:
initialPassword: ZP6***********
```
For example, let's assume our secret yaml file is located in `projects/spacetech/secret.yaml` path.
In order to convert it to base64 encoded `user-secret` run following command.
```bash
base64 projects/spacetech/secret.yaml > projects/spacetech/user-secret
```
You can check `user-secret` file content in human-readable form with below command if required.
```bash
base64 -d projects/spacetech/user-secret
```
We have `user-secret` filled in successfully and don't need `projects/spacetech/secret.yaml` anymore. So we should delete it.
```bash
rm projects/spacetech/secret.yaml
```
:::caution
On your first export, which makes `global.yaml` template for you, also creates an empty template file for `user-secret` as seen below:
```bash
base64 -d projects/spacetech/user-secret
```
```yaml
smtpServer:
password:
keycloak:
initialPassword:
```
If you prefer defining above variables in `global.yaml`, then they should not be in `user-secret`.
If you defined all of them in `global.yaml`,simply remove `user-secret` before next steps.
:::
Note that after changes made to yaml files, you must execute the script again for the changes to take effect as shown below.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
### 4. DNS Settings
Appcircle server has some subdomains for different services. So, you need to add them to DNS in your network before running server.
- api
- auth
- dist
- hook
- my
- resource
- store
- monitor
- redis
- (optional) Enterprise App Store's Custom Domain
:::info
If your configuration (`global.yaml`) has setting `storeWeb.customDomain.enabled:true`, it means that you will use a custom domain for Enterprise App Store. So, its value (`storeWeb.customDomain.domain`) must be configured on DNS along with other system subdomains.
:::
Below is an example DNS configuration that is compatible with our sample scenario.
If you have a dedicated DNS, adding subdomains will be enough to run self-hosted Appcircle server in an easy and quick way.
You can also make DNS settings later, when you complete all configuration and testing.
Until you're satisfied with your setup, you can use `/etc/hosts` file for both self-hosted Appcircle server and connected clients. You can run whole system, test all functionality and your configuration with using the `/etc/hosts` file.
Following section will give you the details for this use case.
#### Using `hosts` file for DNS Settings
The hosts file contains the Internet Protocol (IP) host names and addresses for the local host and other hosts in the network. This file is used to resolve a name into an address (that is, to translate a host name into its IP).
So, you can use hosts file like DNS by adding all required subdomains with their mapped IP address.
:::info
Hosts file is located at:
- `/etc/hosts` on Linux and MacOS
- `C:\Windows\System32\drivers\etc\hosts` on Windows
:::
Entries in the hosts file have the following format:
```txt
Address HostName
```
On self-hosted Appcircle server, you should add below entries to the `/etc/hosts` file.
```txt
0.0.0.0 api.appcircle.spacetech.com
0.0.0.0 auth.appcircle.spacetech.com
0.0.0.0 dist.appcircle.spacetech.com
0.0.0.0 hook.appcircle.spacetech.com
0.0.0.0 my.appcircle.spacetech.com
0.0.0.0 resource.appcircle.spacetech.com
0.0.0.0 store.appcircle.spacetech.com
0.0.0.0 monitor.appcircle.spacetech.com
0.0.0.0 redis.appcircle.spacetech.com
0.0.0.0 store.spacetech.com
```
For clients that will connect to self-hosted Appcircle server, either self-hosted runners or end-users using their browsers for web UI, should add external IP of the server to their `/etc/hosts` files. External IP is the address of self-hosted Appcircle server that other hosts in the network can reach to server using that address.
You can get external IP of self-hosted Appcircle server with below command.
```bash
hostname -I | awk '{print $1}'
```
Let's assume we got value `35.241.181.2` as an example.
Other clients that connect to the server should add below entries to their `/etc/hosts` files.
```txt
35.241.181.2 api.appcircle.spacetech.com
35.241.181.2 auth.appcircle.spacetech.com
35.241.181.2 dist.appcircle.spacetech.com
35.241.181.2 hook.appcircle.spacetech.com
35.241.181.2 my.appcircle.spacetech.com
35.241.181.2 resource.appcircle.spacetech.com
35.241.181.2 store.appcircle.spacetech.com
35.241.181.2 monitor.appcircle.spacetech.com
35.241.181.2 redis.appcircle.spacetech.com
35.241.181.2 store.spacetech.com
```
With this network setup, you can run and test both self-hosted Appcircle server and connected self-hosted runners with all functionality.
### 5. Initialize Vault
Initialize [vault](/self-hosted-appcircle/install-server/linux-package/installation/docker#vault) before starting the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" init
```
:::caution
You should initialize the server only once while installing it or after data cleanup is done with the `reset` command.
It must not be used on upgrades in any way.
:::
### 6. Run Server
Appcircle server's modules are run on Docker Engine as a container application on your system. All containers are run using a `compose.yaml` file which is generated after `ac-self-hosted.sh` is executed successfully explained in above steps.
`projects/${YOUR_PROJECT}/export` path will have all exported environment for self-hosted Appcircle services along with `compose.yaml`.
```text
projects/
└── spacetech
├── export
│ ├── agent-cache
│ ├── api-gateway
│ ├── build
│ ├── common.env
│ ├── compose.yaml
│ ├── distribution
│ ├── keycloak
│ ├── keycloak-migration
│ ├── license
│ ├── minio
│ ├── mongo
│ ├── nginx
│ ├── notification
│ ├── postgres
│ ├── report
│ ├── rijndael
│ ├── signing-identity
│ ├── store
│ ├── store-submit
│ ├── tester-web
│ ├── vault
│ ├── webApp
│ └── webhook
├── generated-secret.yaml
├── global.yaml
└── user-secret
```
Run Appcircle server services.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::info
#### Artifact Registry Credentials: Cred.json
Before we run self-hosted appcircle, we need to set artifact registry credentials. Using credentials JSON key file, we will pull docker images for Appcircle server services.
Although it's not required immediately at configuration steps, it's required while we're starting Appcircle server. Otherwise it can not pull docker images from our artifact registry.
For this reason, it's a part of the configuration. `ac-self-hosted.sh` bash script configures docker engine with appropriate credentials. If you don't have the key file, bash script gives error with a detailed message about the requirement.
When you buy an enterprise license for self-hosted appcircle, you will get a credentials JSON key file which enables you to login our artifact registry. For example, assume our fictive company is Space Tech.
You've got `space-tech-cred.json` key file and downloaded it into `~/Downloads` folder.
First you need to copy that key file into self-hosted Appcircle root directory.
```bash
cp ~/Downloads/space-tech-cred.json cred.json
```
After that you can execute below command.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
You should see
> "Docker login cred not found. Trying to login now..."
in command output and then
> "Login Succeeded"
which shows us successful artifact registry login.
If you get any error for some reason at this step, you can remove `~/.docker/config` file to reset and execute same command again to retake same steps.
:::
:::info
At first run, it will pull once all docker images needed from artifact registry. Also there are some migration steps taken for once which prepares system for other operations.
So it may need up to ~20 min to system be up according to your internet connection speed and CPU power. But recurrent boots will take a couple of minutes and will have shorter durations.
:::
Now you can check system health and gain an overview of the status.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
It will give a quick health summary. You should see below message on success.
```
All services are running successfully. Project name is spacetech
```
If you want to get details about docker services, you may run the following commands.
```bash
cd projects/spacetech/export
docker compose ps
```
If everything is okay, then you should see service statuses as "running", "running (healthy)" or "exited (0)".
:::caution
#### Vault
All secret data, including the API keys, signing identities, environment variables, and secrets are stored in an HashiCorp Vault. OAuth tokens and SSH keys, used in build pipeline, are also stored securely in HashiCorp Vault.
Vault is a tool for securely accessing secrets. It's an important and required service for whole self-hosted Appcircle server. If it's status is `unhealthy`, secrets will be inaccessible and most CI/CD functions won't work properly.
For this reason, **before starting to use self-hosted Appcircle server** within your organization, make sure you check **vault service** status in container list above. Its **status must be `healthy`**.
While you're working on configuration back and forth, it's status may become `unhealthy` in some way.
In this case, stop all services with data cleanup.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
Then make a new export, initialize the vault and start services. Refer to [reset configuration](/self-hosted-appcircle/install-server/linux-package/installation/docker#reset-configuration) section for more details.
:::
:::info
Self-hosted Appcircle server uses some ports for communication.
Below ports must be unused on system and dedicated to only Appcircle server usage.
- `80`
- `443`
If the self-hosted server is configured as HTTP, the below port must also be unused. (_For HTTPS configuration, that's not required._)
- `6379`
You can get a list of up-to-date ports used by docker with below command.
```bash
sudo netstat -tulpn | grep LISTEN | grep docker
```
:::
#### Using 3rd Party or Self-hosted Artifact Registry
If your organization uses another registry (harbor, nexus, etc.), in order to use the Appcircle registry, you can head to the [External Image Registries](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry) document for detailed usage and configuration examples.
### :tada: Ready
Open your browser and go to URL `http://my.appcircle.spacetech.com`. You should see login page.
Login to self-hosted Appcircle with `initialUsername` and `initialPassword` that we have configured in above steps. For our example, user name is `admin@spacetech.com`.
You can also login to enterprise app store with configured custom URL `store.spacetech.com`.
:::info
Although you can run export multiple times with different project names, you can run only one of them as an Appcircle server instance.
With default installation steps, reserved ports are the same for all exports. For this reason, when you run `docker compose up -d` first instance will reserve open ports to itself. And later `docker compose up -d` commands for other projects will get errors like "port is already allocated".
:::
:::info
For now, self-hosted Appcircle server is a single node solution. You can not scale it by adding more nodes with other bare-metals or VMs.
Because it has a self-contained architecture with all its data side-by-side its docker services. Every node can only use its internal volumes and data on host.
:::
## Reset Configuration
If you have made a mistake at installation steps, especially at configuration, you can reconfigure your server after installation.
All configuration updates requires Appcircle server restart. So resetting configuration should start with stopping Appcircle server.
Stop Appcircle server services.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
On complete, you can check list of running services with command below.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
Its response should be something like below.
`WARNING:Services are not started. Project name is spacetech`
:::caution
Some configuration changes may require data cleanup with extra steps which means data loss if you use Appcircle server for some time.
For example, you can add other git providers with above steps any time you want without any data loss. But changing `external.scheme` from "http" to "https" or changing `smtpServer.*` settings requires docker volume prune which results with data cleanup.
So, we suggest you to be sure with your configuration before using it in production environment. You can try different settings back and forth until you're satisfied.
:::
:::tip
#### SMTP Configuration
Starting from version `3.28.2`, SMTP settings can be configured and updated directly from the Appcircle Dashboard without a server reset or data cleanup.
This is the recommended method if you do not have any specific reason to do it in the `global.yaml`.
See [Email Integration docs](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) for more details.
:::
To begin reconfiguration with data cleanup (for settings like `external.scheme`), use below command while stopping Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
It will remove all unused local volumes which is useful for a clean start.
Then go back to your configuration and change settings as done previously at [configure](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) step.
When you're ready for a new export, in root directory execute below command again as done previously.
:::info
For our example scenario, root directory is `appcircle-server` as seen [here](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download). And project name is "spacetech".
:::
```bash
./ac-self-hosted.sh -n "spacetech" export
```
Now you are ready to restart self-hosted appcircle.
Before that, make sure you initialize the [vault](/self-hosted-appcircle/install-server/linux-package/installation/docker#5-initialize-vault) again.
```bash
./ac-self-hosted.sh -n "spacetech" init
```
Run Appcircle server services.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
## Connecting Runners
When you complete installation successfully by following above steps, you're ready for your first build. :tada:
But in order to run build pipelines, you need to install and connect self-hosted runners. We have dedicated section for installation and configuration of self-hosted runners.
Follow and apply related guidelines in [here](/self-hosted-appcircle/self-hosted-runner/installation).
Self-hosted runner section in docs, has all details about runners and their configuration.
:::::caution
By default, self-hosted runner package has pre-configured `ASPNETCORE_REDIS_STREAM_ENDPOINT` and `ASPNETCORE_BASE_API_URL` for Appcircle-hosted cloud.
- `webeventredis.appcircle.io:6379,ssl=true`
- `https://api.appcircle.io/build/v1`
:point_up: You need to change these values with your self-hosted Appcircle server's Redis and API URL.
Assuming our sample scenario explained above, these values should be:
- `redis.appcircle.spacetech.com:6379,ssl=false`
- `http://api.appcircle.spacetech.com/build/v1`
for our example configuration.
:::info
If your Appcircle server is running with `HTTPS`, then Redis and API URL should be like this:
- `redis.appcircle.spacetech.com:443,ssl=true`
- `https://api.appcircle.spacetech.com/build/v1`
:::
:reminder_ribbon: After [download](/self-hosted-appcircle/self-hosted-runner/installation#1-download), open `appsettings.json` with a text editor and change the `ASPNETCORE_REDIS_STREAM_ENDPOINT` and the `ASPNETCORE_BASE_API_URL` values according to your configuration.
Please note that, you should do this before [register](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
:::::
Considering system performance, it will be good to install self-hosted runners to other machines. Self-hosted Appcircle server should run on a dedicated machine itself.
You can install any number of runners regarding to your needs and connect them to self-hosted Appcircle server.
---
## Installation (Docker/Podman)
# Installation
Docker and Podman are containerization platforms that enable running applications in isolated environments. They provide a lightweight, portable, and consistent runtime for deploying applications across different environments. This guide outlines the installation process for Docker and Podman, along with considerations for cloud-based deployments.
Current headlines are listed below:
- [Pre-Installation Checklist](/self-hosted-appcircle/install-server/linux-package/installation/pre-installation-checklist)
- [Docker](/self-hosted-appcircle/install-server/linux-package/installation/docker)
- [Podman](/self-hosted-appcircle/install-server/linux-package/installation/podman)
- [Cloud Provider Setup](/self-hosted-appcircle/install-server/linux-package/installation/cloud-providers)
In order to see the details, check the submenu of this documentation page.
---
## Podman
# Overview
Following sections give you detailed information about system requirements, installation and configuration steps. After following directives successfully, you will get a running Appcircle instance on your infrastructure.
## Prerequisites
Below are the hardware and OS requirements for self-hosted Appcircle installation.
### Supported Linux Distributions
Self-hosted Appcircle server utilizing Podman, can only be installed on Linux operating system.
- CentOS Stream 8 or later
- RHEL 8 or later
:::info
We are working on Ubuntu and Debian support. It will be available soon.
:::
### Hardware Requirements
Minimum hardware requirements for self-hosted Appcircle can be:
- 100GB or more free disk space
- 4 or more cores CPU
- 8 or more gigabytes (GB) RAM
:point_up: These hardware specs are minimum requirements for basic execution and it can be used only for quick evaluation or development purposes.
:::caution
CPU architecture must be AMD or Intel 64-bit arch (`x86_64`).
:::
:::info
If you have enough RAM and a recent CPU, performance of Appcircle server can be limited by hard drive seek times. So, having a fast drive like a solid state drive (SSD) improves runtime.
:::
Higher numbers will be better especially for increased number of users.
For an enterprise installation, **minimum** hardware requirements are
- 500GB SSD
- 8 CPU
- 16GB RAM
For production environments, **recommended** hardware requirements are
- 1TB SSD
- 32 CPU
- 64GB RAM
:::caution
#### Swap
:::
### Podman Requirements
The Appcircle server supports Podman as the container runtime. The minimum required version of Podman is 4.3.0 or higher.
:::caution Podman Compose Version Compatibility
Based on the Appcircle server version, you should use a compatible version of Podman Compose as detailed below.
#### `3.29.6` or later
Podman Compose version must be `1.5.0` or later since older versions have a known issue affecting [`CMD` health checks](https://github.com/containers/podman-compose/releases/tag/v1.5.0) that breaks container runtime.
#### `3.29.4` or older
Podman Compose version `1.3.0` contains a known issue affecting relative path handling. To avoid this bug, use version `1.2.0` or earlier, or version `1.4.0` or later.
:::
:::info RHEL 8 Python Version Requirement
Podman Compose version `1.4.0` and later require Python `3.7` or higher.
RHEL 8 systems may have an older Python version by default. Before installing or upgrading Podman Compose to `1.4.0` or newer, ensure Python `3.7+` is installed and set as the default `python3` interpreter.
:::
#### Enabling the Linger Option
You can run the Appcircle server in the background now.
#### Overcoming Privileged Port Limitations
### Firewalld Requirements
## Installation
### 1. Download
You need to have the following tools installed on your system:
- curl
- unzip
To download the licensed Appcircle Server package for your organization, you must copy the `cred.json` file to the directory where you want to install the package.
:::info
Without the `cred.json` file, you will not be able to access the licensed Appcircle Server package.
If you have not yet obtained the `cred.json` file, please contact us for assistance.
:::
Download the latest self-hosted Appcircle package.
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-server.sh | bash
```
Extract self-hosted Appcircle package into folder.
```bash
unzip -o -u appcircle-server-linux-x64-${version}-${build}.zip -d appcircle-server
```
:::info
You should use the downloaded `zip` archive while extracting so that the actual `${version}` and `${build}` will come from there. You can find the relevant data in the previously executed download command output.
:::
Change directory into extracted `appcircle-server` folder for following steps.
```bash
cd appcircle-server
```
### 2. Packages
You need to have the following tool(s) installed on your system.
- podman
The good news is that the ac-self-hosted.sh script installs all the necessary tools if they are not already installed on your system.
:::caution
You need to have root access on your system for this step. Being able to run `sudo` is sufficient for the following step. (sudoer)
:::
To do this, execute the script using the `-i` argument as shown below.
```bash
sudo ./ac-self-hosted.sh -i
```
You can also use the long option `--install-package` for the same purpose.
Make sure the script was executed without any error. Script will print installed and required packages when executed. Some packages may need manual installation on some linux distributions. Check command output for warnings and follow directives given in the output.
:::info
Podman is one of our major dependencies. So, its version is also important for Appcircle server runtime.
Older podman versions may be incompatible for our operations. Podman versions above `4.3.0` should be preferred to eliminate any compatibility issues.
:::
#### Podman Network Stack
#### Change the Podman Data Location
In certain scenarios, you may encounter situations where the available free space on the root directory (`/`) is limited. However, you might have ample free space in a different directory, such as `$HOME` or `/opt`.
In such cases, you can modify the Podman data location path to utilize the available space in the desired directory.
These are the steps to change podman data location path:
:::caution
If you have selinux enabled, you should disable it temporarily before changing podman data location.
```bash
sudo setenforce 0
```
:::
:::caution
Podman data path may vary according to users.
- If you will use podman with the root user, the data path is `/var/lib/containers`.
- If you will use podman with regular user, the data path is `$HOME/.local/share/containers`.
Please be sure about your podman data path.
The commands below are shown for the root user. Please change it according to your data path.
:::
- Stop the podman service.
```bash
sudo systemctl stop podman
```
- Move the existing Podman data directory to the new location.
```bash
sudo mv /var/lib/containers $HOME/podman
```
- Create a softlink from default location to the new location.
```bash
sudo ln -s $HOME/podman /var/lib/containers
```
- Restart the podman service.
```bash
sudo systemctl start podman
```
:::caution
If you disabled selinux and want to enable it again, you can run the following command.
```bash
sudo setenforce 1
```
:::
### 3. Configure
First we need to find a name to our self-hosted Appcircle installation. It will be the unique project name.
```bash
./ac-self-hosted.sh -n "${YOUR_PROJECT}" export
```
Let's assume we have company named as Space Tech. Then our project name can be "spacetech". For following steps, we will give examples based on this fictive company for better understanding.
Then our command to execute will be:
```bash
./ac-self-hosted.sh -n "spacetech" export
```
On `ac-self-hosted.sh` execution complete, the folder contains `global.yaml`, `user-secret` files and `export` folder.
```txt
projects
└── spacetech
├── export
├── generated-secret.yaml
├── global.yaml
└── user-secret
```
At this point, the `compose.yaml` file is generated in `projects/${YOUR_PROJECT}/export` path. But some custom environment variables are not configured for your environment. So we need to configure them.
`global.yaml` and `user-secret` files are standard yaml files to configure custom variables for your environment.
`global.yaml` file is in human-readable form but `user-secret` is in base64 encoded form.
You can keep all your environment variables in `global.yaml` but if you don't want to keep some secrets visible in `global.yaml`, you should keep them in `user-secret`.
:::caution
`user-secret` is a complementary file for `global.yaml`. Although it's usage is optional, it's used actively when it has defined values.
So, keep in mind that values kept in `user-secret` always overrides same values in `global.yaml`.
If you want a secret used from `global.yaml`, then it should not be in `user-secret`. You should remove its definition from `user-secret`.
:::
#### Configuring `global.yaml`
`global.yaml` has some initial and example values preset when it's generated.
```yaml
---
environment: Production
enableErrorHandling: "true"
external:
scheme: http
mainDomain: ".example.com"
smtpServer: # Optional
user:
from:
host:
fromDisplayName:
port:
ssl:
auth:
starttls:
keycloak:
initialUsername: admin@example.com
enabledRegistration: true
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: store.example.com
```
:::caution
In later steps, other system subdomains will be concatted to main domain. For this reason, `external.mainDomain` in configuration file must always begin with `.` character as prefix.
You can see a list of these subdomains in [here](/self-hosted-appcircle/install-server/linux-package/installation/podman#4-dns-settings).
:::
As an example, we can change some variables like below according to our fictive company setup.
```yaml
---
environment: Production
enableErrorHandling: "true"
external:
scheme: http
mainDomain: ".appcircle.spacetech.com"
smtpServer: # Optional
user: o***y*****@v******.net
from: o***y*****@v******.net
host: smtp.v******.net
fromDisplayName: Space Tech
port: "587"
ssl: "false"
auth: "true"
starttls: "true"
keycloak:
initialUsername: admin@spacetech.com
enabledRegistration: true
storeWeb:
external:
subdomain: store
customDomain:
enabled: true
domain: store.spacetech.com
```
For our example, we configured below values:
- `external.scheme` is configured as `http` for our case. When we set as `https` we also need to configure other SSL options. See related section in online docs for [SSL configuration](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/ssl-configuration) details.
- `external.mainDomain` is set as a subdomain of our example company's main domain. See [DNS Settings](/self-hosted-appcircle/install-server/linux-package/installation/podman#4-dns-settings) for more details.
- `smtpServer` settings are set for e-mail notifications. We choose not to set SMTP password as plain text in here. Recommended methods will be explained in the next section. But if it's acceptable for you, then you can set `smtpServer.password` variable in here.
- `keycloak.initialUsername` will be appcircle's default organization's admin user. Its username is set to `initialUsername`. We choose not to set its password as plain text in here. We will put it to `user-secret` on next steps. But if it's acceptable for you, then you can set `keycloak.initialPassword` variable in here.
- `storeWeb.customDomain.domain` is set with our example company's store domain. It's used for enterprise app store URL.
:::caution
Starting from the version `3.28.2`, SMTP settings can be configured directly from the Appcircle Dashboard. This is the recommended approach for managing SMTP settings. To use this method, you can remove the `smtpServer` part from your `global.yaml` file, and configure SMTP settings on the Dashboard after installation.
See [Email Integration docs](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) for more details.
:::
:::caution
#### Initial Password
`keycloak.initialPassword` value can not be empty since default organization's admin user will login with that password.
Same as in cloud, it must be compatible with Appcircle password policy;
- minimum character **length must be at least 6**
- must contain at least **one lower** case character
- must contain at least **one upper** case character
- must contain at least **one numerical** digit
#### Troubleshooting
If `keycloak.initialPassword` value is not compatible with password policy, you will get below error on service start while [running Appcircle server](/self-hosted-appcircle/install-server/linux-package/installation/podman#6-run-server).
```txt
service "keycloak_migration" didn't completed successfully: exit 1
```
In this case, before updating initial password in `global.yaml`, you need to **stop** partially started podman services with below command. See [reset configuration](/self-hosted-appcircle/install-server/linux-package/installation/podman#reset-configuration) section for more details.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
After updating initial password, to activate changes, you need to do fresh export.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
Then, make sure you initialize the [vault](/self-hosted-appcircle/install-server/linux-package/installation/podman#5-initialize-vault) again.
```bash
./ac-self-hosted.sh -n "spacetech" init
```
Now you can run services again. It should complete without any error.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::
#### Configuring Secrets
As seen in previous section, we left some secrets out of the `global.yaml` to set them in `user-secret` file. So we need to take additional steps to complete configuration. If you set them as plain text in `global.yaml` then you don't need to take `user-secret` steps.
:::caution
As described in the previous section, SMTP settings can now be configured directly from the Appcircle Dashboard. With this method SMTP password will be stored as an encrypted secret which is secure unlike a plain text or `base64` encoding. To use this method:
1. Remove the `smtpServer.password` part from the `secret.yaml` file in the next steps here. Therefore, it will not be included in the `user-secret` file that you will generate, and won't effect the Appcircle server configuration.
2. Configure SMTP settings on the Dashboard after installation. See [Email Integration docs](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) for more details.
:::
First create your `secret.yaml` configuration as plain text like below.
```yaml
smtpServer:
password: 4NZ**********
keycloak:
initialPassword: ZP6***********
```
For example, let's assume our secret yaml file is located in `projects/spacetech/secret.yaml` path.
In order to convert it to base64 encoded `user-secret` run following command.
```bash
base64 projects/spacetech/secret.yaml > projects/spacetech/user-secret
```
You can check `user-secret` file content in human-readable form with below command if required.
```bash
base64 -d projects/spacetech/user-secret
```
We have `user-secret` filled in successfully and don't need `projects/spacetech/secret.yaml` anymore. So we should delete it.
```bash
rm projects/spacetech/secret.yaml
```
:::caution
On your first export, which makes `global.yaml` template for you, also creates an empty template file for `user-secret` as seen below:
```bash
base64 -d projects/spacetech/user-secret
```
```yaml
smtpServer:
password:
keycloak:
initialPassword:
```
If you prefer defining above variables in `global.yaml`, then they should not be in `user-secret`.
If you defined all of them in `global.yaml`,simply remove `user-secret` before next steps.
:::
Note that after changes made to yaml files, you must execute the script again for the changes to take effect as shown below.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
### 4. DNS Settings
Appcircle server has some subdomains for different services. So, you need to add them to DNS in your network before running server.
- api
- auth
- dist
- hook
- my
- resource
- store
- monitor
- redis
- (optional) Enterprise App Store's Custom Domain
:::info
If your configuration (`global.yaml`) has setting `storeWeb.customDomain.enabled:true`, it means that you will use a custom domain for Enterprise App Store. So, its value (`storeWeb.customDomain.domain`) must be configured on DNS along with other system subdomains.
:::
Below is an example DNS configuration that is compatible with our sample scenario.
If you have a dedicated DNS, adding subdomains will be enough to run self-hosted Appcircle server in an easy and quick way.
You can also make DNS settings later, when you complete all configuration and testing.
Until you're satisfied with your setup, you can use `/etc/hosts` file for both self-hosted Appcircle server and connected clients. You can run whole system, test all functionality and your configuration with using the `/etc/hosts` file.
Following section will give you the details for this use case.
#### Using `hosts` file for DNS Settings
The hosts file contains the Internet Protocol (IP) host names and addresses for the local host and other hosts in the network. This file is used to resolve a name into an address (that is, to translate a host name into its IP).
So, you can use hosts file like DNS by adding all required subdomains with their mapped IP address.
:::info
Hosts file is located at:
- `/etc/hosts` on Linux and MacOS
- `C:\Windows\System32\drivers\etc\hosts` on Windows
:::
Entries in the hosts file have the following format:
```txt
Address HostName
```
On self-hosted Appcircle server, you should add below entries to the `/etc/hosts` file.
```txt
0.0.0.0 api.appcircle.spacetech.com
0.0.0.0 auth.appcircle.spacetech.com
0.0.0.0 dist.appcircle.spacetech.com
0.0.0.0 hook.appcircle.spacetech.com
0.0.0.0 my.appcircle.spacetech.com
0.0.0.0 resource.appcircle.spacetech.com
0.0.0.0 store.appcircle.spacetech.com
0.0.0.0 monitor.appcircle.spacetech.com
0.0.0.0 redis.appcircle.spacetech.com
0.0.0.0 store.spacetech.com
```
For clients that will connect to self-hosted Appcircle server, either self-hosted runners or end-users using their browsers for web UI, should add external IP of the server to their `/etc/hosts` files. External IP is the address of self-hosted Appcircle server that other hosts in the network can reach to server using that address.
You can get external IP of self-hosted Appcircle server with below command.
```bash
hostname -I | awk '{print $1}'
```
Let's assume we got value `35.241.181.2` as an example.
Other clients that connect to the server should add below entries to their `/etc/hosts` files.
```txt
35.241.181.2 api.appcircle.spacetech.com
35.241.181.2 auth.appcircle.spacetech.com
35.241.181.2 dist.appcircle.spacetech.com
35.241.181.2 hook.appcircle.spacetech.com
35.241.181.2 my.appcircle.spacetech.com
35.241.181.2 resource.appcircle.spacetech.com
35.241.181.2 store.appcircle.spacetech.com
35.241.181.2 monitor.appcircle.spacetech.com
35.241.181.2 redis.appcircle.spacetech.com
35.241.181.2 store.spacetech.com
```
With this network setup, you can run and test both self-hosted Appcircle server and connected self-hosted runners with all functionality.
### 5. Initialize Vault
Initialize [vault](/self-hosted-appcircle/install-server/linux-package/installation/podman#vault) before starting the Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" init
```
:::caution
You should initialize the server only once while installing it or after data cleanup is done with the `reset` command.
It must not be used on upgrades in any way.
:::
### 6. Run Server
Appcircle server's modules are run on Podman as a container application on your system. All containers are run using a `compose.yaml` file which is generated after `ac-self-hosted.sh` is executed successfully explained in above steps.
`projects/${YOUR_PROJECT}/export` path will have all exported environment for self-hosted Appcircle services along with `compose.yaml`.
```text
projects/
└── spacetech
├── export
│ ├── agent-cache
│ ├── api-gateway
│ ├── build
│ ├── common.env
│ ├── compose.yaml
│ ├── distribution
│ ├── keycloak
│ ├── keycloak-migration
│ ├── license
│ ├── minio
│ ├── mongo
│ ├── nginx
│ ├── notification
│ ├── postgres
│ ├── report
│ ├── rijndael
│ ├── signing-identity
│ ├── store
│ ├── store-submit
│ ├── tester-web
│ ├── vault
│ ├── webApp
│ └── webhook
├── generated-secret.yaml
├── global.yaml
└── user-secret
```
Run Appcircle server services.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
:::info
#### Artifact Registry Credentials: Cred.json
Before we run self-hosted appcircle, we need to set artifact registry credentials. Using credentials JSON key file, we will pull container images for Appcircle server services.
Although it's not required immediately at configuration steps, it's required while we're starting Appcircle server. Otherwise it can not pull container images from our artifact registry.
For this reason, it's a part of the configuration. `ac-self-hosted.sh` bash script configures podman with appropriate credentials. If you don't have the key file, bash script gives error with a detailed message about the requirement.
When you buy an enterprise license for self-hosted appcircle, you will get a credentials JSON key file which enables you to login our artifact registry. For example, assume our fictive company is Space Tech.
You've got `space-tech-cred.json` key file and downloaded it into `~/Downloads` folder.
First you need to copy that key file into self-hosted Appcircle root directory.
```bash
cp ~/Downloads/space-tech-cred.json cred.json
```
After that you can execute below command.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
You should see
> "Podman login cred not found. Trying to login now..."
in command output and then
> "Login Succeeded"
which shows us successful artifact registry login.
If you get any error for some reason at this step, you can remove `${XDG_RUNTIME_DIR}/containers/auth.json` file to reset and execute same command again to retake same steps.
:::
:::info
At first run, it will pull once all container images needed from artifact registry. Also there are some migration steps taken for once which prepares system for other operations.
So it may need up to ~20 min to system be up according to your internet connection speed and CPU power. But recurrent boots will take a couple of minutes and will have shorter durations.
:::
Now you can check system health and gain an overview of the status.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
It will give a quick health summary. You should see below message on success.
```
All services are running successfully. Project name is spacetech
```
If you want to get details about podman services, you may run the following commands.
```bash
cd projects/spacetech/export
podman-compose ps
```
If everything is okay, then you should see service statuses as "up", "up (healthy)" or "exited (0)".
:::caution
#### Vault
All secret data, including the API keys, signing identities, environment variables, and secrets are stored in an HashiCorp Vault. OAuth tokens and SSH keys, used in build pipeline, are also stored securely in HashiCorp Vault.
Vault is a tool for securely accessing secrets. It's an important and required service for whole self-hosted Appcircle server. If it's status is `unhealthy`, secrets will be inaccessible and most CI/CD functions won't work properly.
For this reason, **before starting to use self-hosted Appcircle server** within your organization, make sure you check **vault service** status in container list above. Its **status must be `healthy`**.
While you're working on configuration back and forth, it's status may become `unhealthy` in some way.
In this case, stop all services with data cleanup.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
Then make a new export, initialize the vault and start services. Refer to [reset configuration](/self-hosted-appcircle/install-server/linux-package/installation/podman#reset-configuration) section for more details.
:::
:::info
Self-hosted Appcircle server uses some ports for communication.
Below ports must be unused on system and dedicated to only Appcircle server usage.
- `80`
- `443`
- `8080`
- `8443`
If the self-hosted server is configured as HTTP, the below port must also be unused. (_For HTTPS configuration, that's not required._)
- `6379`
Appcircle server will listen on `8080` and `8443` ports by default for HTTP and HTTPS connections.
You can get a list of up-to-date ports used by podman with below command.
```bash
sudo netstat -tulpn | grep LISTEN | grep -E 'rootlessport|socat'
```
- Filter "rootlessport" to see ports used by podman.
- Filter "socat" to see ports used by port forwarder tool socket.
:::
:::caution
##### Rebooting the Server
By default, the Appcircle server containers do not start automatically upon rebooting the host when podman is used as the container engine.
To enable automatic startup of the Appcircle server containers, additional steps are required.
For detailed instructions on configuring the automatic startup of the server containers upon server reboot, please refer to the [Restarting Host](../configure-server/restarting-host) page.
:::
#### Using 3rd Party or Self-hosted Artifact Registry
If your organization uses another registry (harbor, nexus, etc.), in order to use the Appcircle registry, you can head to the [External Image Registries](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry) document for detailed usage and configuration examples.
### :tada: Ready
Open your browser and go to URL `http://my.appcircle.spacetech.com`. You should see login page.
Login to self-hosted Appcircle with `initialUsername` and `initialPassword` that we have configured in above steps. For our example, user name is `admin@spacetech.com`.
You can also login to enterprise app store with configured custom URL `store.spacetech.com`.
:::info
Although you can run export multiple times with different project names, you can run only one of them as an Appcircle server instance.
With default installation steps, reserved ports are the same for all exports. For this reason, when you run `./ac-self-hosted.sh -n spacetech up` first instance will reserve open ports to itself. And later `./ac-self-hosted.sh -n spacetech up` commands for other projects will get errors like "port is already allocated".
:::
:::info
For now, self-hosted Appcircle server is a single node solution. You can not scale it by adding more nodes with other bare-metals or VMs.
Because it has a self-contained architecture with all its data side-by-side its podman services. Every node can only use its internal volumes and data on host.
:::
## Reset Configuration
If you have made a mistake at installation steps, especially at configuration, you can reconfigure your server after installation.
All configuration updates requires Appcircle server restart. So resetting configuration should start with stopping Appcircle server.
Stop Appcircle server services.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
On complete, you can check list of running services with command below.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
Its response should be something like below.
`WARNING:Services are not started. Project name is spacetech`
:::caution
Some configuration changes may require data cleanup with extra steps which means data loss if you use Appcircle server for some time.
For example, you can add other git providers with above steps any time you want without any data loss. But changing `external.scheme` from "http" to "https" or changing `smtpServer.*` settings requires podman volume prune which results with data cleanup.
So, we suggest you to be sure with your configuration before using it in production environment. You can try different settings back and forth until you're satisfied.
:::
:::tip
#### SMTP Configuration
Starting from version `3.28.2`, SMTP settings can be configured and updated directly from the Appcircle Dashboard without a server reset or data cleanup.
This is the recommended method if you do not have any specific reason to do it in the `global.yaml`.
See [Email Integration docs](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/integration#configure-via-dashboard-recommended) for more details.
:::
To begin reconfiguration with data cleanup (for settings like `external.scheme`), use below command while stopping Appcircle server.
```bash
./ac-self-hosted.sh -n "spacetech" reset
```
It will remove all unused local volumes which is useful for a clean start.
Then go back to your configuration and change settings as done previously at [configure](/self-hosted-appcircle/install-server/linux-package/installation/podman#3-configure) step.
When you're ready for a new export, in root directory execute below command again as done previously.
:::info
For our example scenario, root directory is `appcircle-server` as seen [here](/self-hosted-appcircle/install-server/linux-package/installation/podman#1-download). And project name is "spacetech".
:::
```bash
./ac-self-hosted.sh -n "spacetech" export
```
Now you are ready to restart self-hosted appcircle.
Before that, make sure you initialize the [vault](/self-hosted-appcircle/install-server/linux-package/installation/podman#5-initialize-vault) again.
```bash
./ac-self-hosted.sh -n "spacetech" init
```
Run Appcircle server services.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
## Connecting Runners
When you complete installation successfully by following above steps, you're ready for your first build. :tada:
But in order to run build pipelines, you need to install and connect self-hosted runners. We have dedicated section for installation and configuration of self-hosted runners.
Follow and apply related guidelines in [here](/self-hosted-appcircle/self-hosted-runner/installation).
Self-hosted runner section in docs, has all details about runners and their configuration.
:::::caution
By default, self-hosted runner package has pre-configured `ASPNETCORE_REDIS_STREAM_ENDPOINT` and `ASPNETCORE_BASE_API_URL` for Appcircle-hosted cloud.
- `webeventredis.appcircle.io:6379,ssl=true`
- `https://api.appcircle.io/build/v1`
:point_up: You need to change these values with your self-hosted Appcircle server's Redis and API URL.
Assuming our sample scenario explained above, these values should be:
- `redis.appcircle.spacetech.com:6379,ssl=false`
- `http://api.appcircle.spacetech.com/build/v1`
for our example configuration.
:::info
If your Appcircle server is configured as `HTTPS`, then the Redis and API URL should be like this:
- `redis.appcircle.spacetech.com:443,ssl=true`
- `https://api.appcircle.spacetech.com/build/v1`
:::
:reminder_ribbon: After [download](/self-hosted-appcircle/self-hosted-runner/installation#1-download), open `appsettings.json` with a text editor and change the `ASPNETCORE_REDIS_STREAM_ENDPOINT` and the `ASPNETCORE_BASE_API_URL` values according to your configuration.
Please note that, you should do this before [register](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
:::::
Considering system performance, it will be good to install self-hosted runners to other machines. Self-hosted Appcircle server should run on a dedicated machine itself.
You can install any number of runners regarding to your needs and connect them to self-hosted Appcircle server.
---
## Pre-Installation Checklist
This page provides a checklist to be followed before installing the self-hosted Appcircle.
Please ensure all the checks are completed for a smooth installation process.
## Server Checklist
### Check the Operating System
- [ ] If you are using RHEL, it should be **RHEL 8 or later**.
```bash
cat /etc/redhat-release
```
- [ ] If you are using Ubuntu, it should be **Ubuntu 20.04 or later**.
```bash
cat /etc/os-release
```
- [ ] If you are using Debian, it should be **Debian 11 or later**.
```bash
cat /etc/os-release
```
- [ ] If you are using CentOS, it should be **CentOS 8 or later**.
```bash
cat /etc/centos-release
```
### Check the CPU Cores
- [ ] Minimum CPU core count should be **8 cores**.
- For enterprise installations and production environments, **16 or 32 CPU cores** are recommended.
```bash
nproc --all
```
### Check the CPU Architecture
- [ ] The CPU architecture must be **x86_64**.
```bash
uname -i
```
If the command above doesn't work, you can try the command below.
```bash
arch
```
### Check the RAM Size
- [ ] Minimum RAM size should be **16 GB**.
- For enterprise installations and production environments, **32 GB or 64 GB of RAM** is recommended.
```bash
free -h
```
### Check the Disk Size
- [ ] Minimum disk size should be **500 GB**.
- For enterprise installations and production environments, **1 TB of disk space** is recommended.
```bash
df -h
```
:::info
Keep in mind that **SSDs** are a better and **recommended** choice for faster disk operations.
:::
### Check the Swap Size
- [ ] The swap size should be minimum half of the RAM size.
```bash
free -h
```
If you don't have any swap space or it's insufficient, you can find the configuration details [here](./docker#swap).
### Check the Swappiness
- [ ] The swappiness configuration should be **10**.
```bash
sudo cat /proc/sys/vm/swappiness
```
If the output is not 10, you can find the configuration details [here](./docker#swappiness).
### Configure the DNS Settings
- [ ] Create a subdomain under your company's primary domain name.
For example, if your company is "Spacetech" with the domain `spacetech.com`, you can create a subdomain like `appcircle.spacetech.com` or `appcircle-test.spacetech.com` to assign to the Appcircle server.
It will be the **main domain** for the self-hosted Appcircle server.
The main domain (`appcircle.spacetech.com`, for instance.) should have seven subdomains which should resolve to the IP address of the Appcircle server.
These subdomains are **api**, **auth**, **dist**, **hook**, **my**, **resource** and **store**.
- [ ] Create these seven domain name entries on your DNS.
- [ ] `api.appcircle.spacetech.com`
- [ ] `auth.appcircle.spacetech.com`
- [ ] `dist.appcircle.spacetech.com`
- [ ] `hook.appcircle.spacetech.com`
- [ ] `my.appcircle.spacetech.com`
- [ ] `resource.appcircle.spacetech.com`
- [ ] `store.appcircle.spacetech.com`
- [ ] `monitor.appcircle.spacetech.com`
- [ ] `redis.appcircle.spacetech.com`
- [ ] All of these domain names should resolve to the same server IP address, which is the Appcircle server.
You can see details in the [DNS Settings](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings) section.
### Obtain an SSL Certificate
- [ ] You should create only one SSL certificate that covers all seven domain names which you have seen in the [Configure DNS](#configure-the-dns-settings) section above.
- [ ] The SSL certificate should be in PEM format.
- [ ] The SSL certificate private key must not have a passphrase.
- [ ] Obtain the root CA certificate of your company.
- [ ] Obtain the intermediate CA certificate of your company if it exists.
### Obtain the SMTP Settings
- [ ] Obtain the IP address or host name of the SMTP server.
- [ ] Obtain the port number of the SMTP server.
- [ ] Determine if the SMTP server is using `SSL`.
- [ ] Determine if the SMTP server is using `STARTTLS`.
- :warning: `SSL` and `STARTTLS` are **not** the same thing.
- [ ] Determine if the SMTP server requires SSL certificate verification.
- ✨ Appcircle server version `3.23.1` or later supports disabling the certificate verification if you have problems with the SMTP server certificate and need a workaround for certificate errors while troubleshooting.
- ⚠️ It's **not recommended to disable** the SSL certificate verification in production environments.
- If the SMTP server requires authentication:
- [ ] Create a user for Appcircle on the SMTP server.
- [ ] Obtain the password of the Appcircle user on the SMTP server.
- [ ] Contact the system admin to get required permissions to send email with the Appcircle user via the SMTP server.
- [ ] Create a firewall rule (or permission) from the Appcircle server to the SMTP server.
### Configure the Git Server
- [ ] Import Appcircle Android and/or iOS sample repositories on your local git server.
- [ ] [Android Sample Repo](https://github.com/appcircleio/appcircle-sample-android)
- [ ] [iOS Sample Repo](https://github.com/appcircleio/appcircle-sample-ios)
- [ ] Create an Appcircle user on the git server (GitLab, Azure DevOps, Bitbucket).
- [ ] Give the required permissions to the Appcircle user to clone and edit the repositories.
- If you are using GitLab, Azure DevOps, Bitbucket:
- [ ] Create an Appcircle user. Give it permissions for the repositories.
- [ ] Create a personal access token that has sufficient permissions.
- For details like token permissions, check the [connect your repository](/build/manage-the-connections/connection-guides) section.
- If you are using any other git server:
- [ ] Create a public-private SSH key pair.
- [ ] Configure your Appcircle git user's public SSH keys and upload the public SSH key you created.
- For details, you can check the [connect via SSH](/build/manage-the-connections/connection-guides/connecting-to-private-repository-via-ssh) section.
- [ ] Create a firewall rule (or permission) between the Appcircle server and the git server in both directions.
### Network Access for Installation
According to the selected Linux distribution and installation method, you need to configure firewall rules (or permissions) for the Appcircle server. All required domains that are used for installation are detailed in the [network access](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access) section.
- [ ] Review the [network access](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access#appcircle-server-install-and-update) section and be sure that the listed domains are reachable from the Appcircle server.
## Runner Checklist
### Network Access for Installation
The Appcircle runner should be able to access the Appcircle server.
- [ ] Create a firewall rule (or permission) from the Appcircle runner to the Appcircle server.
:::info
Port depends on the configured `external.scheme` in the `global.yaml`.
- Port `443` must be allowed if the Appcircle server is configured as HTTPS.
- Ports `80` and `6379` must be allowed if the Appcircle server is configured as HTTP.
:::
The Appcircle runner should be able to access to the git provider
- [ ] Create a firewall rule (or permission) from the Appcircle runner to the git server.
:::info
Port depends on the selected connection method. Default values can be:
- HTTP(s): `80` or `443`
- SSH: `22`
If your git server has a custom port for git servcies, then you should use that port.
:::
- [ ] Review the [network access](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access#appcircle-runner-install-as-ready-to-use-macos-virtual-machine) section and be sure that the listed domains are reachable from the Appcircle runner.
---
## Updates
# Overview
As in cloud, we're releasing regular updates for self-hosted Appcircle server. You should keep your instance up-to-date in order to get latest features, bug fixes and improvements.
When a new version of self-hosted Appcircle is released, you can update with below steps.
:::info
Prerequisites and dependencies are all same as installation steps. So we will keep it short in this page, try to document only update related details, and give references to installation when required.
When you're in trouble with update, it will be useful to review details and warnings written in [installation](/self-hosted-appcircle/install-server/linux-package/installation/docker) docs.
:::
:::info
Below steps does not affect or destroy your data. Update process keeps your data and schema compatible with latest self-hosted Appcircle server by using incremental migrations all handled automatically.
:::
:::info
To determine the current version of either a project or the script itself, use the version command provided with the script. This will display the script version and any docker image hashes associated with the project. If no docker images are found, the command will output script version only.
Note that a project name is required to execute the version command.
For example, to find the version for a project named "spacetech", run the following command:
```bash
./ac-self-hosted.sh -n "spacetech" version
```
:::
:::tip
#### ✨ Auto-upgrading Server
If you want to update the Appcircle server in an automated way, you can check out the [Auto-upgrading Server](/self-hosted-appcircle/install-server/linux-package/configure-server/auto-updating) documents.
You can effortlessly manage all the commands listed below.
Additionally, you can set up recurring cron jobs (daily or weekly) to automatically check if Appcircle's server needs updating.
:::
:::caution
If you are using the Appcircle DMZ structure and upgrading an Appcircle server, it is critical to also update the Appcircle DMZ server. If you don't, Enterprise App Store and Testing Distribution may not function as expected.
For more information about the DMZ structure, you can check the [Appcircle DMZ documentation](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/store-dist-dmz).
:::
### Version History
Below is the version history of the self-hosted Appcircle server. This table helps you track the latest updates and releases since your current version.
[3.29.8]: https://docs.appcircle.io/release-notes#3-29-8
[3.29.6]: https://docs.appcircle.io/release-notes#3-29-6
[3.29.5]: https://docs.appcircle.io/release-notes#3-29-5
[3.29.4]: https://docs.appcircle.io/release-notes#3-29-4
[3.29.3]: https://docs.appcircle.io/release-notes#3-29-3
[3.29.2]: https://docs.appcircle.io/release-notes#3-29-2
[3.29.1]: https://docs.appcircle.io/release-notes#3-29-1
[3.29.0]: https://docs.appcircle.io/release-notes#3-29-0
[3.28.3]: https://docs.appcircle.io/release-notes#3-28-3
[3.28.2]: https://docs.appcircle.io/release-notes#3-28-2
[3.28.1]: https://docs.appcircle.io/release-notes#3-28-1
[3.28.0]: https://docs.appcircle.io/release-notes#3-28-0
[3.27.2]: https://docs.appcircle.io/release-notes#3-27-2
[3.27.1]: https://docs.appcircle.io/release-notes#3-27-1
[3.27.0]: https://docs.appcircle.io/release-notes#3-27-0
[3.26.2]: https://docs.appcircle.io/release-notes#3-26-2
[3.26.1]: https://docs.appcircle.io/release-notes#3-26-1
[3.26.0]: https://docs.appcircle.io/release-notes#3-26-0
[3.25.1]: https://docs.appcircle.io/release-notes#3-25-1
[3.25.0]: https://docs.appcircle.io/release-notes#3-25-0
[3.24.0]: https://docs.appcircle.io/release-notes#3-24-0
[3.23.1]: https://docs.appcircle.io/release-notes#3-23-1
[3.23.0]: https://docs.appcircle.io/release-notes#3-23-0
[3.22.1]: https://docs.appcircle.io/release-notes#3-22-1
[3.22.0]: https://docs.appcircle.io/release-notes#3-22-0
[3.21.0]: https://docs.appcircle.io/release-notes#3-21-0
[3.20.5]: https://docs.appcircle.io/release-notes#3-20-5
[3.20.4]: https://docs.appcircle.io/release-notes#3-20-4
[3.20.1]: https://docs.appcircle.io/release-notes#3-20-1
[3.20.0]: https://docs.appcircle.io/release-notes#3-20-0
[3.19.1]: https://docs.appcircle.io/release-notes#3-19-1
[3.19.0]: https://docs.appcircle.io/release-notes#3-19-0
[3.18.0]: https://docs.appcircle.io/release-notes#3-18-0
[3.17.1]: https://docs.appcircle.io/release-notes#3-17-1
[3.17.0]: https://docs.appcircle.io/release-notes#3-17-0
[3.16.0]: https://docs.appcircle.io/release-notes#3-16-0
[3.15.0]: https://docs.appcircle.io/release-notes#3-15-0
[3.14.0]: https://docs.appcircle.io/release-notes#3-14-0
[3.13.0]: https://docs.appcircle.io/release-notes#3-13-0
Click to view version history.
Since the cloud and self-hosted versions are released asynchronously, the release dates listed in the table may differ from those on the **[Release Notes](https://docs.appcircle.io/release-notes)** page.
:::tip
Release dates in the table below are listed in `dd/mm/yyyy` date format.
:::
| Version | Release Date |
|-----------|--------------|
| [3.29.8] | 30/01/2026 |
| [3.29.6] | 24/12/2025 |
| [3.29.5] | - |
| [3.29.4] | 13/10/2025 |
| [3.29.3] | 23/09/2025 |
| [3.29.2] | - |
| [3.29.1] | - |
| [3.29.0] | 15/08/2025 |
| [3.28.3] | 01/08/2025 |
| [3.28.2] | 17/07/2025 |
| [3.28.1] | - |
| [3.28.0] | - |
| 3.27.3 | 21/05/2025 |
| [3.27.2] | 12/05/2025 |
| [3.27.1] | - |
| [3.27.0] | - |
| [3.26.2] | 27/03/2025 |
| [3.26.1] | 10/03/2025 |
| [3.26.0] | - |
| [3.25.1] | 30/01/2025 |
| [3.25.0] | 13/01/2025 |
| [3.24.0] | - |
| 3.23.2 | 04/12/2024 |
| [3.23.1] | 19/11/2024 |
| [3.23.0] | - |
| [3.22.1] | 23/10/2024 |
| [3.22.0] | 11/10/2024 |
| 3.21.2 | 01/10/2024 |
| 3.21.1 | 30/09/2024 |
| [3.21.0] | 17/09/2024 |
| 3.20.6 | 10/09/2024 |
| [3.20.5] | 09/09/2024 |
| [3.20.4] | 26/08/2024 |
| 3.20.3 | 20/08/2024 |
| 3.20.2 | 16/08/2024 |
| [3.20.1] | 07/08/2024 |
| [3.20.0] | - |
| [3.19.1] | 19/07/2024 |
| [3.19.0] | - |
| [3.18.0] | 14/06/2024 |
| 3.17.2 | 30/05/2024 |
| [3.17.1] | 25/05/2024 |
| [3.17.0] | 21/05/2024 |
| [3.16.0] | 14/05/2024 |
| 3.15.1 | 11/05/2024 |
| [3.15.0] | 26/04/2024 |
| [3.14.0] | 17/04/2024 |
| 3.13.2 | 15/03/2024 |
| 3.13.1 | 07/03/2024 |
| [3.13.0] | - |
| 3.12.3 | 21/02/2024 |
| 3.12.2 | 19/02/2024 |
| 3.12.1 | 12/02/2024 |
### 1. Download Latest
To download the licensed Appcircle Server package for your organization, you must copy the `cred.json` file to the directory where you want to install the package. This typically means copying the `cred.json` file to the same directory containing the `appcircle-server` directory.
:::info
Without the `cred.json` file, you will not be able to access the licensed Appcircle Server package.
If you have not yet obtained the `cred.json` file, please contact us for assistance.
:::
Download the latest self-hosted Appcircle package.
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-server.sh | bash
```
:::tip
By default, the command above downloads the latest available Appcircle server version.
You can specify a specific version using the `--package-version` option or `AC_SERVER_VERSION` environment variable..
For instance, suppose there are multiple versions available (e.g. `3.14.0`, `3.14.1`, `3.14.2`, and `3.15.0`) and you want to download version `3.14.1`. To achieve this, simply run the command below:
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-server.sh | AC_SERVER_VERSION=3.14.1 bash
```
Alternatively, if you wish to download the latest package in the 3.14.x series (which would be version 3.14.2), use the following command:
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-server.sh | AC_SERVER_VERSION=3.14 bash
```
:::
:::caution
Upgrading from older versions to `3.14.0` or later requires MinIO migration, which should be done interactively while upgrading.
In order to migrate to single-node single drive MinIO configuration or stay with the deprecated multi-node single drive MinIO configuration, **you must follow the instructions** that are defined in the [MinIO Migration](/self-hosted-appcircle/install-server/linux-package/configure-server/minio-migration) document.
:::
:::caution
#### Upgrade path for `3.29.3` or later
If you are using `3.28.3` or an older version and planning to upgrade to `3.29.3` or a later version, you must have an **intermediate upgrade step** with version `3.29.0`.
See **[here](/release-notes#upgrading-from-3283-or-older-versions-)** for further details, and follow the guide for a healthy upgrade path.
:::
Extract self-hosted Appcircle package into folder.
```bash
unzip -o -u appcircle-server-linux-x64-${version}-${build}.zip -d appcircle-server
```
:::info
You should use the downloaded `zip` archive while extracting so that the actual `${version}` and `${build}` will come from there. You can find the relevant data in the previously executed download command output.
:::
Change directory into extracted `appcircle-server` folder for following steps.
```bash
cd appcircle-server
```
For other details and troubleshooting, you can refer to [download](/self-hosted-appcircle/install-server/linux-package/installation/docker#1-download) section in installation docs.
:::info
After version `3.7.1`, the container image versions, pulled from the Appcircle artifact registry, will be the same version of the Appcircle zip package you downloaded.
In this case, if you download an older version of the Appcircle zip package, the container images will also be older versions.
So as a result, you will downgrade the Appcircle server if you download an older version zip package.
:::
### 2. Update Packages
Although it's rare, update may have new packages or package updates. Those are the tools that self-hosted Appcircle depends on. So they should be kept up-to-date same as Appcircle server.
:::caution
You need to have root access on your system for this step. Being able to run `sudo` is sufficient for the following step. (sudoer)
:::
In order to update packages, execute the script using the `-i` argument as shown below.
```bash
sudo ./ac-self-hosted.sh -i
```
You can also use the long option `--install-package` for the same purpose.
For other details and troubleshooting, you can refer to [packages](/self-hosted-appcircle/install-server/linux-package/installation/docker#2-packages) section in installation docs.
### 3. Update Server
:::info
We're going on with the same sample scenario as in [installation](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) steps.
Let's assume we have company named as Space Tech and our project name is "spacetech". For the following steps, we will give examples based on this fictive company for better understanding.
:::
If update has new features with their configuration options or you want to make some minor changes in your configuration, first edit your `global.yaml` file.
```txt
projects
└── spacetech
├── export
├── generated-secret.yaml
├── global.yaml
└── user-secret
```
In most cases, you don't need to change anything in your configuration. So, above step is optional.
Then execute below command to update server.
```bash
./ac-self-hosted.sh -n "spacetech" export
```
For other details and troubleshooting, you can refer to [configuration](/self-hosted-appcircle/install-server/linux-package/installation/docker#3-configure) section in installation docs.
:::info
Although it's rare, self-hosted Appcircle may have a new service with its dedicated subdomain.
If it was announced in release notes, you need to add new subdomain to your DNS server.
All process is same as in installation, so refer to [DNS settings](/self-hosted-appcircle/install-server/linux-package/installation/docker#4-dns-settings) section in installation docs for details.
:::
### 4. Update Images
In order to get docker image updates for Appcircle server services, we need to pull them from remote artifact repository.
To activate image updates, first stop all running docker containers.
```bash
./ac-self-hosted.sh -n "spacetech" down
```
Upgrade images.
```bash
./ac-self-hosted.sh -n "spacetech" upgrade
```
:::caution
If you are using a proxy on the server, then you should maintain the proxy variables.
Please head to the [Maintenance of Proxy Variables](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/proxy-configuration#maintenance-of-no_proxy-variables) for more details.
:::
Then start with below command.
```bash
./ac-self-hosted.sh -n "spacetech" up
```
When complete, check service statuses.
```bash
./ac-self-hosted.sh -n "spacetech" check
```
You may also print the image hashes and script's version by using the below command.
```bash
./ac-self-hosted.sh -n "spacetech" version
```
:::caution
Please keep in mind that, restarting docker containers will stop all services until all started again. So, it will take some time and during that duration self-hosted Appcircle server will be unreachable.
For this reason, you may prefer to execute this step on an idle time in order to minimize its negative effects on your users.
:::
For other details and troubleshooting, you can refer to [run server](/self-hosted-appcircle/install-server/linux-package/installation/docker#6-run-server) section in installation docs.
## Notes
:::info
Above explained update steps keep all your data consistent and compatible. On most cases, data loss is an undesired case for an update scenario.
But if you want or need to reset your data for some reason, you can follow [reset configuration](/self-hosted-appcircle/install-server/linux-package/installation/docker#reset-configuration) steps in installation docs.
:::
:::info
Although it's rare, self-hosted Appcircle may require also self-hosted runner update. Because on some cases, it may bring some breaking changes for older runners.
If it's required, it will be announced in self-hosted Appcircle release notes with minimum supported runner version.
In order to update your self-hosted runners, refer to [update self-hosted runner](/self-hosted-appcircle/self-hosted-runner/update) section in docs.
For other details and troubleshooting, you can refer to [connecting runners](/self-hosted-appcircle/install-server/linux-package/installation/docker#connecting-runners) section in installation docs.
:::
---
## Amazon Web Services (AWS)
## Overview
In this document, you will see how to create a self-hosted Appcircle runner instance on Amazon Web Services (AWS).
By following the steps below, you will create a dedicated host, Sonoma macOS, from the base AMI, install the Appcircle runner, and make it ready to build Android and iOS applications, just like in the Appcircle cloud.
## Pre-requirements
### Appcircle Requirements
You can use a self-hosted Appcircle runner with your self-hosted Appcircle server or Appcircle cloud account.
:::danger
The only requirement for using self-hosted runners is to be in `enterprise` plan.
See [pricing](https://appcircle.io/pricing) and feature comparison table for details.
:::
### Technical Requirements
Before creating an Appcircle runner on AWS, there are a couple of things that you need to handle.
#### AWS Account
You must have an active AWS account with appropriate permissions to launch EC2 instances and work with other related services.
#### Understanding of AWS Services
A basic understanding of Amazon Web Services (AWS) services, particularly EC2 (Elastic Compute Cloud), is beneficial.
You should be familiar with instance creation, networking, security groups, and storage configurations.
##### 1. Networking and Security Configuration
You might need to configure networking aspects such as Virtual Private Cloud (VPC), subnets, route tables, and security groups to properly integrate the instance within the network environment and manage access controls.
##### 2. SSH Key Pairs for Secure Access
You need an SSH key pair to access to the server that you will create securely.
##### 3. MacOS System Configuration
Basic familiarity with macOS system configurations and commands is essential since this document will use macOS commands.
:::info
MacOS is a Unix-like operating system, much like Linux, which means that many of the commands and underlying principles are similar.
If you have experience with Linux, installing the Appcircle runner on macOS should be a seamless process.
:::
##### 4. Dedicated Hosts and EC2 Mac Instances
While the process of creating an EC2 Mac instance on AWS differs slightly from creating a Linux instance, the key distinction lies in the requirement of a dedicated host.
After selecting a macOS image during the instance creation process, users must specify the dedicated host they have previously provisioned, as outlined in the AWS [documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html) for comprehensive guidance.
Furthermore, detailed instructions are provided below on creating a dedicated Mac instance, ensuring you have the necessary resources for seamless operation.
However, please make sure that you have a dedicated host service quota before proceeding to create a dedicated host.
For more details about the AWS EC2 Mac instances, you can refer to the [documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html).
## Creating a Mac Instance for the Appcircle Runner
After you meet all the requirements discussed above, you can follow the steps below to create a Mac instance for the Appcircle runner installation.
### Creating a Dedicated Host for EC2 Mac Instance
- Log in to the AWS console with your account.
- Select the region from the right upper corner.
:::tip
If you have a self-hosted Appcircle server in AWS, it's better to deploy the self-hosted Appcircle runner in the same region as the Appcircle server.
This approach will reduce the latency between two machines.
:::
#### Check and Request the Dedicated Mac Instance Quota
Before creating the dedicated host instance, you should check the dedicated service quota.
- Head to the "Service Quotas" menu.
- Click on the "AWS services". Filter the EC2 services as below, and then click on the "Amazon Elastic Compute Cloud (Amazon EC2)" service.
- Filter the services by "dedicated mac2" and select the relevant instance type service quota.
- In this tutorial, we will use "mac2" hosts.
If the "applied account-level quota value" is `0`, then you should request an increase as below.
- For your first quota request, you can request `1` quota.
#### Create the Dedicated Host
- Head to the EC2 menu to create an dedicated instance.
- Head to the "Dedicated Hosts" menu and click on the "Allocate Dedicated Host" button.
- Enter a dedicated instance name in the "Name tag" field. For example, "Appcircle Dedicated Host".
- Then you should select the **instance family**, **instance type** and the **availability zone**. For example, `mac2` for the instance family and `mac2.metal` for the instance type.
:::info
You must select one of the **`mac2`**, **`mac2-m2`** or **`mac2-m2pro`** instance families since the Appcircle runner is supported on these instance families.
In the AWS [documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html), you can find the underlying infrastructure listed below.
> - EC2 M1 Mac instances (mac2.metal) are built on 2020 Mac mini hardware powered by Apple silicon M1 processors.
>
> - EC2 M2 Mac instances (mac2-m2.metal) are built on 2023 Mac mini hardware powered by Apple silicon M2 processors.
>
> - EC2 M2 Pro Mac instances (mac2-m2pro.metal) are built on 2023 Mac mini hardware powered by Apple silicon M2 Pro processors.
:::
- Since the Mac instances doesn't support "Host maintenance", you must uncheck it.
- Click on the "Allocate" button to create your dedicated host.
- You can see the created dedicated host on the **Dedicated Hosts** dashboard.
- When you see the state of the dedicated host as "Available", you can continue with creating EC2 Mac instance.
:::tip
If you have more than one dedicated hosts, make a note of the dedicated **Host ID** to avoid confusion when creating the EC2 Mac instance.
:::
### Creating an EC2 Mac Instance on the Dedicated Host
- Head to the EC2 menu to create an EC2 Mac instance.
- Click on the "Launch Instance" button from the EC2 dashboard.
You should fill out the required fields as per your needs. Please follow the below steps for a sample instance configuration.
- Enter an instance name in the "Name and Tags" field. For example, "My Appcircle Runner".
- In order to select the AMI, click on the "macOS" button. Then select "macOS Sonoma" from the AMI drop-down menu. And for the architecture, select "64-bit (Mac-Arm)".
- We will use the `mac2.metal` instance type for our sample configuration since we have crated a `mac2.metal` dedicated host [above](#creating-a-dedicated-host-for-ec2-mac-instance).
:::caution
If you have created another type of dedicated host, like `mac2-m2.metal` or `mac2-m2pro.metal`, you should choose them from the menu.
:::
- Select an existing key pair or click on the "Create new key pair" button if you don't have any on the AWS console.
- For the network settings:
- We will use the default VPC created on the form.
- Don't allow HTTP and HTTPS traffic from the internet.
- The Appcircle runner doesn't require accepting any incoming HTTP(S) requests.
- You can restrict the SSH connection by specifying the source IP addresses.
- **SSH is required** to access the runner from the command line.
- For the storage, you should select a minimum 300 GB disk for a runner that will build Android and iOS applications with three Xcode versions.
- For each Xcode version you plan to install side by side, you should add 50 GB of disk space, roughly.
- In this tutorial, we will install the latest (_at the moment_) three Xcode versions as a sample configuration, which are `15.3`, `15.2`, and `15.1`.
- To select the previously created dedicated host, expand the "Advanced details" settings.
- Set the "Tenancy" to **`Dedicated Host`**.
- Set the "Target host by" to **`Host ID`**.
- Set the "Tenancy host ID" to the dedicated **Host ID** of the previously created dedicated host.
Now you're ready to click on the **Launch Instance** button to create the EC2 Mac instance with the configuration you made.
You can head to the EC2 **Instances** page to see if your server is up and running.
:::info
You need to wait until the **Instance state** of the instance is **`Running`** in order to connect to the instance with SSH.
Generally it takes ~5-10 minutes till the **Instance state** becomes **`Running`** from **`Pending`**.
:::
## Configuring the Appcircle Runner Instance
### Connect via SSH
After you have successfully created an EC2 Mac instance, you can follow the steps below to configure it.
- Get the IP address of the instance from EC2 dashboard.
- Networking > Networking Details > Public IPv4 address
- Or, Instance > Details > Public IPv4 address
- Locate the SSH key pair, especially the private key, that you've created or used while configuring the instance.
- Get an SSH connection tool like `putty` on Windows or `ssh` on macOS and Linux to connect to the instance.
:::info
The `ssh` command below is for macOS and Linux. The other commands are the same after you connect to the instance.
:::
Using **private key** and **IP address**, you can connect to the instance with SSH as seen below.
```bash
ssh -i "/path/to/your/private/key" ec2-user@ip-address-of-the-instance
```
:::info
The default user for the Sonoma macOS AMI is `ec2-user`. So you should use `ec2-user` while connecting to the newly created EC2 Mac instance.
So, let's assume that your instance IP address is `3.234.230.124` and your private SSH key path is `/home/spacetech/.ssh/id_rsa`.
You can connect to the instance using the below command on macOS or Linux.
```bash
ssh -i "/home/spacetech/.ssh/id_rsa" ec2-user@3.234.230.124
```
:::
:::tip
When you "Create new key pair" while creating the instance, the downloaded private key might cause a permission error when you try to connect to the instance. For instance;
> ... Permissions 0644 for 'MyCICDSSHKey.pem' are too open.
> It is required that zour private key files are NOT accessible by others.
> This private key will be ignored. ...
In this case, you need to change the permissions of the private key using the below command before connecting.
```bash
chmod 600 "/path/to/your/private/key"
```
It will be a one-time-operation that should be done once per private key.
:::
:::info
The SSH command may ask you to add this server to the list of known hosts. You should write `yes` and hit enter.
:::
### Configure Runner
#### Install Latest Package
After you successfully connect to the Appcircle runner instance, you can install the Appcircle runner into it.
Change the current working directory to the home directory.
```bash
cd "$HOME"
```
Download the latest self-hosted runner package.
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-osx-arm64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-osx-arm64-1.8.5.zip
```
Change directory into extracted `appcircle-runner` folder for following steps.
```bash
cd appcircle-runner
```
#### Register the Runner to the Appcircle server
:::info
By default, the Appcircle runner is pre-configured to connect to the Appcircle cloud. If you are not using the Appcircle server as self-hosted, you can skip this information.
If you are using a self-hosted Appcircle server, edit the `appsettings.json` file with your favorite editor.
```bash
vi appsettings.json
```
You will see that the `ASPNETCORE_BASE_API_URL` and `ASPNETCORE_REDIS_STREAM_ENDPOINT` values are pre-defined for the Appcircle cloud.
- Change the API URL to your self-hosted server API URL without changing the path.
- Change the Redis stream endpoint to the URL that's compatible with your installation.
For example:
```json
{
...
"ASPNETCORE_REDIS_STREAM_ENDPOINT": "redis.appcircle.spacetech.com:443,ssl=true",
...
"ASPNETCORE_BASE_API_URL": "https://api.appcircle.spacetech.com/build/v1"
}
```
:::caution
If your Appcircle server is working with HTTP, the Redis stream endpoint port must be `6379` instead of `443` and the `ssl` argument must be set to `false`.
Also, don't forget to configure the API URL scheme as HTTP in the `global.yaml`.
:::
Now you need to create a **Runner Access Token** to register this instance with the Appcircle server.
#### Install the Required Build Tools
For this tutorial, we will install the Android tools and iOS tools with the latest (_at the moment_) three stable Xcode versions.
```bash
./ac-runner install -o ios,android -x 15.3,15.2,15.1
```
#### Run the Service
## Building Applications
For a comprehensive overview of building applications on the Appcircle platform, you can navigate to the [Platform Build Guides](/build/platform-build-guides) page.
Have questions? [Contact us here.](https://appcircle.io/support/)
---
## Cloud Providers Integration
Leverage the power of cloud computing within your Appcircle builds by integrating with Cloud Providers. This section details how to connect with Amazon Web Services (AWS), allowing you to scale your build infrastructure on-demand and access a wide range of cloud resources.
## Amazon Web Services (AWS)
Enhance your building and testing capabilities by integrating Amazon Web Services (AWS) into your workflow. Follow the step-by-step guide to set up AWS with your Appcircle environment for improved performance and flexibility.
---
## Android Emulators
# Overview
On build pipeline, you can use android emulators for UI testing of android apps. Self-hosted runner supports this use case and installs below android emulator for general purpose usage by default.
For example, on `macOS arm64` installation default emulator on self-hosted runner will be:
```txt
Name: Pixel_3a
Device: pixel_3a (Google)
Path: $HOME/.android/avd/Pixel_3a.avd
Target: Google Play (Google Inc.)
Based on: Android 9.0 (Pie)
Tag/ABI: google_apis_playstore/arm64-v8a
```
Self-hosted runner chooses emulator ABI according to host architecture. So, android emulator ABI will be always compatible with host architecture for better optimization.
For all types of platforms, whether linux or macOS, other properties of default emulator and its device name are same. You don't need any conditional steps on your workflow while using default installed emulator.
If default emulator does not satisfy your requirements, you can install any additional emulators to self-hosted runner for your own usage.
For example, in order to install Android 11 (API 30) emulator to arm64 macOS you can take below steps:
**1.** Install emulator system image if not exists. (If it exists, command will return quickly with success.)
```bash
sdkmanager "system-images;android-30;google_apis;arm64-v8a"
```
You can see list of available system images with below command:
```bash
sdkmanager --list | grep "system-images;android"
```
**2.** Create new pixel_3a device with "Pixel_Custom" emulator name.
```bash
avdmanager create avd -n Pixel_Custom -k "system-images;android-30;google_apis;arm64-v8a" -c 512M -d pixel_3a
```
When completed with success, you should see below device with `avdmanager list avd`:
```txt
Name: Pixel_Custom
Device: pixel_3a (Google)
Path: /Users/onur/.android/avd/Pixel_Custom.avd
Target: Google APIs (Google Inc.)
Based on: Android 11.0 (R)
Tag/ABI: google_apis/arm64-v8a
Sdcard: 512 MB
```
:::caution
Self-hosted installation checks machine architecture and decides whether to install the default Android emulator on the machine.
If the machine does not support nested virtualization, it will not install the Android emulator with a warning message indicating the case.
:::
## Emulators on Linux
For linux hosts, there are some preconditions to run android emulator. These are not preventing installation of default android emulator on self-hosted runner but you won't be able to start or use emulator on pipeline. So, you should check and satisfy them.
Although we summarize key points on below sections, you can get more detailed information about configuring hardware acceleration for the android emulator from [here](https://developer.android.com/studio/run/emulator-acceleration#dependencies-gpu).
### Check the capability of running KVM
To run KVM, you need a processor that supports hardware virtualization.
```bash
grep -cw ".*\(vmx\|svm\).*" /proc/cpuinfo
# or
egrep -c '(vmx|svm)' /proc/cpuinfo
```
A non-zero result means the host CPU supports hardware virtualization.
Alternatively, you can use below command to check capability:
```bash
sudo apt install -y cpu-checker >/dev/null 2>&1 && sudo kvm-ok
```
If virtualization is not enabled, be sure to enable the virtualization feature in your system.
If you're using cloud computing services, you can take a look at below resources:
- [Amazon Web Services](https://aws.amazon.com/blogs/compute/running-hyper-v-on-amazon-ec2-bare-metal-instances/)
- [Google Cloud Computing](https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances)
- [Microsoft Azure](https://azure.microsoft.com/en-us/blog/nested-virtualization-in-azure)
### Check if KVM module is loaded
```bash
lsmod | grep kvm
```
If you don't see any output, most probably you don't have KVM installed and running. So, follow below steps for Ubuntu based linux distributions.
**1.** Run the command below to install KVM and additional virtualization packages.
```bash
sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system virtinst libvirt-clients bridge-utils
```
**2.** After all the packages installed, enable and start the Libvirt daemon.
```bash
sudo systemctl enable --now libvirtd
```
```bash
sudo systemctl start libvirtd
```
You can check virtualization daemon is status as shown.
```bash
sudo systemctl status libvirtd
```
**3.** Add the currently logged-in user to the kvm and libvirt groups so that they can create and manage virtual machines.
```bash
sudo usermod -aG kvm $USER
```
```bash
sudo usermod -aG libvirt $USER
```
To apply this change, you may need to log out and log in back again.
## Emulators on MacOS
If your GPU hardware and drivers are compatible, the emulator uses the GPU for graphics acceleration. You may get an error message like below, if your user is not logged in. (mostly on reboot cases)
> ... FATAL: Could not compile shader for guest framebuffer blit. There may be an issue with the GPU drivers on your machine. ...
So, take following steps to enable auto-login for the currently logged-in user.
1. Click the **Apple** logo.
2. Select **System Preferences** from the menu.
3. Click **Users & Groups.** (In earlier versions of OS X, this is called **Accounts**.)
4. Click the **lock** to make changes, and enter your administrator password when prompted.
5. Click **Login Options**.
6. Select the **Automatic login** username that you want to configure.
For more details, see [here](https://support.apple.com/en-us/HT201476).
---
## Self-signed Certificates
# Overview
If you're using self-signed certificates in your environment, the same certificates must also be added to runners. It can be your self-hosted Appcircle server or your own git repositories.
If you don't add and trust those self-signed certificates, runner will most probably get SSL connection errors while trying to access those resources.
While adding root CAs and sub CAs to host, you should consider the following locations:
- System keychain (macOS)
- `ca-certificates`, `ca-trust` (linux)
- Ruby's `DEFAULT_CERT_DIR`
- Java's keystore `cacerts`
- Node.js `NODE_EXTRA_CA_CERTS`
## Adding Certificates
The self-hosted runner has a command-line tool to help you install the required certificates. When called, it connects to the given host via the URL and extracts the root CA. It adds the root CA to the locations listed above.
If your runner version `1.3.12` or later, you can find it in the `scripts` directory inside the Appcircle runner directory.
If your runner version is older than `1.3.12`, then you can follow one of the steps below:
- [Upgrade](/self-hosted-appcircle/self-hosted-runner/update#1-update-runner) the Appcircle runner to `1.3.12` or later
- If you can't upgrade the Appcircle runner, you can [download the latest](/self-hosted-appcircle/self-hosted-runner/update#1-update-runner) runner package and get the script from there after you extract the archive.
Execute the bash script like below.
```bash
./install_cert.sh
```
When asked, enter the URL that you need to connect to.
Below is a sample log that was run on macOS.
```txt
% ./install_cert.sh
[+] OS: Darwin
Enter a URL or 'q' to quit: gitlabint.fintek.local
Valid URL entered: gitlabint.fintek.local
[-] Allowing addition of root certificates
[-] Getting root certificate of 'gitlabint.fintek.local'
[+] Subject: mkcert osboxes@osboxes (osboxes.org)
[+] Expires on: Feb 11 08:10:48 2033 GMT
[+] Certificate written to 'gitlabint.fintek.local.crt'
[-] Adding 'gitlabint.fintek.local.crt' to Keychain
YES (0)
YES (0)
[-] Adding 'gitlabint.fintek.local.crt' to Ruby
[+] Copying 'gitlabint.fintek.local.crt' to '/Users/appcircle/.rbenv/versions/2.7.5/openssl/ssl/certs'
[+] Rehashing 'gitlabint.fintek.local.crt' via /Users/appcircle/.rbenv/versions/2.7.5/openssl/bin/c_rehash
Doing /Users/appcircle/.rbenv/versions/2.7.5/openssl/ssl/certs
[-] Adding 'gitlabint.fintek.local.crt' to Java Keystore
Certificate was added to keystore
[-] Verifying connection to 'gitlabint.fintek.local'
[+] Verification successful!'
Enter a URL or 'q' to quit: q
%
```
After the script is complete, the operating system, default Java (`17`), Ruby, and Node.js trust the root certificate.
:::caution
Please exit from the current terminal session and start a new one for changes to take effect.
:::
### Adding Certificates Manually
In situations where automatic root certificate detection may not work, the bash script provides a user-friendly manual trust method.
Users can supply the root certificates themselves locally to the tool and import them.
Once imported, the operating system and other tools listed above will trust the certificate, ensuring secure connections to the server, just like getting them from a URL.
If `install_cert.sh` can't auto-detect the root CA from URL, follow the steps below to import it from disk:
- Get your organization's root CA and copy its content.
- Go to the `scripts` directory, which is in the `appcircle-runner` directory.
- Create a file named `rootca.crt` and paste the root CA content inside it.
```bash
vi rootca.crt
```
:::info
Alternatively, you can push the certificate files to the runner disk and use them directly as certificate arguments.
:::
- To use the `install_cert.sh` in manual mode, you should provide the root CA and a URL to test the connection.
```bash
./install_cert.sh
```
For example, if you saved the root CA in the `rootca.crt` file and want to import and test the connection to the Appcircle server, see the example below:
```bash
./install_cert.sh rootca.crt api.appcircle.spacetech.com
```
After the script completes successfully, the certificate will be trusted in your system.
---
## Configure Runner
Configuring runners within your self-hosted Appcircle setup is essential for customizing your build and test environments. The following sections provide guidance on how to effectively manage your runners and ensure they are optimized for your development processes.
## [Managing Pools](/self-hosted-appcircle/self-hosted-runner/configure-runner/manage-pools)
Organize your runners into pools to efficiently manage resources and distribute tasks. This section will help you set up and manage pools tailored to different project needs or environments.
## [Managing Runners](/self-hosted-appcircle/self-hosted-runner/configure-runner/manage-runners)
Get detailed instructions on how to manage individual runners. Learn how to add, remove, and configure runners to balance loads and maintain a seamless CI/CD pipeline.
## [Service Configuration](/self-hosted-appcircle/self-hosted-runner/configure-runner/runner-service)
Fine-tune your runners by configuring service parameters. Adjust settings for optimal performance and compatibility with your projects.
## [Android Emulators](/self-hosted-appcircle/self-hosted-runner/configure-runner/android-emulator)
Set up and manage Android emulators for testing purposes. Ensure your Android apps run smoothly across different versions and resolutions by configuring emulators within your runners.
## [Self-signed Certificates](/self-hosted-appcircle/self-hosted-runner/configure-runner/custom-certificates)
Learn how to use self-signed certificates with your runners. This section provides steps to secure your runner communication within your private network.
## [Upgrading Runner](/self-hosted-appcircle/self-hosted-runner/update)
Keep your runners up-to-date with the latest features and improvements. Find out how to upgrade your runners to the latest version with minimal downtime.
## [Cloud Providers](/self-hosted-appcircle/self-hosted-runner/cloud-providers)
Connect your self-hosted runners with cloud providers for additional resources and scalability. This section guides you through integrating popular cloud services into your runner setup.
---
## Managing Pools
### Monitoring Self-hosted Pools
When you add a new self-hosted runner to your organization, it appears at "Self-hosted Runners" list with its pool.
Pool creation is managed automatically while registering a self-hosted runner from CLI.
If a pool doesn't exist in your organization, system creates that pool and adds runner into that pool. If you choose a pool name existing in organization, your runner will be added to that existing pool.
### Select Pool for Build Profile
Self-hosted pools are visible as a list in "Build Profiles". Open your app's build profile, click on "Config" button and you will find pools at "Config" tab in build profile settings.
If you don't have any self-hosted pool yet, list will have only "Default" pool which is Appcircle cloud.
You can choose your self-hosted pools or Appcircle cloud anytime you want and switch between them according to your needs.
:::danger
Keep in mind that, pool selection is important for build pipeline success. Your self-hosted runners in that pool should have required capabilities for the selected build profile.
For example, if your pool has only android tools configured in its runners, you can't build an iOS app in that pool. Or if you have runners with only Xcode 13.3 in your pool, your Xcode 13.4 selected build profile won't be executed in that pool.
:::
:::info
You can not define or select specific self-hosted runner in a pool. When a build job enters queue, it will be selected by any of the runner in that pool. So, as a best practice, try to organize your pool homogeneously.
Pools should have runners which have similar tools and capabilities. Machine architecture (arm64, x86_64) can also be taken into account when organizing self-hosted pools.
:::
:::info
Changing runner pool doesn't affect current running builds on pool. It will affect next build job after change.
:::
#### Pool-Based Xcode Version Selection
When self-hosted runners connect, they provide the build platform information they can receive builds for, along with any available Xcode versions. In the self-hosted collection, this information is updated and maintained. The goal is to allow the selection of an Xcode version specific to the runner during the build process instead of using the default Xcode.
If we are working with multiple machines on the iOS side, we can now define Xcode versions specific to the runner pool.
Accordingly, you can make specific pool selections and set your configurations.
Example Macpool 1:
Example Macpool 2:
### Delete Self-hosted Pool
Pool removal is managed automatically while removing or moving runner. If you remove a self-hosted runner and its pool doesn't have any other runners in that pool, then empty pool is deleted automatically and you won't see it in self-hosted runners list or build profile config tab. Same behavior happens when you move a self-hosted runner from one pool to another.
If you want to remove pool manually or remove group of runners with pool removal, click on pool name at "Self-hosted Runners" list and use "Delete" button at the bottom of pool details.
A confirmation dialog will be visible for your approval. Type pool name into textbox and click on delete.
This action removes pool and its runners all together. Previously assigned build profiles will be mapped to "Default" pool and until you assign them to another self-hosted pool, their build jobs will be sent to Appcircle cloud.
:::info
Removing or deleting self-hosted pools doesn't affect running build jobs on that pool. On-going build jobs will be completed but that self-hosted pool won't get any new build job from queue.
:::
---
## Managing Runners
### Monitoring Self-hosted Runners
When you add a new self-hosted runner to your organization, it appears at "Self-hosted Runners" list with `Offline` state. You can see your runner in list with given name and pool from CLI.
After configuring and starting runner service, it becomes `Online` on list.
Self-hosted runners list has also other quick details which give your overview for your runners.
- "Version" is your self-hosted runner's version, you got from CLI.
```bash
./ac-runner --version
```
- "Last Contact" shows when Appcircle cloud has last contact with your self-hosted runner.
- "State" shows your self-hosted runner's current build status. For example, it can be `idle` when runner is waiting for a build job and `running` when it's executing build job.
You can **disable** self-hosted runner from list, using toggle button on right-hand side. When runner is disabled, it won't accept build job anymore. Disabling runner, doesn't affect currently running build pipeline on runner. It will complete its executing job. When complete, it won't take any new build job from queue until you **enable** it again. Using same toggle button you can enable self-hosted runner.
With quick enable/disable feature, you can remove self-hosted runner from pool temporarily and make some maintenance or debugging. When ready, you can add the self-hosted runner to pool again without any CLI operation.
:::danger
Your pool should have at least one active (ready-to-build) runner for build pipeline continuity.
If your pool is assigned to an active build profile but doesn't have any active runners, started build jobs from that profile will wait in queue until timeout.
For this reason, you should think about your pool organization and build profile settings while removing or disabling self-hosted runners.
:::
### Move Self-hosted Runner Between Pools
For some reason, you may need to move your runner from one pool to another. For this purpose, use below command:
```bash
./ac-runner install -p ${Runner Pool}
```
Runner pool argument must be new target pool to move self-hosted runner.
If there is no runner left in old pool, it will be deleted automatically and disappear from build profile pool selection list.
If new target pool doesn't exist, it will be created automatically.
:::info
Moving self-hosted runner from one pool to another doesn't require service restart. Change will be activated immediately without any manual intervention.
:::
### Delete Self-hosted Runner
If you want to remove your self-hosted runner for any reason, click on runner name to open details view. Here you can see details of your runner. (its pool, create and update times etc.)
Click on delete button at the bottom of the page. A confirmation dialog will be visible for your approval. Type runner name into textbox and click on delete.
Deleting runner removes it from pool and it's unreachable from Appcircle cloud. If you want to add same runner again to the same pool or another pool, you need to register and configure it again. See, [add self-hosted runner](../installation) page for details.
:::info
Removing or deleting runner from pool doesn't affect running build job on that runner. On-going build job will be completed but that runner won't get any new build job from queue.
:::
:::info
If there is no runner left in self-hosted pool, it will be deleted automatically and disappear from build profile pool selection list.
:::
:::danger
When a self-hosted pool is deleted from organization for any reason, its related build profiles will return to `default` pool automatically which is Appcircle cloud. So, build jobs will go on with Appcircle-hosted runners automatically.
:::
### Adding Xcode After Install
You can add more Xcode versions side-by-side or more up-to-date Xcode any time after installation.
```bash
./ac-runner xcode -v ${Xcode Version}
```
Xcode version argument is similar to xcode argument on [installation](../installation#3-configure). You can give one or more versions comma-separated.
For example, below command will install Xcode 13.1.x:
```bash
./ac-runner xcode -v 13.1
```
For example, below command will install both Xcode 13.1.x and 12.5.x side-by-side:
```bash
./ac-runner xcode -v 13.1,12.5
```
:::info
Adding Xcode to self-hosted runner doesn't require service restart. Newly added Xcode versions will be enabled immediately without any manual intervention.
:::
---
## Service Configuration
# Overview
After registration and configuration of self-hosted runner, you need to install launchd or systemd service to start runner as a daemon. Launchd service is used for macOS, systemd service is used for Linux.
Self-hosted runner periodically checks for build jobs and dequeues eligible job for pipeline execution. So, it's always up in background and works non-interactively. When service is installed successfully, it will be automatically started on operating system boot without any manual intervention.
Runner service keeps its logs at `$HOME/appcircle-runner` path. There are two log files:
- stdout.log
- stderr.log
`stdout.log` is connected to standard out of service and `stderr.log` is connected to standard error of service.
`stdout.log` file has build job log. You can see same build log as web UI while pipeline is executing:
```bash
tail -f stdout.log
```
Logs are rotated daily and are kept at most 7 days historically.
Old logs can be found under `service.logs` directory. Each archived log file has date suffix and compressed by gzip. If you need to view an archived log, you can use `gzip -dk LOG_FILE.gz` to extract archive file.
### Install
```bash
./ac-runner service -c install
```
Installs and starts self-hosted runner service. It's used once, while installing and configuring self-hosted runner.
### Status
```bash
./ac-runner service -c status
```
You can see current service status of self-hosted runner (up or down).
### Start
```bash
./ac-runner service -c start
```
Starts runner service if it's stopped. If runner service is down for some reason, you can try start manually.
### Stop
```bash
./ac-runner service -c stop
```
You can disable self-hosted runner from web UI. (See, [here](./manage-runners) for details)
If you need to disable self-hosted runner from CLI, you can use service stop option.
Service start from CLI will enable runner again.
:::info
Launchd or systemd service start and stop actions doesn't affect "Enabled" toggle button state on "Self-hosted Runners" list.
When a self-hosted runner service is stopped from CLI, you will see it as `Offline`. When service is started, it will become `Online`.
:::
:::danger
You should be careful for running pipelines while stopping self-hosted runner service. When you stop service, it will immediately terminate self-hosted runner process and build job will be cut. It will be still shown as in-progress build but actually it's not working. It will stuck in that state until build timeout.
Sometimes this situation may not be a problem for you, because you can cancel and retry build job with another online self-hosted runner. But if it's an unacceptable case for you, then you should check current state of runner from "Self-hosted Runners" list before stopping self-hosted runner service.
You can also follow instantly service log `stdout.log` for running build job. When runner becomes idle, you can stop service safely.
While waiting runner to complete its job, you can use "disable" toggle button from "self-hosted runners" list in order to prevent runner getting new build job from queue.
Service restart and uninstall processes have also same situation since they have service stop implicitly.
:::
### Restart
```bash
./ac-runner service -c restart
```
It's equivalent to stop and start with a single command.
### Uninstall
```bash
./ac-runner service -c uninstall
```
Stops self-hosted runner service and removes launchd/systemd service entries. It reverts service install process.
---
## Troubleshooting & FAQ for Appcircle Runner
## Appcircle Runner FAQ
### We are facing a self-signed certificate error on builds.
The certificate of your organization should be trusted on the Appcircle runner virtual machines.
You should refer to the [Custom Certificates](/self-hosted-appcircle/self-hosted-runner/configure-runner/custom-certificates) page for more details.
### We are facing an "SSL certificate is not valid yet" error on builds.
The runner VMs cannot connect to the servers to update their date and time due to network restrictions.
You should configure NTP server settings in the runner VMs. For updating base runners, please refer to the [Update Base Images](/self-hosted-appcircle/self-hosted-runner/runner-vm-setup#update-base-images) section.
For details on configuring NTP settings, you can refer to the [NTP Configuration](/self-hosted-appcircle/self-hosted-runner/runner-vm-setup#2-configure-base-runners-ntp-settings) section and follow the steps.
### We are facing a "connection timeout" / "connection reset" / "403 forbidden" error on builds.
Especially if you're using external sources as dependencies that require access to certain URLs, you may encounter connection issues due to network restrictions.
To verify whether your Appcircle runner can access the URL, you can run the command below and check the output. Make sure to replace the example RubyGems URL below with the URL you faced network problems with while running the build.
```bash
curl -v https://rubygems.org
```
If you receive an "operation timed out", "connection timeout", "connection reset", or "403 forbidden" error, it indicates that the Appcircle runner is unable to access the URL due to network restrictions. In that case, you'll need to allow Appcircle runners to access the URL.
You can find the list of commonly required URLs for Appcircle runners [here](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access#appcircle-runner-runtime). Please note that the specific URL the Appcircle runner is unable to access may not be included in this list.
### We can't register Appcircle runner to the server.
First, you should check if your Appcircle runner can access the Appcircle server. You can run the command below to test this. You should change the example Appcircle URL for yourself.
```bash
curl -v https://api.appcircle.spacetech.com
```
You should check if there is a self-signed certificate problem. You can refer to the [Custom Certificates](/self-hosted-appcircle/self-hosted-runner/configure-runner/custom-certificates) page to trust the root CA certificate of your organization.
If you already trusted the root CA cert, you should check the Appcircle server's certificate. If it is too long, like 5 years, it should be trusted using the graphical user interface. You should open the Keychain Access application from the GUI and add the Appcircle server's certificate. After that, you should click on the certificate and select "Always trust".
### We are facing "LoginName too long" error while running the `screen` command.
The `screen` command has a bug with long usernames which has been fixed in the new versions.
If you are facing this error while trying to run Appcircle runner VMs on a macOS host, you should update the `screen` tool on the host machine with `brew`.
You should follow the steps below to update the `screen` tool:
- Check the current version before updating.
```bash
screen --version
```
- Install the up-to-date version using Homebrew.
```bash
brew install screen
```
- Open a new terminal session to use the new `screen`.
:::caution
If you don't open a new terminal session, you cannot use the up-to-date `screen` since the current shell session has access to the older version.
:::
- Re-check the version to see if the update was done successfully.
```bash
screen --version
```
---
## Overview of Self-hosted Runner
Self-hosted runner enables you to use your own systems and infrastructure for running Appcircle build pipelines. By this way, you can build and test your apps on your choice of architectures. You have full control over the build environment especially for hardware and operating system.
Self-hosted runners can be physical (bare-metal) machines or virtual machines. You should choose your hardware configurations that meet your needs with enough processing power and memory to run your build jobs.
To get started:
- Provide your own platform to install Appcircle self-hosted runner
- Install and register self-hosted runner to Appcircle infrastructure
:::danger
The only requirement for using self-hosted runners is to be in `enterprise` plan.
See [pricing](https://appcircle.io/pricing) and feature comparison table for details.
:::
### Differences Between Appcircle-hosted and Self-hosted Runners
**Appcircle-hosted runners:**
- Receive automatic updates for the operating system
- Has some operating system level optimizations
- Preinstalled packages and tools regularly updated
- Are managed and maintained by Appcircle
- Provides a clean instance for every build job
- Can take longer to start your build (waiting in queue)
**Self-hosted runners:**
- Can use your own local or private cloud machines for build job
- Customizable to your hardware, operating system, and security requirements
- Don't need to have a clean instance for every build job (reusable caches)
- Not waiting in build queue for other users' build jobs (private queue)
:::info
On self-hosted runners, you can have a clean and isolated instance for each build, just like Appcircle Cloud.
In this case, we recommend running a single runner per (virtual) machine for better isolation if you need concurrency. Using a well-established virtualization infrastructure, such as a virtual machine or Docker container, for a self-hosted runner also helps you to run every build on a clean state.
:::
## Runner Pools
Runner pools are a way of grouping many runners with similar build capabilities and assigning them to build profiles with a single click. You can group and organize your runners according to installed platform tools, operating systems or architectures. You can use any number of pools for your needs.
You can use any text for your pool naming according to your requirements. Pools are added automatically while adding self-hosted runners. Then you will find your runner and its pool in "Build > Self-hosted Runners" list. When your runner is ready for build, you can choose your runner pool from "Build Profile > Config" section and send build jobs to those group of runners.
## Limitations
Self-hosted runner usage is limited with your current plan's monthly quotas. Same hard limits of `enterprise` plan is applied to both self-hosted and Appcircle-hosted runners.
For example, you can not start a new build when you exceeded the number of builds that can be initiated in a month. Your self-hosted runners will be kept in your organization. You can manage them and you can add new runners, but can not use them for build job. When your monthly quotas are renewed, you can go on with self-hosted builds.
When your `enterprise` plan expires or doesn't renew on time, self-hosted runner usage will also be limited with your downgraded plan. In this case, you can not build apps with self-hosted runners although your build quota is sufficient. You can't add new self-hosted runners even if you have runner access token created previously before downgrade. You can see list of existing self-hosted runners but can not see pool or runner details. You can't delete any pool or runner and can't enable or disable any runner.
Your existing self-hosted runners will be kept in system as-is and won't be removed by us. When you upgrade to `enterprise` plan again, you can go on using your self-hosted runners as usual.
If you don't upgrade to `enterprise` plan, you can only use Appcircle-hosted runners which is default pool.
---
## Self-Hosted Runner Installation
# Prerequisites
The following operating systems are supported for the self-hosted runner.
**Linux**
- Ubuntu 20.04 or later
- Debian 11 or later
**MacOS**
- MacOS 11 (Big Sur) or later
The following processor architectures are supported for operating systems.
- `x64` Linux, macOS
- `arm64` macOS only
To install and execute runner, you will need to have root access. Being able to run `sudo` (sudoer) is sufficient for runner operations.
Also you need to have the following tools installed on your system:
- curl
- unzip
These tools are already installed on most operating systems or can be got from default package managers.
Minimum hardware requirements for self-hosted runner can be:
- 100GB or more free disk space
- 2 or more cores CPU (x64, arm64)
- 8 gigabytes (GB) or more RAM
Minimum required disk space should be enough both for iOS and android platforms. But that value is only for one Xcode version. According to your selection of Xcode versions you need more disk space for successful installation.
:::info
For linux installations, you can also prefer docker container for supported distributions. You can install linux package of self-hosted runner on a running docker container same as bare-metals.
**But you must select a docker image with `systemd` support enabled.**
You can either install and configure `systemd` on docker by yourself, or choose from preconfigured images.
See [here](https://developers.redhat.com/blog/2019/04/24/how-to-run-systemd-in-a-container) for more detailed information about `systemd` in a container.
Or, as a quick alternative, you can use docker images from [here](https://hub.docker.com/r/jrei/systemd-ubuntu) for `ubuntu` containers.
Let's assume, you selected ready-to-use `ubuntu:20.04` image from there.
First you should start container with command below.
```bash
docker run -d --name systemd-ubuntu --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro jrei/systemd-ubuntu:20.04
```
Log in to running container with bash, interactively.
```bash
docker exec -it systemd-ubuntu /bin/bash
```
From now on, you will follow same installation steps seen below as other environments.
:::
:::tip
#### macOS VM
Appcircle provides a ready-to-use macOS VM image, especially for enterprise installations. It can be run on macOS Ventura, Sonoma, Sequoia, or Tahoe `arm64` hosts according to the guest macOS version.
See details in [here](/self-hosted-appcircle/self-hosted-runner/runner-vm-setup).
:::
## Installation
Adding a self-hosted runner requires that you download, register and configure Appcircle runner in your environment.
### 1. Download
Download the latest self-hosted runner package.
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-osx-arm64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-osx-arm64-1.8.5.zip
```
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-osx-x64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-osx-x64-1.8.5.zip
```
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-linux-x64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-linux-x64-1.8.5.zip
```
Change directory into extracted `appcircle-runner` folder for following steps.
```bash
cd appcircle-runner
```
### 2. Register
### 3. Configure
#### Self-Signed Certificates
If you're using self-signed certificates, you need to follow the below document to add your certificates to runners.
Self-Signed Certificates
### 4. Run Service
If you need concurrency or multiple instances of self-hosted runner but don't have multiple bare-metals, then you should use virtualization infrastructure.
You can install multiple VMs on a single bare-metal and deploy self-hosted runner to each VM seperately.
:::
:::tip
You can also add or change platform tools after start of runner service.
For example, you configure runner with iOS platform tools using `-o ios` at first, then add android platform tools with `-o ios,android` to build both iOS and android apps.
Install command used for runner configuration, both adds tools to your system and makes some configurations for them. In order to activate changes and updates completely, you should restart runner service after configuration is done successfully.
```bash
./ac-runner service -c restart
```
Restarting runner service will first stop service and start it again.
See [here](./configure-runner/runner-service) for more details about runner service operations.
:::
### 5. Build App
---
## Runner Virtual Machine Setup
# Self-hosted Runner as MacOS VM Image
Self-hosted runner installation is explained at Appcircle [docs](installation) in detail. You can install runner in your self-hosted environment by yourself, following instructions on there.
We're also providing ready-to-use runner VM image that you can download from Appcircle CDN. Especially for enterprise installation, it might be more practical than installing from scratch.
Here are some reasons for choosing VM image for self-hosted runner;
- It's more quick and easy way of deploying runner. Just download VM image and make some minor configurations for your environment.
- While installing runner, we need several packages from various sources on internet and runner installation requires to be online. Since all iOS and android build pipeline tools are included in VM image, you don't need complex firewall rules while deploying runner.
- It minimizes effects of strict macOS policies applied to host, especially at enterprise environments. Your runner environment will be same as used in Appcircle cloud.
- Since we use virtual machine for runner, it provides a clean, isolated instance for every build job. It means, known and more stable runner environment. Your runner won't persist any macOS changes done in build pipeline which can make runner unstable in time.
- You can install and run only one instance of self-hosted runner on a physical machine. On the other hand, using virtualization infrastructure brings us concurrency. We can run multiple instances of runner on the same host.
## Requirements
In order to use macOS VM, we need to install some dependencies on macOS host.
### 1. Install Homebrew
Script explains what it will do, follow instructions on there.
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
When installation complete, test:
```bash
brew doctor
```
```bash
brew --version
```
### 2. Install Tart
Tap Appcircle repository and install `tart` (Tart is a registered trademark of Cirrus Labs, Inc.).
```bash
brew tap appcircleio/cli
```
```bash
brew install appcircleio/cli/tart
```
When installation complete, test:
```bash
tart --version
```
Run `tart` to touch initial folders.
```bash
tart list
```
Create VMs root folder in tart home.
```bash
mkdir $HOME/.tart/vms
```
### 3. Install Pigz
Pigz is an acronym for **P**arallel **I**mplementation of **GZ**ip, which is a fully functional replacement for `gzip` that helps us compress and extract files faster and more stably.
```bash
brew install pigz
```
When installation complete, test:
```bash
pigz --version
```
### 4. Configure Power Settings
Configuring power settings on macOS to prevent the system from entering sleep mode is vital when deploying it as an Appcircle runner.
By keeping the system awake, you ensure uninterrupted accessibility to your Appcircle runners, preventing any potential offline cases caused by the system going to sleep.
This continuous availability is critical for running builds, as it guarantees that your builds can find runners online.
We suggest disabling those power settings to make it behave like a server station.
```bash
sudo pmset -a sleep 0
sudo pmset -a powernap 0
sudo pmset -a disksleep 0
sudo pmset -a displaysleep 0
```
### 5. Configure Power Failure Settings
Power failure settings allow a Mac to restart automatically after a power outage or failure. Activating this on a Mac ensures the host comes back online automatically if power is lost, avoiding downtime.
:::info
For now, Appcircle runners don't support auto-start when the macOS host restarts.
You should connect to host with SSH and [start the VMs](#start-vm) manually.
:::
To configure power failure settings, you can run the command below.
```bash
sudo /usr/sbin/systemsetup -setrestartpowerfailure on
```
You should see "setrestartpowerfailure: On" in the command output after successful execution.
:::info
If your host doesn't support this feature, you will get the message below.
> Restart After Power Failure: Not supported on this machine.
You can ignore power failure settings if they are not supported.
:::
## Download MacOS VM
You have two options to obtain the Appcircle runner images: manual or automated.
To perform these tasks manually, you can follow our step-by-step guide on [downloading the macOS VM image manually](#download-the-macos-vm-image-manually).
Alternatively, you can automate this process in the background by following our instructions on [downloading the macOS VM and Xcode images automatically](#download-the-macos-vm-and-xcode-images-automatically).
### Download the macOS VM Image Manually
:::tip
MacOS VM image has a versioning convention based on release date instead of arbitrary numbers. This date-based approach is called calendar versioning, or CalVer for short.
Our calendar versioning scheme for the macOS image is `YY0M0D`. For example, a macOS image that's released on March 6, 2024, should have version `240306`.
The versions are listed in reverse chronological order, from the most recent to the earliest, in the tabs below.
:::
Download macOS VM from Appcircle bucket.
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_260303.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_251224.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_251113.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_251015.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_250603.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_250512.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_241227.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_240918.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_240514.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/macOS_240306.tar.gz
```
:::tip
If you encounter network interruption, just run the same command again. It should continue download for remaining part. It will result in saving both time and bandwidth.
:::
---
**Note:** You can check the integrity of downloaded file by comparing the MD5 checksum.
```bash
md5 macOS_260303.tar.gz
```
```bash
md5 macOS_251224.tar.gz
```
```bash
md5 macOS_251113.tar.gz
```
```bash
md5 macOS_251015.tar.gz
```
```bash
md5 macOS_250603.tar.gz
```
```bash
md5 macOS_250512.tar.gz
```
```bash
md5 macOS_241227.tar.gz
```
```bash
md5 macOS_240918.tar.gz
```
```bash
md5 macOS_240514.tar.gz
```
```bash
md5 macOS_240306.tar.gz
```
After a couple of minutes later you should see the output below.
```bash
MD5 (macOS_260303.tar.gz) = 425ad8bff9189a156d09b308cebd54a3
```
```bash
MD5 (macOS_251224.tar.gz) = 4384fe1988db6a54f6e399e91b9c7a2c
```
```bash
MD5 (macOS_251113.tar.gz) = 433b0c2fc81fe7f97af33168711fc066
```
```bash
MD5 (macOS_251015.tar.gz) = cad8bcb22c5f7207fcbb25e5b78a6a88
```
```bash
MD5 (macOS_250603.tar.gz) = fec1fb675be9ff50754a894f56096f6f
```
```bash
MD5 (macOS_250512.tar.gz) = 896f7bb2f46d7091ef0125948749ee8a
```
```bash
MD5 (macOS_241227.tar.gz) = 505d3bd11088c193fd9b828cbcf95df0
```
```bash
MD5 (macOS_240918.tar.gz) = aeb6ff4b655b04fa47fb45e2caf09792
```
```bash
MD5 (macOS_240514.tar.gz) = 8524abc65668a084589e79f214a9b281
```
```bash
MD5 (macOS_240306.tar.gz) = 084a9221075ed5453aceba6a3438b134
```
---
Create folder for VM.
```bash
mkdir -p $HOME/.tart/vms/macOS_260303
```
```bash
mkdir -p $HOME/.tart/vms/macOS_251224
```
```bash
mkdir -p $HOME/.tart/vms/macOS_251113
```
```bash
mkdir -p $HOME/.tart/vms/macOS_251015
```
```bash
mkdir -p $HOME/.tart/vms/macOS_250603
```
```bash
mkdir -p $HOME/.tart/vms/macOS_250512
```
```bash
mkdir -p $HOME/.tart/vms/macOS_241227
```
```bash
mkdir -p $HOME/.tart/vms/macOS_240918
```
```bash
mkdir -p $HOME/.tart/vms/macOS_240514
```
```bash
mkdir -p $HOME/.tart/vms/macOS_240306
```
Extract archive into VMs folder.
```bash
pigz -cvdp 4 macOS_260303.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_260303
```
```bash
pigz -cvdp 4 macOS_251224.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_251224
```
```bash
pigz -cvdp 4 macOS_251113.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_251113
```
```bash
pigz -cvdp 4 macOS_251015.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_251015
```
```bash
pigz -cvdp 4 macOS_250603.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_250603
```
```bash
pigz -cvdp 4 macOS_250512.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_250512
```
```bash
pigz -cvdp 4 macOS_241227.tar.gz | tar xvf - --directory $HOME/.tart/vms/macOS_241227
```
```bash
tar -zxf macOS_240918.tar.gz --directory $HOME/.tart/vms/macOS_240918
```
```bash
tar -zxf macOS_240514.tar.gz --directory $HOME/.tart/vms/macOS_240514
```
```bash
tar -zxf macOS_240306.tar.gz --directory $HOME/.tart/vms/macOS_240306
```
It may take a little to complete. Be patient and wait return of command.
You can track progress of extraction by monitoring VM folder size.
```bash
du -sh $HOME/.tart/vms/macOS_260303
```
```bash
du -sh $HOME/.tart/vms/macOS_251224
```
```bash
du -sh $HOME/.tart/vms/macOS_251113
```
```bash
du -sh $HOME/.tart/vms/macOS_251015
```
```bash
du -sh $HOME/.tart/vms/macOS_250603
```
```bash
du -sh $HOME/.tart/vms/macOS_250512
```
```bash
du -sh $HOME/.tart/vms/macOS_241227
```
```bash
du -sh $HOME/.tart/vms/macOS_240918
```
```bash
du -sh $HOME/.tart/vms/macOS_240514
```
```bash
du -sh $HOME/.tart/vms/macOS_240306
```
### Download Xcode Images Manually
Download Xcode images from the Appcircle bucket. They are disk images for each Xcode version archived in a package.
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_260303.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_251224.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_251113.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_251015.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_250603.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_250512.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_241227.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_240918.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_240514.tar.gz
```
```bash
curl -L -O -C - https://storage.googleapis.com/appcircle-dev-common/self-hosted/xcodes_240306.tar.gz
```
If you encounter network interruption, just run the same command again. It should continue download for remaining part. It will result in saving both time and bandwidth.
---
**Note:** You can check the integrity of downloaded file by comparing the MD5 checksum.
```bash
md5 xcodes_260303.tar.gz
```
```bash
md5 xcodes_251224.tar.gz
```
```bash
md5 xcodes_251113.tar.gz
```
```bash
md5 xcodes_251015.tar.gz
```
```bash
md5 xcodes_250603.tar.gz
```
```bash
md5 xcodes_250512.tar.gz
```
```bash
md5 xcodes_241227.tar.gz
```
```bash
md5 xcodes_240918.tar.gz
```
```bash
md5 xcodes_240514.tar.gz
```
```bash
md5 xcodes_240306.tar.gz
```
After a couple of minutes later you should see the output below.
```bash
MD5 (xcodes_260303.tar.gz) = fdccb3a8611306932248556a763a0e94
```
```bash
MD5 (xcodes_251224.tar.gz) = 40e975b030f4b04b81d04c71e2dd1e17
```
```bash
MD5 (xcodes_251113.tar.gz) = a141a968a72c3f5ba40761139e61f268
```
```bash
MD5 (xcodes_251015.tar.gz) = ee09cc713cbfaf276dbc9008fad403c0
```
```bash
MD5 (xcodes_250603.tar.gz) = 1d65383129a0bcc650be506c4c1b827a
```
```bash
MD5 (xcodes_250512.tar.gz) = 8c66b7f20c64fc3e8f987d95aa31c50d
```
```bash
MD5 (xcodes_241227.tar.gz) = ee312f6077b9a09a5563d57e50bf53f8
```
```bash
MD5 (xcodes_240918.tar.gz) = bb26c0070bbd1a8ed23fe59b87f0a144
```
```bash
MD5 (xcodes_240514.tar.gz) = e3edc40c9b6dda91530d8a1f8cf456bc
```
```bash
MD5 (xcodes_240306.tar.gz) = 4df051e11b6c0b8670cd9b82928dfab2
```
---
Create folder for the Xcode disk images.
```bash
mkdir -p $HOME/images
```
Extract archive into the folder.
```bash
pigz -cvdp 4 xcodes_260303.tar.gz | tar xvf - --directory $HOME/images
```
```bash
pigz -cvdp 4 xcodes_251224.tar.gz | tar xvf - --directory $HOME/images
```
```bash
pigz -cvdp 4 xcodes_251113.tar.gz | tar xvf - --directory $HOME/images
```
```bash
pigz -cvdp 4 xcodes_251015.tar.gz | tar xvf - --directory $HOME/images
```
```bash
pigz -cvdp 4 xcodes_250603.tar.gz | tar xvf - --directory $HOME/images
```
```bash
pigz -cvdp 4 xcodes_250512.tar.gz | tar xvf - --directory $HOME/images
```
```bash
pigz -cvdp 4 xcodes_241227.tar.gz | tar xvf - --directory $HOME/images
```
```bash
tar -zxf xcodes_240918.tar.gz --directory $HOME/images
```
```bash
tar -zxf xcodes_240514.tar.gz --directory $HOME/images
```
```bash
tar -zxf xcodes_240306.tar.gz --directory $HOME/images
```
It may take a little to complete. Be patient and wait return of command.
---
**Note:** This macOS VM image is the Sequoia (`15.6.1`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 26.3 | `17C529` |
| 26.2 | `17C52` |
| 26.1.1 | `17B100` |
| 26.0.1 | `17A400` |
| 16.4 | `16F6` |
**Note:** This macOS VM image is the Sequoia (`15.6.1`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 26.2 | `17C52` |
| 26.1.1 | `17B100` |
| 26.0.1 | `17A400` |
| 16.4 | `16F6` |
**Note:** This macOS VM image is the Sequoia (`15.6.1`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 26.1.1 | `17B100` |
| 26.0.1 | `17A400` |
| 16.4 | `16F6` |
**Note:** This macOS VM image is the Sequoia (`15.6.1`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 26.0.1 | `17A400` |
| 16.4 | `16F6` |
| 16.3 | `16E140` |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
**Note:** This macOS VM image is the Sequoia (`15.4.1`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 16.4 | `16F6` |
| 16.3 | `16E140` |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
**Note:** This macOS VM image is the Sequoia (`15.4.1`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 16.3 | `16E140` |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
**Note:** This macOS VM image is the Sonoma (`14.5`) stack and comes with the Xcode versions below:
| Version | Build |
| ------- | ----- |
| 16.2 | `16C5032a` |
| 16.1 | `16B40` |
| 16.0 | `16A242d` |
**Note:** This macOS VM image is the Sonoma (`14.5`) stack and comes with the Xcode versions below:
> - `16.1.x`
> - `16.0.x`
> - `15.4.x`
> - `15.3.x`
> - `15.2.x`
> - `15.1.x`
> - `15.0.x`
> - `14.3.x`
:::caution
This stack has the `beta` version of Xcode that was included at the time the macOS image was built.
So, if you need to publish iOS apps to the App Store, you should upgrade to the **next** stack that has the latest GA versions of Xcode `16.x.x`.
Otherwise, you might get the error below when you try to publish iOS apps to App Store.
> _... Unsupported SDK or Xcode version. Your app was built with an SDK or version of Xcode that isn't supported. Although you can use beta versions of SDKs and Xcode to build and upload apps to App Store Connect, you need to use the latest Release Candidates (RC) for SDKs and Xcode to submit the app. ..._
If you're currently not ready for Xcode `16.x.x` migration, you can go on using the previous stack until you migrate your iOS apps to newer Xcode versions.
:::
**Note:** This macOS VM image is the Sonoma (`14.1`) stack and comes with the Xcode versions below:
> - `15.4.x`
> - `15.3.x`
> - `15.2.x`
> - `15.1.x`
> - `15.0.x`
> - `14.3.x`
**Note:** This macOS VM image is the Sonoma (`14.1`) stack and comes with the Xcode versions below:
> - `15.3.x`
> - `15.2.x`
> - `15.1.x`
> - `15.0.x`
> - `14.3.x`
In order to keep free disk space sufficient for build pipelines, we're packaging the latest and most frequently used Xcode versions. But you can also install other Xcode versions yourself if required.
You can find more information about the build infrastructure in the documents below:
- [iOS Build Infrastructure](/infrastructure/ios-build-infrastructure)
- [Android Build Infrastructure](/infrastructure/android-build-infrastructure)
### Download the macOS VM and Xcode Images Automatically
To download and extract the Appcircle runner VM and Xcode images in the background automatically, you can run the command below.
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "260303" &
```
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "251224" &
```
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "251113" &
```
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "251015" &
```
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "250603" &
```
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "250512" &
```
```bash
curl -fsSL https://cdn.appcircle.io/self-hosted/download-runner-beta.sh -o download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "241227" &
```
```bash
curl -fsSL -O https://cdn.appcircle.io/self-hosted/download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "240918" &
```
```bash
curl -fsSL -O https://cdn.appcircle.io/self-hosted/download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "240514" &
```
```bash
curl -fsSL -O https://cdn.appcircle.io/self-hosted/download-runner.sh && \
chmod +x download-runner.sh && \
nohup ./download-runner.sh "240306" &
```
:::tip
If you face any errors while downloading the files, please delete the corrupted file and re-run the command block above.
:::
It may take some time to complete with respect to your network speed. You can see and follow the logs with the command below.
```bash
tail -f nohup.out
```
:::info
You can close the SSH or terminal session while the tool is running. The download and extract process will go on in the background.
But be aware that there might be some errors while downloading and extracting the VM image, such as network or disk errors. Please keep an eye on the logs.
:::
:::tip
If no specific image identifier is provided when executing the `download-runner.sh` tool, it will automatically attempt to download the most recent runner images.
:::
## Create Base Images
### Create Base Runner VMs
Apple's virtualization framework allows us to run up to two macOS VMs on host.
:::caution
If you have installed the macOS VM image previously and you're currently trying to upgrade your self-hosted runner environment to another release, first [stop](#stop-vm) the runners if they're online.
Since the below steps will create new `vm01` and `vm02` from the base image, you should also cleanup the current ones using `tart delete` command.
```bash
tart delete vm01
```
```bash
tart delete vm02
```
:::
Each runner must register to the self-hosted Appcircle server with a unique name and configuration. So we will need two VM base images.
When you list VMs with `tart list` command, you should see our extracted VM image in list.
In the steps below, we will create 2 base images named vm01 and vm02.
:::tip
The `vm01` base image is derived from our base image, and subsequently, the `vm02` base image will be created from the `vm01` base image.
This approach eliminates the need to redo all the configurations applied to `vm01` when setting up `vm02`, ensuring efficiency and consistency across both virtual machines.
:::
Create VM image for runner1.
```bash
tart clone macOS_260303 vm01
```
```bash
tart clone macOS_251224 vm01
```
```bash
tart clone macOS_251113 vm01
```
```bash
tart clone macOS_251015 vm01
```
```bash
tart clone macOS_250603 vm01
```
```bash
tart clone macOS_250512 vm01
```
```bash
tart clone macOS_241227 vm01
```
```bash
tart clone macOS_240918 vm01
```
```bash
tart clone macOS_240514 vm01
```
```bash
tart clone macOS_240306 vm01
```
:::tip
It's not recommended to delete the base image (`macOS_YY0M0D`) as it won't save disk space due to copy-on-write file system on macOS. You can safely re-create `vm01` from the same base image `macOS_YY0M0D` without downloading and extracting again from network if needed.
:::
In docker terminology, `vm01` and `vm02` will be our docker images. We will configure them separately, persist our changes and then create containers to execute build pipelines. On every build, fresh containers will be used for both runners.
### Configure Runner VM Resources
You can adjust the resource limits for runner VMs based on your needs.
:::info
By default, our runner images are configured with an 8GB memory limit and 4 CPU cores.
:::
:::caution
Total allocated resources (memory, CPU) for all VMs combined, should not exceed host machine's physical capacity for optimal performance.
:::
#### Set Memory Limits
To configure the memory limit for a VM, run the following command:
```bash
tart set --memory
```
Replace `vm_name` with your VM's name and `size_in_mb` with the desired memory size in MB. E.g.,
> `tart set vm01 --memory 8192` (8GB)
> `tart set vm01 --memory 16384` (16GB)
:::tip
Example configurations:
| Host Memory Size | Runner Memory Config. |
|------------------|-----------------------|
| 8GB | 1 x VM with 8GB |
| 16GB | 2 x VM with 8GB |
| 16GB | 1 x VM with 16GB |
| 32GB | 2 x VM with 16GB |
:::
#### Set CPU Limits
To configure the number of CPU cores for a VM, run the following command:
```bash
tart set --cpu
```
Replace `vm_name` with your VM's name and `count` with the desired number of CPU cores. E.g.,
> `tart set vm01 --cpu 4`
> `tart set vm01 --cpu 8`
:::tip
To check the total number of CPU cores on your system, use the following command:
```bash
sysctl -n hw.ncpu
```
If you have an 8 core CPU according to the command output, you can run 2 VMs and allocate half of the cores to each one, which means 4 cores per VM. Or you can run a single VM using all 8 cores.
Example configurations:
| Host CPU Cores | Runner CPU Config. |
|----------------|----------------------|
| 8 | 2 x VM with 4 Cores |
| 8 | 1 x VM with 8 Cores |
:::
:::caution
Mac devices that have M-series chips (Apple silicon) have two types of CPU cores that you should take into consideration when you configure CPU for the VMs. See the [FAQ](#why-do-i-have-different-build-durations-in-the-pipeline-especially-when-they-run-concurrently-on-the-same-mac-host) below for details.
:::
#### Backing Up and Restoring VM Configuration
When recreating VMs or upgrading to a new image, it's important to preserve your custom settings.
1. Before making changes, backup your base VM's configuration file at `~/.tart/vms//config.json`.
2. After recreating or upgrading the VM, you can either:
- Restore the entire configuration:
```bash
cp /path/to/your/backup/config.json ~/.tart/vms//config.json
```
- Or, manually set the values again using the `tart set` commands.
### Configure Base Runner VMs
Be cautious when updating the base VMs (`vm01` and `vm02`). Any changes made on these base VMs are persisted and may affect disk usage, keychain, and cache files on the runner VMs created from them.
:::warning
If you're freshly creating the base VMs, you can ignore this warning. However, if you've already registered runners to your Appcircle server and want to make updates to the base VMs, it's highly recommended to [disable the runner](/self-hosted-appcircle/self-hosted-runner/configure-runner/manage-runners#monitoring-self-hosted-runners) from the Appcircle dashboard to prevent builds from running on the base VMs.
:::
#### Configure Runner 1
Start runner1 VM image for configuration.
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro \
--disk=$HOME/images/xcode.26.3.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro
```
SSH login into running macOS VM.
```bash
ssh -o StrictHostKeyChecking=no appcircle@$(tart ip vm01)
```
---
**Note:** You should use "cicd" as SSH login password.
---
:::info
While trying to connect VM you can get an SSH connection error as below.
```text
ssh: Could not resolve hostname err: nodename nor servname provided, or not known
```
Wait a couple of seconds and let the VM start its internal services. You can try the same command until you connect successfully.
:::
:::info
Since the VM IPs are rotating, it's possible to see the below error when you try to connect to the VM in the long term.
```text
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:f6CfksJoc0/ZIqItwH5IJDN87SP6RiOo9q1irzDxawU.
Please contact your system administrator.
Add correct host key in /Users/appcircle/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /Users/appcircle/.ssh/known_hosts:5
Password authentication is disabled to avoid man-in-the-middle attacks.
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
UpdateHostkeys is disabled because the host key is not trusted.
appcircle@192.168.64.2: Permission denied (publickey,password,keyboard-interactive).
```
The above example error message indicates that there is an entry for the server `192.168.64.2` located on line 5 of the `known_hosts` file that needs to be removed.
You can delete the old host key entry with the following command and then try re-connecting.
```bash
ssh-keygen -R $(tart ip vm01)
```
:::
In the macOS VM, `/Volumes/agent-disk/appcircle-runner` is the root folder of runner.
```bash
cd /Volumes/agent-disk/appcircle-runner
```
So, the following commands will assume that current working directory is `/Volumes/agent-disk/appcircle-runner`.
##### 1. Check the Runner Version
You may have installed the latest Appcircle runner VM image, but the Appcircle runner may not be up-to-date.
You can follow the steps below to check the Appcircle runner version and upgrade if it isn't the latest version.
- Check the version of the current installation.
```bash
./ac-runner --version
```
- Check the latest version from the [Upgrade Runner](/self-hosted-appcircle/self-hosted-runner/update#1-update-runner) page.
- If your version is not up to date, please follow the [Update Runner](/self-hosted-appcircle/self-hosted-runner/update#1-update-runner) section in the page.
:::caution
You should run the `curl` and `unzip` commands on the `/Volumes/agent-disk/` path.
Since you're in the `appcircle-runner` directory now, please change the directory one level up.
:::
You don't need to apply the `Reconfigure Runner` section. But the `Reinstall Service` section is necessary since the latest version may also have some service updates.
When you complete update successfully, you should see the updated version in `--version` output.
Go to the `appcircle-runner` directory.
```bash
cd appcircle-runner
```
Check the version of the runner.
```bash
./ac-runner --version
```
##### 2. Configure Base Runner's NTP Settings
MacOS VMs try to update their date and time using the network time protocol (NTP) by default.
If your organization has limited network access for the Appcircle runner machine, the VM may be unable to reach the servers responsible for updating its date and time settings.
In a situation like that, your organization might have an NTP server for internal usage.
You can configure your macOS runner VM to use your organization's own NTP server.
You can use the helper script named `configure_ntp.sh` that comes with the runner package to configure the NTP settings.
To configure NTP settings:
- The IP address or URL of the NTP server should be known.
- Network access should be allowed from the Appcircle runner to the NTP server.
- You will find a script named `configure_ntp.sh` in the `scripts` folder inside the `appcircle-runner` directory.
- Run the script and give the NTP server IP (or URL) as an argument, like the example below:
```bash
./scripts/configure_ntp.sh "10.10.1.50"
```
:::caution
You should change "10.10.1.50" to the NTP server address of your organization in the example above.
:::
##### 3. Trust The Root Certificates of Your Organization
If the resources you want to connect use a self-signed certificate, you should also trust the root certificate of your organization in your Appcircle runner VMs. These resources can be:
- Git providers (GitLab, Bitbucket, Azure DevOps, etc.)
- Self-hosted Appcircle server
- Proxy server for network access
Trusting your organization's root certificate on the OS is crucial.
Because the runner will try to connect to these resources over HTTPS and the SSL certificate will be signed with your organization's root certificate.
Furthermore, if the runner attempts to access external web sites, the requests will most likely be intercepted by the proxy and re-signed with a self-issued certificate that is also signed by the root certificate.
You can use the helper script named `install_cert.sh` that comes with your runner package to configure the certificates.
- You will find a script named `install_cert.sh` in the `scripts` folder inside the `appcircle-runner` directory.
- Run the script like the example below:
```bash
./scripts/install_cert.sh
```
- The script will ask you to enter a URL. Please give the URL of the resource that you need to connect to from the runner.
- Hit "enter" and check the results.
- Your organization's root CA certificate is now trusted on the OS, Java, Ruby, and Node.js.
:::info
For more detailed usage, you can check the [Self-signed Certificates](./configure-runner/custom-certificates#adding-certificates) page.
:::
##### 4. Configure Runner Service
---
**Note:** Runner logs are kept in `$HOME/appcircle-runner` folder.
---
Stop runner service.
```bash
./ac-runner service -c stop
```
Edit `appsettings.json` with your favorite editor. (nano, vi etc.)
```json
{
...
"ASPNETCORE_NOSHUTDOWN": "false",
...
"ASPNETCORE_REDIS_STREAM_ENDPOINT": "redis.appcircle.spacetech.com:443,ssl=true",
...
"ASPNETCORE_BASE_API_URL": "https://api.appcircle.spacetech.com/build/v1"
}
```
- **`ASPNETCORE_NOSHUTDOWN`**: It should be `false`. So, it will shutdown VM when build complete.
- **`ASPNETCORE_BASE_API_URL`**: It should be your self-hosted Appcircle server API URL.
- The runner will register to server defined here and take the build jobs from there.
:::tip
The latest macOS VM image,`macOS_240221` or later, has the ASPNETCORE_NOSHUTDOWN setting as `false` by default and has no pre-defined ASPNETCORE_BASE_API_URL setting in the `appsettings.json` file.
So, if you did not upgrade the packaged self-hosted runner at [previous steps](#1-check-the-runner-version) above, only modifying the ASPNETCORE_BASE_API_URL value with the following command should be enough for the configuration up-to-here.
```bash
echo "$(jq '.ASPNETCORE_BASE_API_URL="https://api.test-appcircle.tool.zb/build/v1"' appsettings.json)" > appsettings.json
```
If you upgraded the self-hosted runner, you must also modify the ASPNETCORE_NOSHUTDOWN setting as well.
```bash
echo "$(jq '.ASPNETCORE_NOSHUTDOWN="false"' appsettings.json)" > appsettings.json
```
:::
- **`ASPNETCORE_REDIS_STREAM_ENDPOINT`**: It should be your self-hosted Appcircle server's Redis URL, port, and SSL settings.
- If you are using the Appcircle server with HTTPS, then the port should be `443` and the `ssl` argument should be set to `true`.
- If you are using the Appcircle server with HTTP, then the port should be the external port of Redis which is `6379` by default. And the `ssl` argument should be set to `false`.
- For instance, `redis.appcircle.spacetech.com:6379,ssl=false`.
Create runner access token from appcircle server and register runner to server. See details in [here](/self-hosted-appcircle/self-hosted-runner/installation#2-register).
For example,
```bash
./ac-runner register -t aat_eev4NQdG_7F2jodmMShBFhh_DgabOJSsWSMojX5_lo4 -n runner1 -p macOS_pool
```
It won't print anything to CLI on success. You can also check its exit value with `echo $?`. It should be `0` on success.
Finally run below command to edit self-hosted runner configuration for pre-installed platforms.
```bash
echo "$(jq '.OsValues = ["ios","android"]' selfHosted.json)" > selfHosted.json
```
Start runner service.
```bash
./ac-runner service -c start
```
Now you should see "runner1" in "Build > Self-hosted Runners" list. It may take a couple of seconds to become online.
If "runner1" is online, we can shutdown VM since configuration is done with success.
```bash
sudo shutdown -h now
```
#### Configure Runner 2
As we configured the runner1 (vm01), we can clone vm01 to vm02.
So we won't need to reconfigure NTP settings, self-signed SSL certificates, or other configurations that we made for vm01.
Create VM image for runner2 from runner1.
```bash
tart clone vm01 vm02
```
Start runner2 image for configuration.
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro \
--disk=$HOME/images/xcode.26.3.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro
```
SSH login into running macOS VM.
```bash
ssh -o StrictHostKeyChecking=no appcircle@$(tart ip vm02)
```
After login, configuration steps for Appcircle runner service are the same as "runner1". So, we don't need to repeat same commands again.
The only difference should be runner naming. It must be unique. For the second runner, just give a different name. For example, "runner2".
Refer to the [Configure Runner Service](#4-configure-runner-service) for detailed Appcircle runner service configuration.
After shutdown, we're ready to run instances from `vm01` and `vm02` base VM images.
At this stage, your VM list returned by `tart list` might be like below, according to your preferred macOS VM image version.
```txt
Source Name Size
local macOS_240306 167
local vm01 130
local vm02 130
```
## Operating MacOS VMs
### Prerequisites
We need to create two seperate folders for two runners. These will be their working directories on runtime.
Create folder for "runner1".
```bash
mkdir $HOME/runner1
```
Create folder for "runner2".
```bash
mkdir $HOME/runner2
```
We have a simple bash script that will be used to run VM instances in loop.
Download the script into runner folders you created and make script executable.
For "runner1" use below commands.
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.3.0.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.2.0.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.1.0.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.9.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.8.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.7.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.6.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.5.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.4.sh && \
chmod u+x $HOME/runner1/run.sh
```
```bash
curl -L -o $HOME/runner1/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.3.sh && \
chmod u+x $HOME/runner1/run.sh
```
For "runner2" use below commands.
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.3.0.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.2.0.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.1.0.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.9.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.8.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.7.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.6.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.5.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.4.sh && \
chmod u+x $HOME/runner2/run.sh
```
```bash
curl -L -o $HOME/runner2/run.sh https://storage.googleapis.com/appcircle-dev-common/self-hosted/run-1.0.3.sh && \
chmod u+x $HOME/runner2/run.sh
```
:::caution
With new versions of the macOS VM image, we're also constantly updating the `run.sh` tool for fixes and improvements.
So, there might be a new version of `run.sh` that's compatible with the latest macOS VM image.
The above commands should be executed on every macOS VM image upgrade in order to get the latest `run.sh` version that's compatible with the latest macOS VM image.
:::
### Start VM
In order to start "runner1", use below command.
```bash
screen -d -m $HOME/runner1/run.sh vm01
```
It will start "runner1" in detached mode and will manage VM lifecycle continuously.
In a couple of minutes, you should see "runner1" as online in self-hosted runners list.
We can also start "runner2" with below command.
```bash
screen -d -m $HOME/runner2/run.sh vm02
```
In docker terminology, we're creating container from docker image at this stage. On build complete, runner will be shutdown automatically and `run.sh` will create a fresh one from macOS image. It continuously does the same operation until stopped.
We can see running instances on macOS host with `tart list`.
```txt
Source Name Size
local macOS_240306 167
local vm01 130
local vm01-4f496549-cfe8-462c-ba55-774f01c03b4f 130
local vm02 130
local vm02-9f1fc62a-f43c-40f3-98d0-523ed9a67042 130
```
As you can see in list, we have new VMs with long unique name. Those are actually online VMs that we started.
`vm01` and `vm02` are immutable VM images. On the other hand, others are instances created from VM images.
### Stop VM
In order to stop VM, we need to mark runner as stopped and shutdown online runner over SSH.
Touch `.stop` file at runner's working directory.
```bash
touch $HOME/runner1/.stop
```
Creating `.stop` file prevents creating new instance by `run.sh` on shutdown.
If runner is executing build pipeline, you may prefer waiting completion of the build job. See [stop](/self-hosted-appcircle/self-hosted-runner/configure-runner/runner-service#stop) section at self-hosted runner docs. When executing build pipeline completes, runner will be shutdown automatically.
On the other hand if you want to stop runner immediately for whatever reason or it's in idle state, you can SSH into runner and run shutdown command.
First you need to have to find out online runner's VM name from `tart list`.
```txt
Source Name Size
local macOS_240306 167
local vm01 130
local vm01-4f496549-cfe8-462c-ba55-774f01c03b4f 130
local vm02 130
local vm02-9f1fc62a-f43c-40f3-98d0-523ed9a67042 130
```
In above list, "vm01-4f496549-cfe8-462c-ba55-774f01c03b4f" is the name of runner that we will shutdown.
SSH login into that runner.
```bash
ssh -o StrictHostKeyChecking=no appcircle@$(tart ip vm01-4f496549-cfe8-462c-ba55-774f01c03b4f)
```
---
**Note:** You should use "cicd" as SSH login password.
---
Execute shutdown command.
```bash
sudo shutdown -h now
```
Shutdown process may take a couple of seconds.
After shutdown, you won't see anymore instance from `vm01` on `tart list`.
```txt
Source Name Size
local macOS_240306 167
local vm01 130
local vm02 130
local vm02-9f1fc62a-f43c-40f3-98d0-523ed9a67042 130
```
After a couple of minutes later, "runner1" will also become offline at self-hosted runners list.
Steps are also similar for "runner2". You need to touch `.stop` file in its working directory and after getting its VM name from `tart list`, you can shutdown "runner2" over SSH.
## Update Base Images
On some cases, you may need to update to your macOS base images in order to make your changes permanent.
Below are the ones that frequently occur, but not limited to them.
- Your team might use a tool frequently in build pipeline, that's not included in Appcircle macOS image. Installing that tool into the image once will save build time. Your build pipeline will be more efficient and optimized.
- You may prefer to get iOS and android tool updates by using [self-hosted runner update](/self-hosted-appcircle/self-hosted-runner/update) method instead of getting fresh macOS VM image. When you get fresh macOS image you may need to make your custom configurations again.
- You may need to make persistent proxy configuration for your internal network requirements.
- You may need to add your corporate's self-signed root CAs to macOS VM image in order to succeed SSL connections.
Steps, that we need to take, are technically similar as in [Create Base Images](#create-base-images) section. So, a conceptual overview of the steps will be sufficient.
- Stop all online runners as explained in [Stop VM](#stop-vm) section.
- Run `vm01` base image.
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro \
--disk=$HOME/images/xcode.26.3.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro
```
```bash
screen -d -m tart run vm01 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro
```
- SSH into `vm01`.
```bash
ssh -o StrictHostKeyChecking=no appcircle@$(tart ip vm01)
```
- Make your modifications, configurations or updates in macOS.
- Shutdown `vm01`.
- Run `vm02` base image.
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro \
--disk=$HOME/images/xcode.26.3.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro \
--disk=$HOME/images/xcode.26.2.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro \
--disk=$HOME/images/xcode.26.1.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro \
--disk=$HOME/images/xcode.26.0.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro \
--disk=$HOME/images/xcode.16.4.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro \
--disk=$HOME/images/xcode.16.3.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro \
--disk=$HOME/images/xcode.16.2.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro \
--disk=$HOME/images/xcode.16.0.dmg:ro \
--disk=$HOME/images/xcode.16.1.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro \
--disk=$HOME/images/xcode.15.4.dmg:ro
```
```bash
screen -d -m tart run vm02 --no-graphics \
--disk=$HOME/images/xcode.14.3.dmg:ro \
--disk=$HOME/images/xcode.15.0.dmg:ro \
--disk=$HOME/images/xcode.15.1.dmg:ro \
--disk=$HOME/images/xcode.15.2.dmg:ro \
--disk=$HOME/images/xcode.15.3.dmg:ro
```
- SSH into `vm02`.
```bash
ssh -o StrictHostKeyChecking=no appcircle@$(tart ip vm02)
```
- Make your modifications, configurations or updates in macOS.
- Shutdown `vm02`.
- Start offline runners as explained in [Start VM](#start-vm) section.
## Troubleshooting
### Tart list has runner instance in list but I can not SSH into the runner
Rarely your runner might hang or might become offline for some reason.
- You can get its IP with `tart ip` but might not connect.
- Although it's in `tart list` you might not get its IP.
- Detached `screen` session might be terminated because of an error.
You need to check your macOS host for possible system issues. (disk space, network connectivity, OS reboot etc.)
You can also check runner's working directory for any error that might happen at virtualization. (`stderr.log`, `stdout.log`)
In this case, you can make your runners operational again by following below steps.
1- Make sure detached screen session and all its child processes terminated for the runner.
For instance, you can find list of PIDs for "runner2" as seen below.
```bash
% ps aux | grep vm02 | grep -v grep
appcircle 35640 0.0 0.1 408653856 18320 s002 S+ 2:35PM 0:00.68 tart run vm02-3a003bce-a2ee-4ae7-9500-7754e181c314 --no-graphics
appcircle 35174 0.0 0.0 408628512 2352 s002 S+ 2:20PM 0:00.01 bash /Users/appcircle/runner2/run.sh vm02
root 35173 0.0 0.0 408515456 6848 s002 Ss+ 2:20PM 0:00.01 login -pflq appcircle /Users/appcircle/runner2/run.sh vm02
appcircle 35172 0.0 0.0 408654848 1264 ?? Ss 2:20PM 0:00.00 SCREEN -d -m /Users/appcircle/runner2/run.sh vm02
```
2- Make sure there is no active virtualization framework process for the runner.
For instance, you can filter like this.
```bash
% ps aux | grep -i virtualmachine | grep -v grep
appcircle 35641 0.3 31.9 503225216 10699872 ?? Ss 2:35PM 42:07.38 /System/Library/Frameworks/Virtualization.framework/Versions/A/XPCServices/com.apple.Virtualization.VirtualMachine.xpc/Contents/MacOS/com.apple.Virtualization.VirtualMachine
```
3- Make sure there is no instance for the runner at VM list. If exists, remove it.
For instance, we have an instance for "runner2" seen below.
```bash
% tart list
Source Name Size
local macOS_230309 187
local vm01 140
local vm02 140
local vm02-3a003bce-a2ee-4ae7-9500-7754e181c314 125
```
Remove dangling "runner2".
```bash
tart delete vm02-3a003bce-a2ee-4ae7-9500-7754e181c314
```
4- Start VM for the runner as usual by following steps at [start VM](#start-vm).
For instance, start "runner2" with command below.
```bash
screen -d -m $HOME/runner2/run.sh vm02
```
### I can SSH into runner but runner is offline at self-hosted runners list
In this case, you need to focus on self-hosted runner issues inside macOS VM (guest).
In order to be able to investigate root cause, you should learn the basics of self-hosted runner. Check our [online docs](/self-hosted-appcircle/self-hosted-runner) details.
- You can check your macOS guest for possible system issues. (disk space, network connectivity etc.)
- If you have custom proxy settings on macOS guest, check these settings.
- If you added custom root CAs to macOS guest, verify their validity for SSL connection errors.
- You can check runner launchd service and its logs. (`stdout.log`, `stderr.log`, `logs` etc.)
- You should check network access from self-hosted runner to server. (firewall, open ports etc.)
### Datetime I see in build logs is not correct
This case is related with broken datetime synchronization between runner and server.
Both server and runner should synchronize their times with relevant NTP services. Timezone difference is not important. Datetime must be correct in their timezones.
If runner doesn't have network access to an NTP server on the internet, you can also configure it to use your internal NTP server.
For updating macOS base image see [related section](#update-base-images) above.
For configuring NTP settings, see [Configure Base Runner's NTP Settings](#2-configure-base-runners-ntp-settings) section above.
### I am facing "SSL cert is not valid yet" error in our builds
This problem is again related to your macOS VM date and time being out of date.
To fix that, you should sync the VMs' date and time with your organization's NTP server.
For updating macOS base image see [related section](#update-base-images) above.
For configuring NTP settings, see [Configure Base Runner's NTP Settings](#2-configure-base-runners-ntp-settings) section above.
### Runners are offline and I noticed that macOS host has been reboot
If there is no system crash, one reason for an unintentional reboot may be caused by automatic updates.
We suggest disabling automatic updates on macOS host, and get them manually when required.
Below are the CLI commands to disable all automatic updates on macOS.
```bash
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticDownload -bool false
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CriticalUpdateInstall -int 0
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled -bool false
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates -int 0
sudo defaults write /Library/Preferences/com.apple.commerce AutoUpdate -int 0
```
### Runners are offline but when I SSH into host, it suddenly becomes online
When you install a fresh macOS on a mac device, it comes with predefined power settings which makes it energy efficient.
So, most probably, your macOS host sleeps when there is no UI interaction, and awakes on SSH login.
To do that, please configure your power settings on the host machine.
You can re-check the [Configure Power Settings](#4-configure-power-settings) title for power management on the host.
### I want to make some configurations to macOS base image but need desktop UI for them
If you're not comfortable with CLI, you can also make your customizations using macOS desktop.
For this purpose, remove `--no-graphics` argument from `tart run` commands.
Below step in [update base images](#update-base-images) section,
> 2- Run `vm01` base image. `screen -d -m tart run vm01 --no-graphics`
should be like this in this case.
> 2- Run `vm01` base image. `screen -d -m tart run vm01`
### Deleting Xcode simulator runtimes to create free disk space
Occasionally, you may need to manage disk space on your macOS base VM due to storage constraints or other reasons. One way to free up disk space is by deleting unused Xcode simulator runtimes.
To list the installed Xcode simulator runtimes, run the following command on your base VM:
```bash
xcrun simctl runtime list 2>/dev/null
```
If you determine that certain iOS, watchOS, tvOS or visionOS(xrOS) runtimes are not needed, you can delete them to free up disk space:
```bash
xcrun simctl runtime delete
```
:::caution
Xcode simulator runtimes are essential for testing and debugging iOS, watchOS, and tvOS applications on virtual devices. Deleting a runtime will prevent you from running or debugging an app on that specific device. Other simulators and runtimes will remain unaffected.
Be cautious when deleting Xcode simulator runtimes, as this action is irreversible. Removing a simulator runtime can impact the Xcode build process. For example, if you delete a watchOS runtime, you will no longer be able to build an iOS app that targets the deleted watchOS runtime. Ensure that the runtime you plan to delete is not required for your build pipeline.
:::
### Why do I have different build durations in the pipeline, especially when they run concurrently on the same Mac host?
As we mentioned earlier in the documentation, you can add more than one runner on the same Mac host and run build pipelines concurrently. You can configure their [CPU](#set-cpu-limits) and [memory](#set-memory-limits) resources as your needs and make different types of runner pools for different workloads.
Mac devices that have M-series chips (Apple silicon) have two types of CPU cores: E (efficiency) cores and P (performance) cores. For instance, an M1 Mac mini device has 4 E cores and 4 P cores.
You can see the number of cores and its distribution on your host using the command below:
```bash
system_profiler SPHardwareDataType
```
E (efficiency) cores are energy-efficient but slower cores that are significantly different than P (performance) cores. Apps cannot decide directly which cores they will be run on. For this reason, we cannot assign specific cores to our workload while configuring the macOS VM.
Under macOS lightweight virtualization, virtual machines (VMs) are allocated a number of virtual CPU cores, all of which are the same type. So, the virtual CPU cores in macOS VMs do not differentiate between the high-performance and high-efficiency cores of the host CPU. Instead, macOS VMs automatically alternate between these types of cores depending on the workload being executed within the virtual machines.
You can have two VMs running, and one can use all the performance cores and the other can use all the efficiency cores if the second workload is not CPU intensive. Or, they can share performance cores if both are CPU intensive, which results in some amount of workload being handled using efficiency cores for both of them, which will lead us to a 2x-3x slower build pipeline when they run concurrently.
:::tip
You can analyze the CPU consumption grouped by CPU clusters by running the command below on the macOS host.
```bash
sudo powermetrics -s cpu_power
```
:::
For this reason, if you need your build pipelines to be at peak performance in all conditions and do not want to see fluctuation in build pipeline durations, you should consider using one VM per one Mac device (host), especially for CPU-intensive CI workloads.
Using concurrency on the same Mac device (host) by configuring more than one VM will cause fluctuation in build pipeline durations. When one VM is idle, there will not be a significant degradation. But when both are in the "running" state, you can see significant divergence.
:::tip
#### Build Cache
When you hit the hardware barriers and try to find a way to improve build pipeline duration with existing runner configuration, you can consider using **[Build Cache](/workflows/common-workflow-steps/build-cache/cache-push)**.
Using **[build cache](/workflows/common-workflow-steps/build-cache/cache-push)** can optimize resource usage by reducing repetitive build tasks and reducing demand on CPU, memory, and bandwidth, which can result in significant performance improvement depending on your build workflow.
You can specifically cache the build and test outputs to minimize how much work is done in subsequent builds, which is expected to make the build pipeline more efficient, especially in repositories with frequent updates.
:::
---
## Upgrading Runner
# Update Self-hosted Runner
When a new version of self-hosted runner is released, you can update runner with below steps.
## 1. Update Runner
Download and extract the latest self-hosted runner package.
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-osx-arm64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-osx-arm64-1.8.5.zip
```
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-osx-x64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-osx-x64-1.8.5.zip
```
```bash
curl -O -L https://cdn.appcircle.io/self-hosted/runner/appcircle-runner-linux-x64-1.8.5.zip
```
Extract self-hosted runner package.
```bash
unzip -o -u appcircle-runner-linux-x64-1.8.5.zip
```
Change directory into extracted `appcircle-runner` folder for following steps.
```bash
cd appcircle-runner
```
## 2. Reconfigure Runner
Self-hosted runner updates may include tool upgrades or introduce new required tools for build pipeline. So we need to rerun configuration step same as before. It will check installed tools quickly, and will update only required tools.
To remember what configuration step was, please refer to [this](./installation#3-configure) page.
## 3. Reinstall Service
Although we change self-hosted runner files with above steps, we need to restart runner service in order to activate latest updates.
Some updates may also contain systemd or launchd service updates. For this reason, on every update, reinstalling service is suggested.
Reinstalling service also contains runner restart operations and doesn't affect self-hosted runner logs or produced artifacts.
In order to reinstall systemd or launchd service, first uninstall and then install service with below commands.
```bash
./ac-runner service -c uninstall
```
```bash
./ac-runner service -c install
```
:::info
When you complete update successfully, you will see updated **version** in "Self-hosted Runners" list in [here](./configure-runner/manage-runners#monitoring-self-hosted-runners).
```bash
./ac-runner --version
```
:::
---
## Android Keystores
You need to sign your Android applications with a keystore in order to install and test your application on virtual or real devices and submit your application to Google Play store.
Android keystores can be generated in Appcircle or pre-obtained keystores can be uploaded to use for signing Android applications. If you want to generate keystore in your machine, you can use [KeyStore Explorer](https://keystore-explorer.org).
### 1. Generate Android Keystores
You can create a keystore just by entering the necessary information. No additional software is needed.
### 2. Upload Android Keystore File
Upload your readily available keystore file along with the password(s).
:::info
Only files with .keystore extension can be uploaded.
:::
Builds with debug type will be signed with a default keystore and don't need a keystore file to be uploaded to Appcircle. If you are building your app for distribution, you need to upload your keystore file in order to have your application signed.
:::info Android Keystore Expiration Notifications
You will be notified when an Android Keystore is about to expire. You can see the expiration notification in the [in-app notification window](/account/my-account/in-app-notifications) and optionally enable expiration [notifications](/account/my-organization/notifications) for Email, Slack, Microsoft Teams, etc.
**Standard Schedule**: Keystores already in the system 30+ days before expiration receive notifications at 30, 15, 7, 3, 1 days before expiration, plus expiring today.
**Late Upload**: Keystores uploaded with less than 30 days remaining before expiration get notifications starting from upload day, then continuing with the next applicable intervals from the standard schedule.
:::
### In-Project Keystore Usage
You can alternatively have your signing details stored in your Gradle file and use your in-project keystore to sign your app.;
Go to build workflow editor and disable Sign Application step to use your keystore in your Gradle file.
:::info
[Have questions? Contact us here.](https://appcircle.io/support/)
:::
## FAQ
### What to Do if I Lost My Keystore (Signing File)
First, the keystore is essential for verifying app ownership and enabling updates on platforms like [Google Play](https://play.google.com/store/) or [Huawei AppGallery](https://consumer.huawei.com/tr/mobileservices/appgallery/).
If you have lost your keystore, here are the steps you can take:
#### Google Play:
The [Google Play Console](https://play.google.com/console/) can't restore a lost signing file, but it does let you reset it. To reset your signing file, follow these steps:
:::info
Only the account owner on Google Play Console can reset the signing file.
:::
1. Go to [Google Play Console](https://play.google.com/console/).
2. Select the app for which you want to reset the signing file.
3. Click the `App signing` under the `⚙️ Setup` section.
4. Scroll down and click the `Request upload key reset` button.
5. Choose `I lost my upload key`.
6. Generate a new upload key via [Appcircle](#1-generate-android-keystores) or [follow these instructions.](https://support.google.com/googleplay/android-developer/answer/9842756#create).
7. Export the upload key certificate as a PEM file using the provided command.
8. Upload the PEM file.
9. Click the `Request` button.
3. You’ll receive an email within a few days if your request is approved by the Google Play Console team.
:::tip
To cancel the reset request, click `Cancel Request` under the `Request upload key reset` header after step **9**.
:::
:::warning
> Resetting your upload key doesn’t affect the app signing key that Google Play uses to re-sign APKs before delivering them to users.
For more details, please check Google Play's documentation:
- [Lost or compromised upload key?](https://support.google.com/googleplay/android-developer/answer/9842756?hl=en-GB#lost)
:::
#### Huawei AppGallery:
Whether you can release the same app after losing the keystore on Huawei AppGallery depends on if you have previously used [Huawei App Signing Service](https://developer.huawei.com/consumer/en/doc/AppGallery-connect-Guides/agc-appsigning-newapp-0000001052418290).
- **Without App Signing Service:** You cannot update the app. You'll need either a new package name or a key change, which will require all users to reinstall the app.
- **With App Signing Service:** Your key is protected on the server. You only need to manage your upload key, and even if it's lost, you can still update the app without user impact.
---
## Apple Certificates
# Apple Certificates Overview
Certificate files can be in `.p12` file format as a private-public key pair. There are 2 main types of iOS certificates:
**1. Apple Development:** Used for development and testing.
The development certificates allow deploying apps to the developer devices (connected physically for testing and debugging) during the actual development process on Xcode.
The common practice is to generate this certificate automatically on Xcode, although manual generation is also available. Binaries built with a development certificate cannot be distributed.
**2. Apple Distribution:** Used for submitting applications to the App Store, or for Ad Hoc and Enterprise distribution. (Refer to the provisioning profiles section for the differences between these distribution types.)
In most cases, you will be using a distribution certificate with the combination of a provisioning profile to build and distribute apps in Appcircle.
There is a one-to-many relationship between certificates and provisioning profiles, so you may have multiple provisioning profiles associated with a single certificate.
:::info
For app builds, signing identities are not mandatory. For example, you can use unsigned apps to run on the simulator or on third-party platforms that resign your app, such as AWS Device Farm.
However, unsigned binaries cannot be installed on actual devices; therefore they cannot be used in the Appcircle Testing Distribution.
:::
You can obtain your developer certificates and provisioning profiles from the Apple Developer Portal:
[https://developer.apple.com/support/code-signing/](https://developer.apple.com/support/code-signing/)
## Using Appcircle Signing Identity module for Apple Certificates
### Creating an Apple Certificate
With Appcircle’s advanced Signing Identity module, you can easily generate certificates without logging into your Apple Developer account and securely store these certificates in `.P12` format within the Appcircle.
- To do this, navigate to the Apple Certificates section within the Signing Identity module. Then, using the Add New button, you can create a certificate.
- In the opened window, continue by selecting the “Create an Apple Certificate” step.
- Appcircle **requires** an **App Store Connect API Key** associated with your account to create a certificate. If the API Key is **not** added to your Appcircle organization, you **cannot** proceed with the certificate creation process. For more information, please refer to the [**App Store Connect API Key**](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key) documentation.
- After selecting the appropriate API Key, Appcircle requires a `CSR` (Certificate Signing Request) file to create an Apple certificate. With the option provided by Appcircle, you can select one created on Appcircle from the list. For more detailed information about the `CSR` creation process, please refer to the [**Generate Signing Request to Create Certificate**](/signing-identities/apple-certificates#creating-certificate-signing-request-file) section.
### Create Certificate with CSR File
If you want to create a certificate, you can proceed by using the **Select Certificate Signing Request from List** option.
When this option is selected, all existing `CSR` files in Appcircle will be listed, prompting you to choose one. After selecting the relevant `CSR` file, the desired certificate type must be chosen. **Optionally**, a password can be specified, or the **Auto Generate Password** feature can be used to generate one automatically. If you do not have `CSR` file, please refer to the [**Generate Signing Request to Create Certificate**](/signing-identities/apple-certificates#creating-certificate-signing-request-file) section.
:::caution Generating Password
Adding a password during `P12` export is completely **optional**. If you do **not** specify a password, the `P12` file will be created without one. However, if you prefer for automatic password generation, be sure to record the password generated by Appcircle. Otherwise, you may **encounter** issues when using the provisioning file.
:::
### Creating Certificate Signing Request File
The **Certificate Signing Request (CSR)** file is required by **Apple** when creating a certificate. This file allows the user to generate a certificate, so it must be created in advance and provided as needed. Since this file can only be generated on a `macOS` operating system, it is unlikely to be created on other systems. Therefore, you can **easily** generate a `CSR` file using Appcircle’s **Generate Signing Request to Create Certificates** feature.
By correctly filling in the required parameters such as **name**, **email**, and **country** you can generate this file without needing a `macOS` operating system.
:::caution Generating CSR File
It is **important** that the information provided is **accurate**. Any errors in these details may **prevent** Apple from allowing the certificate generation process.
:::
### Creating P12 File Without Mac
To generate your iOS certificates, simply fill in your details and Appcircle will provide a CSR (certificate signing request) which you can use on Apple Developer Portal to generate your signing certificate.
- Create a CSR File
- Download your CSR file
- Go to the Apple Developer Portal and select "Certificates, IDs & Profiles" from the left menu, then click on "Certificates."
- Select the type of certificate you want to create. If you want to distribute to TestFlight, Ad-hoc or AppStore, you should select Apple Distribution. If you're creating a certificate for local development environment, you should select Apple Development.
- Upload the CSR file you have created on Appcircle
- Download your generated CER file from the Apple Developer portal
- Upload the CER file to the signing identities module by clicking on the upload button next to the CSR file.
- Your CSR will now be converted to a P12 file as an iOS signing certificate. (Please note that the P12 file comes with an empty password.)
### Uploading P12 Certificate
To upload your Apple Certificate, select "Upload Certificate Bundle (.p12)" button and upload your pre-obtained Apple Certificate file.
You can see a list of your created or uploaded certificates. Each certificate will display the certificate name, certificate type (development, ad-hoc, in-house, or app store distribution) along with expiration dates.
:::caution
If your password contains special characters such as `$` and `#`, your workflow may fail with `MAC verification failed during PKCS12 import` message. If you receive such an error, please export your P12 file by removing that symbol.
:::
:::info Apple Certificate Expiration Notifications
You will be notified when an Apple Certificate is about to expire. You can see the expiration notification in the [in-app notification window](/account/my-account/in-app-notifications) and optionally enable expiration [notifications](/account/my-organization/notifications) for Email, Slack, Microsoft Teams, etc.
**Standard Schedule**: Certificates already in the system 30+ days before expiration receive notifications at 30, 15, 7, 3, 1 days before expiration, plus expiring today.
**Late Upload**: Certificates uploaded with less than 30 days remaining before expiration get notifications starting from upload day, then continuing with the next applicable intervals from the standard schedule.
:::
### Deleting a Certificate
To delete an Apple Certificate, click the ... button and select the **Delete** option.
:::info
Certificates deleted on **Appcircle** will only be removed from **Appcircle** and will not affect those on **Apple Developer** account.
:::
---
## Apple Devices
When it comes to developing and testing iOS apps, one of the most important tasks is registering your devices with the Apple Developer portal. This is necessary so that you can install your app on those devices for testing purposes. However, this process can be a bit tedious, especially if you need to register a large number of devices. That's where Appcircle comes in.
Ad-hoc distribution is a method of distributing iOS apps outside the App Store. To use Ad-hoc distribution, devices must be registered with the Apple Developer portal and included in your app's provisioning profile. Appcircle streamlines and simplifies this process, making it more efficient.
:::caution Apple Devices
Please note that Ad Hoc provisioning is intended solely for internal distribution and testing, and cannot be used for App Store submission or external distribution. The number of devices that can be registered in an Apple Developer account is **limited to 100 iOS devices**, which can only be reset once a year.
For more information, please visit [Apple Developer documentations](https://developer.apple.com/documentation/appstoreconnectapi/devices).
:::
## Adding Device
Appcircle's advanced Apple Devices feature simplifies device management. It allows you to fetch existing registered devices and add or register a device manually or via email.
To manage your devices, simply visit the relevant sections in the Apple Devices feature.
- **Registered Devices**: This section lists the devices registered to your Apple Developer Account using an API key.
- **Non-Registered Devices**: This section shows devices registered on Appcircle but not yet registered in your Apple Developer account. You can manually add a new device in this section.
- **Invited Users**: This section lists users who have received email invitations to provide device information. You can collect new device details via email.
:::caution Non-Registered Devices
In Appcircle's Apple Devices feature, when an invited user successfully completes the device UDID journey, the user's device UDID will be listed in the **Non-Registered** device list. However, if this user's UDID value **is already registered** in the **App Store Connect** account, it will not appear in the Non-Registered Devices list.
:::
Follow this document for detailed usage and purpose of all sections.
## Registered Device
In the **Registered Devices** section of Apple Devices, you can view the devices already registered in your Apple Developer account and synchronize them as needed.
:::caution Registered Devices
In order to list your registered devices, the App Store Connect API key must be added to Appcircle. Please follow the related [document](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key) to add App Store Connect API key.
:::
### Fetching Registered Devices
In order to be able to list the registered devices, you must first fetch these devices using the API key. For this, you can use the ‘Get Devices from Apple Developer Portal’ button to fetch the devices with the relevant API key.
Once the fetch process is completed successfully, the entire list of registered devices will be displayed below.
### Filtering Devices by Apple Developer Accounts
Since Appcircle's credential structure allows multiple API key connections at the same time, you can list your devices in different accounts with the account filtering feature on the registerd devices page.
### Filtering Devices by Device Status
Apple offers **Disable** and **Enable** options for registered devices. Disabling a device removes it from provisioning profiles and excludes it from the development process. Appcircle provides filtering options that allow you to filter devices based on their status, making it easier to manage enabled and disabled devices.
### Disable Device
Apple provides a disable option to exclude registered devices from development processes. To disable a registered device on Apple, select the relevant device, and use the **Disable** button at the bottom. This process will simultaneously change the status for the relevant device registered in your Apple Developer account.
:::caution Disable Device
Disabling this device will invalidate all associated provisioning profiles. You can remove this device from your account at the start of your new membership year.
:::
### Enable Device
Apple provides an enable option to include registered devices from development processes. To enable a registered device on Apple, select the relevant device, and use the **Enable** button at the bottom. This process will simultaneously change the status for the relevant device registered in your Apple Developer account.
### Registering Device to different Apple Developer Portal
A device that is already registered to any Apple Developer Account can be added to different Apple accounts if desired. To do this, select the device and then register it by choosing a different API key using the Register Device to Apple Developer button in the menu that appears at the bottom.
When you select different API key in the list, Appcircle will automatically register your device to selected Apple Developer Account.
### Device Information
When you click on any device UDID in the Registered Device list, you can find detailed information about that device. This information includes:
- The API keys to which the device is registered
- The available Provision Profiles associated with the device
- The device type
- The date the device was recorded
You can see it in detail.
## Not Registered Devices
With Appcircle's advanced Apple Devices feature, you can also add user devices manually.
### Adding Device Manually
With this feature, you can manually enter the UDID of the device you want to register and register it to your Appcircle Account. To do this, navigate to the Non-Registered tab and click the **Add Manually** button.
:::caution Manuel Added Devices
Please remember that manually added devices are not automatically registered to your Apple Developer Portal account.
:::
### Registering Device to Apple Developer Portal
After selecting a Non-Registered device, you can register it to your Apple account with the Register to Apple Developer Portal button at the bottom.
## Invited Users
In addition to manually adding devices to your Appcircle account, you can also invite users via email to share their device information. If a device is registered through the invitation sent, its UDID will appear in the **Non-Registered Devices** tab during the registration process.
:::info
Multiple devices can be registered using the link provided in the email invitation, and this process does not require any authentication method.
:::
To invite a user by e-mail, click **Invite User by Email** button, and specify the email address and invitation message.
The mail containing the e-mail invitation will look like this.
When you send an invitation to a user, the invitation will be listed in the **Invited Users** section. If the user has not taken any action, their status will appear as `Pending`. Once the user registers the device UDID, this status will change to `Registered`.
### Adding Device by Email
:::caution Edge Browser for Real Devices
Appcircle temporarily installs a verified profile on the device in order to get the UDID of the device via email. Thanks to this profile, the UDID value of the relevant device is saved in your Appcircle account.
Apple does **not** directly and officially support **Edge Browser**. Therefore, if you are using **Edge Browser**, this feature will **not** work as **expected**. Please use **Safari** instead.
:::
- When the link in the e-mail invitation is clicked, you will see a screen like below.
- Specify the device name and press the Register this Device button.
- Appcircle will prompt you to download a temporary profile to retrieve the device UDID. You must allow this action to proceed.
- Once this profile has been downloaded, go to the iPhone settings and install the downloaded profile.
- After the installation process is completed, you will be automatically redirected to the web portal containing your device information. When this screen comes up, you can see all the information about the device.
:::warning Lost/Stolen Device Protection Feature
Please note that if the relevant device has the **"Lost/Stolen Device Protection”** feature enabled, which is available on Apple's **iOS 17 and later** devices, profile install may only be possible after a 1-hour security delay.
For more information regarding the feature, please visit the [**Apple documentation**](https://support.apple.com/en-al/guide/iphone/iph17105538b/ios#:~:text=Security%20Delay%20helps%20prevent%20someone,find%20devices%20on%20iCloud.com).
:::
- After this step, the device UDID has been successfully registered in Appcircle. You can go to the Appcircle interface and see the relevant device in the Non-Registered Devices tab.
### Cancel Invitation
When an invitation is selected, you can delete this invitation by clicking the Delete button from the menu below. When the invitation is deleted, the link in the e-mail will become inactive and cannot be used again.
---
## Apple Identifiers
# Apple Identifiers Overview
The first requirement for publishing an application on the Apple App Store is to determine the unique identifier that identifies your application. For this reason, you must first register a BundleID. For more information, please refer to the [**Apple Documentation**](https://developer.apple.com/documentation/appstoreconnectapi/bundle_ids).
With the **Apple Identifiers** option in Appcircle's Signing Identities module, you can easily register a BundleID on the Apple Developer Portal or list your existing BundleIDs on Appcircle.
## Register Bundle Identifier
With the **Register Bundle Identifier** option, you can register a new BundleID on the Apple Developer portal using Appcircle.
You can specify the BundleID you wish to save, provide a description to identify this identifier, and select the capabilities you want it to have. Once you click the Save button, Appcircle will store this BundleID in your Apple Developer account.
:::info Register Bundle Identifier
When you register a BundleID, it will be created simultaneously in your Apple Developer account.
:::
- **Description**: A brief explanation to distinguish BundleID.
- **BundleID**: BundleID value to be saved.
- **Capabilities**: The capability values you want BundleID to have.
## Get Bundle Identifiers from Apple Developer
In this option, all currently registered BundleIDs are listed.
You can list your registered BundleIDs on Appcircle by making selections from this list.
After the registration process is completed, the selected or registered BundleIDs will be listed as follows.
## Edit BundleID
With the Actions button in the BundleID list, you can edit your existing BundleID content.
:::info Edit Bundle
The changes you make here will be modified **simultaneously** and saved in your Apple Developer account.
:::
In the Edit screen, you can see all the capabilitiy it has in BundleID and you can add or remove them if you wish.
## Delete BundleID
To delete a BundleID, click the ... button and select the **Delete** option.
:::info
BundleIDs deleted on **Appcircle** will only be removed from **Appcircle** and will not affect those on **Apple Developer** account.
:::
---
## Apple Profiles
# Apple Profiles Overview
Provisioning profiles can be in `.mobileprovision` file format. There are 4 main types of iOS certificates:
**1. Apple App Development:** Used to install development applications on test devices. This provisioning profile type is matched with a development certificate to enable app deployment during development. This is used mainly for debugging or functional testing.
**2. Ad Hoc:** Used for installing an application on a limited number of registered devices.
Ad Hoc profiles enable the installation of the binary on a specified device pool. This allows application testing on actual devices while limiting the app distribution to external parties by requiring all devices to be registered in the Apple Developer Portal to run any app signed by the Ad Hoc certificate of the same developer account.
There is a limit on the number of devices registered for Ad Hoc distribution and for the deployments with a development profile. This limit resets yearly.
For this purpose, you need to get the UDID information of your test devices, register them in the Apple Developer Portal, and then generate an Ad Hoc provisioning profile. You can then upload this file to the Appcircle Signing Identities module to be used in builds.
Please note that every time you add a new device, you have to regenerate the provisioning profile and reupload it to Appcircle. (Regeneration of the associated certificate is not necessary as long as it is valid.)
For more information on getting the UDID and registering it, please refer to the following Apple Developer guide. This guide walks you through all the steps necessary to get a device assigned to your Apple Developer account: [https://developer.apple.com/documentation/xcode/distributing-your-app-to-registered-devices](https://developer.apple.com/documentation/xcode/distributing-your-app-to-registered-devices)
You can use the Appcircle Testing Distribution to deploy apps built with an ad hoc profile. (If the receiving device is registered, of course.)
**3. App Store:** Used for submitting applications to the Apple App Store.
App Store profiles allow you to build store-ready versions of your app to be submitted to the App Store or to TestFlight. You can use the Appcircle Store Submit module to upload apps signed with an App Store profile to App Store Connect.
You cannot use the Appcircle Testing Distribution to deploy apps built with an App Store profile. (You can still share the binary but it cannot be installed on the target device.) The only valid target is for the apps signed with this profile is App Store Connect.
**4. Enterprise (In-House):** Used for in-house application distribution for the enterprises enrolled in the Apple Developer Enterprise Program.
This profile type is only available with the Apple Developer Enterprise program with strict requirements for registration. The apps signed with an enterprise profile can be installed freely on any device without going through the App Store or the Ad Hoc device registration.
The user will only be displayed a trust warning for the first time they are running an app signed with a specific enterprise certificate and then the app can be run just like an app downloaded from the App Store.
There are certain limitations that are mandated by the Apple Developer Enterprise program agreement such as the apps can only be used for work purposes by the actual employees of the enterprise, so it's not a free-for-all certificate to bypass the App Store processes. Apple reserves the right to revoke your certificate at any time in case of a violation.
You can use the Appcircle Testing Distribution or the Enterprise App Store module to deploy apps built with an enterprise profile to any device.
There is no need for device registration, but Apple requires the binary to be protected and not open for public download, so you can use the enrollment feature of the Appcircle Testing Distribution to protect the app distribution.
:::caution Apple Enterprise Signing
If you are **not** enrolled in the **Apple Enterprise Program**, you **cannot** create an **Enterprise** certificate. This limitation is **not** caused by **Appcircle**. Appcircle only provides signing and distribution features and **cannot** be used as an **enterprise signing service**.
:::
:::info
For app builds, signing identities are not mandatory. For example, you can use unsigned apps to run on the simulator or on third-party platforms that resign your app, such as AWS Device Farm.
However, unsigned binaries cannot be installed on actual devices; therefore they cannot be used in the Appcircle Testing Distribution.
:::
You can obtain your developer certificates and provisioning profiles from the Apple Developer Portal:
[https://developer.apple.com/support/code-signing/](https://developer.apple.com/support/code-signing/)
## Using Appcircle Signing Identity module for Apple Profiles
To register, upload or fetch your Apple Profiles, select **Apple Profiles** from the signing module.
### Register a New Provisioning Profile
**Prerequisite**: To register a new provision profile in your Apple Developer Account, you need to add an App Store Connect API Key. Visit the link below for instructions.
Adding an App Store Connect API Key
With Appcircle's register provisionn feature, you can easily create a new provision profile on the Apple Developer portal using the App ID of your choice.
:::info Registering Provision Profile
The provision profile you register via Appcircle is simultaneously registered on the Apple Developer portal.
:::
In order to register a profile, some parameters are needed.
After selecting the distribution method, the relevant App ID is selected for which Bundle ID will be created. Then you need to select which certificate you want to create with.
:::info
The certificates that need to be selected when registering a profile are listed by retrieving certificates from your **Apple Developer** account. The certificates listed here are **not** related to the ones uploaded to **Appcircle**.
:::
#### Device Registration
If you have selected Ad-hoc or Development as distribution method, you need to select a device to be added to the provision profile in the next screen.
### Get Provisioning Profiles from Apple Developer
**Prerequisite**: To list all the signing identities saved in your Apple Developer Account, you need to add an App Store Connect API Key. Visit the link below for instructions.
Adding an App Store Connect API Key
When you go to add a new Provisioning Profile, you'll see the option **Get Provisioning Profiles from App Store Connect**. Select it to see the list of identities fetched from Apple.
You can select to download the provisioning profile from the list. **If you don't want Appcircle to keep the provisioning profile**, you can make our build agents to keep a reference. This way, our agents will fetch the profiles **before every build and dismiss them** when the build is finalized.
You can select the profiles you want to download from the list and fetch them to your Appcircle environment with the download button.
### Upload a Provisioning Profiles
Simply upload your provisioning profiles obtained from the Apple Developer portal.
:::info
Provisioning profile and certificate matching will be done automatically. You can also have multiple provisioning profiles to use in different applications with different Apple developer accounts.
:::
:::tip
You can upload multiple Provisioning Profile files at once.
:::
You can list and manage your provisioning profiles here. Newly uploaded files will display with a blue-colored background. If there is a matching certificate, the profile will show a green check mark. If not, you will see a red cross mark indicating there is no certificate matching the provisioning profile.
You can also see the matching application ID and expiration date of the profiles here.
:::info Apple Profile Expiration Notifications
You will be notified when a provisioning profile is about to expire. You can see the expiration notification in the [in-app notification window](/account/my-account/in-app-notifications) and optionally enable expiration [notifications](/account/my-organization/notifications) for Email, Slack, Microsoft Teams, etc.
**Standard Schedule**: Profiles already in the system 30+ days before expiration receive notifications at 30, 15, 7, 3, 1 days before expiration, plus expiring today.
**Late Upload**: Profiles uploaded with less than 30 days remaining before expiration get notifications starting from upload day, then continuing with the next applicable intervals from the standard schedule.
:::
### Deleting Provisioning Profiles
You can delete a single Provisioning Profile or multiple ones by selecting the checkboxes next to the provisioning profiles. You can also select the checkbox at the top of the list to select all available ones. Once you select the checkboxes for the files you need, a delete button will appear at the top right corner.
If you attempt to delete a Provisioning Profile that is saved in a build configuration of an active Build Profile, a warning message will appear. This message will allow you to view the affected build profiles and navigate to their configuration screens to make necessary changes.
You also have the option to force delete it without changing the configurations.
:::info
Profiles deleted on **Appcircle** will only be removed from **Appcircle** and will not affect those on **Apple Developer** account.
:::
:::caution
Affected build profiles will not be displayed within the warning message if you delete multiple Provisioning Profiles.
:::
### Profile Actions
You can access different Actions for existing provisions within 3 points in the area where the provisions are listed on the Appcircle.
- **Renew**: Renews provisioning that has expired or become out of date
- **Apple Devices**: Lists the device UDIDs registered in the provision
- **Download**: Downloads the selected provisioning
:::danger Renew
The Renew function only applies to provisions that have been **registered** with Appcircle or **fetched** via the Apple Developer portal.
You **cannot** renew **manually uploaded provisioning**.
:::
:::info Renewed Profiles
If a provision profile is used in a Build Profile, it will continue to be used with the renewed version after the profile is renewed.
:::
### Adding Device to Provision Profile
With Appcircle’s Apple Profiles feature, you can easily add the UDIDs of your test devices to the corresponding provisioning profile.
To manage devices and view the current device list, click the **Profile Action** button and navigate to the **Apple Devices** section.
When you click the **Apple Devices** action, you will see a list of devices currently included in the **selected** provisioning profile. In the modal that opens, you can update this list by clicking the **Manage Devices** button.
After clicking the Manage Devices button, you will see two different lists.
The **Existing Devices** list displays the device **UDIDs** currently included in the **selected** provisioning profile. You can remove a device from the provisioning profile by unchecking its checkbox in this list.
Below this, there is the **Non-Existing Devices** list. This list shows the devices that are **registered** in your **Apple Developer Portal** account but are not **included** in the provisioning profile. To add a new device **UDID** to the provisioning profile, select the desired device from this list and proceed.
:::caution Minimum Device Count
According to **Apple’s Developer Portal** rules, a provisioning profile must include at least **one** device. Therefore, you cannot **remove** all devices from a provisioning profile.
:::
After selecting the devices, you will see a final **Preview** screen. This screen displays the updated device list that will be included in the provisioning profile. You can update the devices in the provisioning profile by clicking the **Update Profile** button.
When the profile update is successfully completed, the updated version of the selected provisioning profile will be displayed in the Apple Profiles list.
:::info Updated Provision Profile
When a provisioning profile is updated, Appcircle replaces the old profile with a new one under a different name. The new name includes the update date and time.
:::
### Assign signing identities in the Build module for distribution
For both iOS or Android build projects, you need to assign your signing identities to your build profile for distribution. The distribution-ready binaries will be signed with the selected signing identities both in manual and automatic distribution cases.
You can sign your application either with automatic signing or with manual signing.
## Automatic Signing
Automatic signing allows you to sign your application without uploading any provisioning profiles. Profile creation is done automatically by Xcode. Following prequisites must be met for automatic signing to work:
- Project must be built with Xcode 13 or higher.
- Both Developer and Distribution certificates must be added to Appcircle.
- App Store Connect Key must be added to Appcircle.
You must also select distribution type from the dropdown menu. If you're uploading your app to App Store or TestFlight, you should select **App Store**. If you're uploading your app to Adhoc or Appcircle's distribution module, you should select **Adhoc**. Please check [Apple's documentation](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles) for more details.
:::danger
If you don't upload developer and distribution certificates, Xcode will create new certificates each time you start a build. Since you don't have the private keys, you will not be able to use those certificates later on. If you don't want to clutter your account with unused certificates, you must upload both developer and distribution certificates.
:::
## Manual Signing
You can also select bundle identifier and provisioning profile to sign your application.
:::danger
If your app has multiple targets such as watchOS, Widgets etc, you need to add all the provisioning profiles for every bundle id. Click **+** button and add related bundle id and provisioning profile.
:::
:::info
[Have questions? Contact us here.](https://appcircle.io/support/)
:::
---
## Signing Identities
The Signing Identities section is essential for configuring the credentials required to sign your iOS and Android applications. It's where you can manage and store your signing certificates for iOS and your keystores for Android.
:::tip Learn More
For a complete overview of the Signing Identities module capabilities, check out the [Appcircle's Signing Identities Section](https://appcircle.io/signing-identities).
:::
## [Apple Certificates](/signing-identities/apple-certificates)
Manage your Apple Certificates by adding and storing your Apple Certificates and other related details required for signing iOS applications.
Apple Certificates
## [Apple Identifiers](/signing-identities/apple-identifiers)
Register and Manage your Apple Identifiers by adding and storing your Apple Identifiers and other related details required for signing iOS applications.
Apple Identifiers
## [Apple Devices](/signing-identities/apple-devices)
When it comes to developing and testing iOS apps, one of the most important tasks is registering your devices with the Apple Developer portal. This is necessary so that you can install your app on those devices for testing purposes. However, this process can be a bit tedious, especially if you need to register a large number of devices. That's where Appcircle comes in.
Apple Devices
## [Apple Profiles](/signing-identities/apple-profiles)
Register and Manage your Apple Profiles by adding and storing your Apple Profiles and other related details required for signing iOS applications.
Apple Profiles
## [Android Keystores](/signing-identities/android-keystores)
Keep your Android app signing keys secure by managing your keystores. This part of the documentation helps you understand keystore creation, management, and usage within your Android build processes.
Android Keystores
## [Signing Reports](/signing-identities/signing-reports)
The Signing Reports section contains the list of builds selected for signing in a given time period.
Signing Reports
## [Activity Log](/signing-identities/signing-identities-activity-log)
You can view Signing Identity module actions such as creating, deleting, and adding Apple Certificates or Android Keystores to Organizations or Sub Organizations in the Activity Log section.
Activity Log
---
## Activity Log
You can view Signing Identity module actions such as creating, deleting, and adding Apple Certificates or Android Keystores to Organizations or Sub Organizations in the Activity Log section.
Here is the full list of actions that can be monitored:
- P12 Added
- Csr Generated
- Certificate Uploaded
- Certificate Will Expire
- Certificate Downloaded
- Certificate Deleted
- Provisioning Profile Deleted
- Provisioning Profile Added
- Provisioning Profile Renewed
- Provisioning Profile Downloaded
- Provisioning Profile Will Expire
- Keystore Created
- Keystore Uploaded
- Keystore Deleted
- Keystore Downloaded
- Keystore Will Expire
- App Store BundleIdentifier Created
- App Store BundleIdentifier Deleted
- App Store BundleIdentifier Created In App Store
- App Store BundleIdentifier Updated In App Store
- Tester Devices Added
- Tester Device Deleted
- Tester Device Invitation Deleted
- Device Provisioned
- Device Provision Failed
- Device Registration Link Sent
- Device Registered
- Multiple Devices Registered
- Multiple Device Registration Failed
- App Store Authentication Failed
- App Store Device Synced
- App Store Device Sync Cancelled
- Add Multiple Devices To App Store Request
- Apple Device Updated
- Apple Device Update Failed
- Apple Multiple Device Updated
- Apple Multiple Device Update Failed
:::caution
Only Organization / Sub-Organization Owners and users with Organization Management Role will have access to this area.
Information about other Organizations and their Sub-Organizations will not be accessible without the required level of clearance.
:::
:::info
Organization Owners can also observe the actions of their Sub-Organizations.
:::
You can edit the required date range by clicking the time filter in the top filter header as the default search time option is the last 30 days. Alternatively, you can choose custom dates from the calendar by selecting 'In Between' option.
Team activity logs also include filters to help users perform more precise searches. By clicking the 'All' option next to Organizations, you can select a specific organization or sub-organization from the list, provided you have access to monitor their signing identities activity.
Another method to search is by **Actions**. Simply click the filter option and select **Actions**. Then you can choose a specific action to refine your search.
---
## Signing Reports
This report is accessible from the Signing Identities module.
The Signing Reports section contains the list of builds selected for signing in a given time period.
Each signed build is listed with the utilized provisioning profile name for iOS and the utilized keystore name for Android, along with their build status.
Since the primary objective of this report is to provide visibility on who used which signing identity and when this report includes all builds that consumed a signing identity from the centralized Signing Identities module regardless of the status of the build or the signing operation. (e.g. if the build failed for some reason or if the signing identity is incompatible with the selected project)
The date and time are displayed in the current timezone.
You can filter the report pages according to the organization.
:::info
In the filtering options, you can only view and select the organization and sub-organization you belong to.
:::
---
## Distribution Profile
In order to share your builds with testers, you can create distribution profiles and assign testing groups to the distribution profiles.
> Note that an empty Testing Distribution profile named **Send to Myself** will be created automatically for you.
:::info
A distribution profile corresponds to the multiple versions of the same application for iOS and Android. You do not need to create multiple Testing Distribution profiles for iOS and Android applications of the same application.
:::
:::caution Signing Binary
Appcircle's Testing Distribution module allows you to distribute your application without the need for any external tools. However, the way your app is signed remains your responsibility and depends on your own workflows; therefore, if you are not enrolled in the Apple Enterprise Program, Appcircle will not provide an enterprise signing service.
:::
## Creating a Profile
Select the Testing Distribution from the left and click on the Add New button. Give a name to your distribution profile.
:::info
As a best practice, we recommend using one single distribution profile for both iOS and Android versions of the same application.
:::
### Profile Actions
#### Rename a Distribution Profile
The Distribution Profile can be renamed by following these steps:
- Click on the three dot on the top right of the profile menu.
- Click `Rename`.
- Enter the new name for your profile.
#### Pin a Distribution Profile
The Distribution Profile can be pinned by following these steps:
- Click on the three dot on the top right of the profile menu.
- Click `Pin Item`.
Pinned profiles will stand out by appearing first in the list, making them easily accessible and distinguishable from the rest of the profiles. A pin icon will also be displayed on their profile card.
#### Delete a Distribution Profile
To remove clutter and/or free up storage, an entire profile can be deleted with a single click:
- Click on the three dot on the top right of the profile menu.
- Click `Delete`.
- Go through the confirmation dialog.
:::info
To free up space, other references pointing to the artifact should also be removed. For example, if the same artifact is present in the builds, those artifacts should also be deleted.
:::
## Uploading Binary
### Manual Binary Upload
Pre-built iOS or Android applications can be uploaded for distribution by clicking the "**Upload Binary**" button at the top right corner.
After the file is uploaded, it is checked for errors and parsed for metadata. Any errors that occur will be displayed in the upload area.
Once the upload is complete, the new version will be added to the top of the list with parsed metadata. This version can then be shared with testers or previewed on a virtual device in the browser.
:::info
Please note that iOS and Android binaries are displayed in separate tabs. The required OS tab should be clicked to navigate between them.
:::
### Upload via Build Module
With a successful build, a new version of the application will be added to the distribution profile.
Simply go to _Build Module_ _>_ _Build Configuration_ _>_ _Distribution_ and select a distribution profile you want your build to be sent.
:::tip
The Android build output can be selected as .AAB (Android App Bundle) from the configuration settings within the Build profile.
When the `.AAB` build is sent to the designated Testing Distribution profile, either automatically or manually by uploading the file directly within the Testing Distribution profile, it will be automatically converted to `.APK` format when shared with a Testing Group. This ensures that the `.APK` format is used for the artifact downloaded by the receiving tester.
This conversion capability also applies when app versions are sent from a Testing Distribution profile to an [Enterprise App Store](/enterprise-app-store) profile. The shared `.AAB` artifact will be converted and downloaded in `.APK` format from the Enterprise App Store profile.
:::
:::caution
Only signed builds will be distributed. Unsigned builds will not be distributed.
:::
#### Android applications with multiple flavors
For detailed information about multiple flavors, refer to this documentation:
Building Multiple Apps in One Profile
If multiple product flavors are present in your Android application, a build will be created for each flavor, allowing for simultaneous distribution. A common use case for multi-flavor applications includes offering free and paid versions of the same application.
When an application with multiple flavors is built and distributed, an `.apk` file will be created for each flavor. Once distributed, all of the binaries will be visible on the distribution profile
#### How to see the multiple flavor results
If you also want to download or see the output, you can check through the following steps within the Build Profile:
- Click the three dot under the actions tab
- Click **Download Artifacts** to see all the build outputs.
:::info
If your Git commit has any messages, they will be included in the distribution in Message To Testers area.
:::
### Upload using API & CLI
If you use your own CI structre, you can use our Appcircle API & CLI to upload binaries to your Distribution Profile.
To get more information, please refer to our [API & CLI](/appcircle-api-and-cli) documentation.
## Settings
The settings of your distribution profile can be customized. Click on the three dot (...) option on the top right corner, then click the settings button within the profile.
### Config
The Config tab allows you to modify binary related settings for your distributed applications.
#### Bundle/Package Identifier Validation
You can enforce identifier validation to ensure consistency and prevent mismatches between uploaded binaries and profile settings:
- **Bundle Validation for iOS**: When enabled, this option restricts uploads to only those iOS binaries that exactly match the bundle identifier specified in the profile. This ensures that only binaries from the intended iOS application are accepted.
- **Package Validation for Android**: When enabled, this option restricts uploads to only those Android binaries that exactly match the package identifier specified in the profile. This ensures that only binaries from the intended Android application are accepted.
:::caution Binary comes from Build Module
When you want to send a binary to a Testing Distribution profile with `Bundle/Package` validation via Build module, Appcircle allows this profile to be selected in the build configuration, but if the identifier of the binary from the build module **does not match** the one specified in the **Testing Distribution** profile, you will get an **error**.
For more detailed information about automatic distribution, please visit the Distribution Configuration [documentation](/build/build-process-management/configurations#distribution-configuration).
:::
When either validation is active, binaries with mismatching identifiers will be rejected during upload.
:::info Locked Identifier Behavior
When **Bundle/Package Identifier Validation** is enabled, the profile header will display a **Locked** tag next to the configured bundle or package identifier. This indicates that the profile is now restricted and will only accept binaries that match the identifier defined in the profile settings.
This validation does **not** apply retroactively to existing binaries already uploaded to the profile. Previously uploaded binaries with a different bundle or package identifier will remain accessible and can still be shared with testers. However, all **new uploads must match the locked identifier**, otherwise they will be rejected during upload.
:::
### Auto Send
Auto send feature lets your applications be distributed to specific testing groups whenever a new version is deployed, whether the deployment is triggered via a build process, CLI, or manual upload.
To enable the auto send feature, you need to create testing groups and add testers to these groups.
Testing Groups
Under the Auto Send tab in the settings, you can see the testing groups you have created earlier. Just enable each testing group you want to have your application sent automatically whenever a new version is deployed.
The first section allows you to share the deployed binaries automatically with the selected groups. They will receive a link to download the specific version on their mobile devices.
Your application will be sent to the related testing groups as soon as your build is complete, or when a package is manually uploaded or deployed via CLI.
#### Show Only the Shared Version to the Tester
When the “Show Only the Shared Version to Tester” toggle is enabled, receiving-end testers will only be able to access the most recently uploaded binary version within the Testing Portal, provided that the Auto-Send feature is enabled.
:::info
When this option is enabled, testers will not have access to the search bar or shared testing distribution profiles within the Testing Portal, as they will only receive the latest shared version.
:::
### Testing Portal
Testing Portal tab allows you to modify the settings related to the Portal visuals and configurations as your binaries are displayed.
You can submit your **Publisher Name**, **Contact Email**, **Privacy Policy URL**, and **Terms of Service URL**.
Once you click the save button, the information you have provided will be displayed on the Tester Portal.
Tester Portal
When the tester selects the user icon, the Publisher Information will be displayed.
It will also display the Login Method for the Testing Distribution Profile.
In the example image, the profile has static authentication method, so it is displayed as Static Login.
#### Exclude from Shared Application List
The Exclude from Shared Application List toggle allows you to exclude a Testing Distribution Profile and its associated binaries from appearing in the shared profile list on the Testing Portal. This is useful for limiting visibility of internal or early-stage builds while still enabling targeted distribution.
- When enabled, the profile will not be displayed in the shared list visible to testers browsing the portal.
- However, testers who received a direct email invitation to the profile will still be able to access and download the binary.
#### Hide Shared Application List
You can restrict access to the shared application list within the Testing Portal by enabling the **Hide Shared Application List** toggle from your Testing Distribution profile.
**When enabled:**
- The **Shared Application List** will be **hidden** for users accessing the Testing Portal.
- This restriction **applies** regardless of the **selected authentication type** (None, SSO Login, LDAP Login, or Static Username and Password).
- Testers will **only** see the application(s) associated with the specific distribution profile and will **not** be able to browse shared releases from other profiles.
#### Single Active Session
When the **Single Active Session** toggle is enabled, each user can have only one active session at a time across all browsers and devices within the Testing Portal.
- If the same user signs in from another browser or device, the previous active session is automatically terminated.
- This helps prevent simultaneous logins with the same account and improves overall account security.
If the toggle is disabled, users can sign in from multiple browsers or devices at the same time without terminating existing sessions.
:::warning Single Active Session Compatibility
The **Single Active Session** feature supports all valid authentication types: **SSO**, **Static**, and **LDAP**.
This feature is **not** applicable when the authentication type is set to **None (No Authentication)**.
:::
#### Binary Tags
The Binary Tags feature allows you to label your application binaries with meaningful metadata, which is displayed on the Testing Portal for easy identification by testers.
These tags help testers understand each binary's origin, purpose, and how it was triggered. The available tags are:
- Commit ID
- Commit Hash
- Commit Message
- Commit Author
- Git Source Branch
- Trigger Reason
- Git Target Branch
- Git Tag
- Trigger User
- Build Profile ID
- Workflow Name
- Configuration Name
:::info Build Module Dependency
This section appears only if the binary is distributed to the Testing Distribution profile from the Build Module.
Uploaded binaries without metadata from a build module won’t show the selected tags on the Testing Portal.
:::
Binary tags can be managed through the Testing Distribution Profile Settings under the Info tab:
1. Navigate to **Testing Distribution** module.
2. Select the relevant distribution profile.
3. Click the **Settings** icon.
4. Under the **Info** tab, locate the **Binary Tags** section.
5. Use the “Add a new tag” field to enter or select tags.
6. Click **Save** to apply changes.
Once tags are saved in the profile settings:
- Tags will automatically appear next to the app version on the Testing Portal after being distributed.
This visibility allows testers to filter and select the appropriate version for testing based on context.
### Authentication
Under the Authentication tab in the settings, you can select a preferred authentication method for sharing your application. This will be the login method for the [Testing Portal](/testing-distribution/testing-portal).
- **None**: No authentication, anyone with the link can download binary files
- **Static Username and Password**: One single username and password for all testers
- **SSO Login**: SSO login for all testers (Enterprise accounts only)
- **LDAP Login**: LDAP login for all testers (Enterprise accounts only)
To add your SSO and LDAP details, go to [My Organization](/account/my-organization) Security screen and press the "Connect" button next to SSO Login or LDAP Login under the "Authentications" section.
SSO LoginLDAP Login
:::info
If SSO and LDAP details are not configured for your organization, these authentication methods will not be visible in the Distribution Profile settings.
:::
### Distribution Link
You may enable a link for your distribution. This allows anyone who has the link to access all artifacts of the distribution profile. Additionally, users can now conveniently scan a QR code to retrieve the distribution link directly. This simplifies the process of accessing and sharing the distribution link, making it more accessible for users on mobile devices or others who prefer quick scanning.
:::info
The Tester Portal that you will have access via the Distribution Link, will have the same authentication method that you have set from the authentication settings.
:::
## Share Binary
### Share your application with the test groups manually
Once your build is ready or the binary file is uploaded to Appcircle, the file can be manually sent to testers for downloading, installing on their devices, and running the application for testing purposes.
Click on the 'Share with Testers' button, and the [testing groups](/testing-distribution/testing-groups) previously created can be selected to receive this version of your application. Alternatively, email addresses of testers can be entered here to send the application directly, bypassing the testing groups.
You can also add a message to testers including testing instructions and release notes.
You can automate this message using [Release Notes Component](https://github.com/appcircleio/appcircle-release-notes-component/). You can enrich the contents of your release notes with environment variables or Ruby snippets. The following default template will print the branch name, commit hash and commit message.
```ruby
Branch: $AC_GIT_BRANCH
Commit Hash: <%= ENV['AC_GIT_COMMIT'][0..6] %>
Commit Message: $AC_COMMIT_MESSAGE
```
:::info
If you are using the self-hosted version of Appcircle, you can configure it to use your own business domain for distribution emails instead of the default noreply@appcircle.io address. For details on how to configure SMTP settings in a self-hosted installation see [Email Integration](https://docs.appcircle.io/self-hosted-appcircle/configure-server/integrations-and-access/integration#email).
:::
The Distribution Profile name will be displayed as the sender name in the email address that testers will receive.
:::tip
After sharing your app versions with testers, the most recent sharing time will be displayed on your testing distribution profile card.
:::
### Tracking your distribution
After sending your application to testing groups, you can track the actions of testers:
- **Pending** - Means your tester didn't click on the link they received yet.
- **Clicked** - Means your tester clicked on the link they received but has not logged in to the system yet (only for authenticated distributions).
- **Login, No Download** - Means your tester has logged in (for authenticated distributions) and at the download screen but has not downloaded the binary file yet.
- **Downloaded** - Means your tester clicked and downloaded the binary file.
## Binary Actions
### Binary Information
1. Select the binary.
You can select the files from the list.
2. Click the **...** button and select **Binary Information**.
3. This window provides information about your binary, including the provisioning profile type, certificate name, and build details, such as the branch and logs.
#### Build Metadata Details
The following metadata is displayed in the Binary Information section of a Testing Distribution Profile only when the binary is generated via the Build Module, either through automatic or manual triggers, and subsequently distributed using Auto Distribution to the Testing Distribution module.
- **Trigger Type**: Indicates what initiated the build. Possible values include:
1. Pull Request: The build was triggered by the creation or update of a pull request.
2. User: A build was manually triggered by a user.
3. Commit: A new commit triggered the build automatically.
4. Tag: The build was initiated when a new Git tag was pushed to the repository.
- **Branch Name**: The source branch used during the build process.
- **Target Branch**: Typically used in pull request or merge-based triggers, this is the destination branch for the pull request or merge target.
- **Git Tag**: If the trigger type is Tag, this field shows the tag that initiated the build.
- **Triggered Internal User**: Displays the email address of the internal user who triggered the build or the user responsible for the action.
- **Workflow Name**: The name of the workflow profile name executed during the build process (e.g., Default Push Workflow).
- **Config Name**: Indicates the configuration profile name used within the selected workflow (e.g., Default Configuration).
#### Binary Comparison
In the top-right corner of the Binary Information screen, you can click the **Compare** button to compare the current binary with another of your choice. The comparison highlights differences between the two binaries using color-coded indicators for easy identification.
:::caution Build Details Comparison
Binaries generated through the Appcircle Build Module include associated build details. **However**, if the compared binary was **manually** uploaded to Appcircle, those details **will not be available** for comparison.
:::
### Send your application to Enterprise App Store
You can send your application from your Testing Distribution profile to an Enterprise App Store profile by following these steps:
- Click the three dots next to your application.
- Click **Send to Enterprise App Store**.
- Click **Send**.
:::info
Appcircle will not ask you to pick a profile after choosing the **Send to Enterprise App Store** option. If the binary is unique, it will create the Enterprise App Store profile automatically. If the same app version already exists within the profiles, it will be delivered within that profile.
:::
### Send your application to Publish
You can send your application from your Testing Distribution profile to a designated Publish profile by following these steps:
- Click the three dots next to your application.
- Click **Send to Publish**.
- Choose your Publish profile from the list.
- Click **Send**.
:::caution
You must have already created the designated Publish profile within the Publish Module, and it should correspond to the operating system of your application (Android or iOS) listed in your Testing Distribution Profile.
:::
### Re-sign Binary
Resigning is the process of modifying an existing binary with a new signing certificate or keystore, which is required when an application needs to be published under a different developer account or when updating an existing application. It involves removing the original signature and replacing it with a new one.
For more information please visit the [Re-sign Binary](/testing-distribution/resigning-binaries) documentation.
### Re-sign History
Re-sign History allows you to view the re-sign process logs for your app versions. For more information, please visit [Re-sign History](/testing-distribution/resigning-binaries#re-sign-history) documentation.
### Download Binary
The binary file in the Testing Distribution profile can be downloaded by selecting the Download button from the actions menu.
### Delete Multiple Testing Distribution App Versions
If you don't want to delete an entire distribution profile but free up the past distributions, you can also remove multiple entries.
Click on the `Edit` Text to toggle edit mode:
On edit mode, you will be able to select multiple entries. Select the versions you wish to delete, and click on the `Delete` Text on the top right of the versions:
### Delete a Single Distribution App Version
As an alternative method to bulk deleting versions, you can delete a single version by selecting the three-dot menu next to the app version and then clicking **delete** button.
After clicking `Delete` , type in the version name in the prompt.
## FAQ
### No files or multiple files were received from autodistribute;
A successful distribution depends on a correctly signed binary. Please check if the [signing configuration](/build/build-process-management/configurations#signing-configuration) is correct.
You can also check the list of the [generated build artifacts](/build/build-process-management#binary-actions) to confirm the output. In Android, you can also check the `ac_post_process_output.json` file in the build artifacts to see if the APKs are signed or not.
In Android, please also check if gradle sign is being used for the selected build variant. If gradle sign works alongside with Appcircle signing, you will receive multiple APKs.
### Deleted versions still occupy storage space
The master version of any artifact deployed from the Build to the Testing Distribution is stored within the build artifacts section. Once you delete such a version from the Testing Distribution, only the reference is removed and the binary is still available within the build artifacts of the related build. You also need to remove the binary from the build artifacts to save storage.
### Access Denied on builds
On some distributed apps, the **Access Denied** error can be bypassed by one of these steps:
- Launching the distribution link on a different browser and Incognito Mode
- Clearing the browser cache if the link is pasted to a browser instead of in-line browser on mail applications
- If there is an authorization configuration on Distribution, clearing the authorization temporarily
### Can I set an authentication method for accessing the Testing Portal?
Yes, you can choose one of the authentication methods provided by Appcircle to authenticate your users and control their access to the store. For more information, please visit the Testing Distribution [**Authentication**](/testing-distribution/create-or-select-a-distribution-profile#authentication) documentations.
### Can I send a binary from another CI tool?
Yes, you can use Appcircle **API & CLI** tools within your current CI tool to directly send the binary and utilize it within the Testing Distribution. For more information, please visit the [**Appcircle API & CLI**](/appcircle-api-and-cli) documentations.
### What does email/month mean? How is the number calculated?
An email is calculated every time an app is shared via email from our servers. So every send email adds to email count.
### Do you offer plans specific to Enterprise App Store (without CI/CD features)?
Thanks to the modular structure of Appcircle, all modules can be used independently. Accordingly, you can also request a special plan only for Testing Distribution. Please [contact us](https://appcircle.io/contact) for detailed information.
### How can I get a binary from another organization to use in the Testing Distribution module?
Let’s assume there are two organizations: Organization A and Organization B.
In Organization A, we have a build profile that generates an IPA, APK, or AAB.
In Organization B, we have a testing distribution profile that we want to send the binary to.
In Organization A's build profile workflow, after the build step, we can add a [Custom Script](/workflows/common-workflow-steps/custom-script/) step that includes the code snippet below to transfer the binary generated in Organization A to the Testing Distribution profile in Organization B. In order to do this, we need [Appcircle CLI](/appcircle-api-and-cli/cli-authentication), so this code snippet sets up the necessary information and sends binary with parameters.
```bash
#Bash script
sudo npm install -g @appcircle/cli
appcircle login personal-access-key --secret $ORG_B_PERSONAL_ACCESS_KEY
# If an IPA or AAB is required, change *.apk to *.ipa or *.aab
appcircle testing-distribution upload \
--distProfileId "$ORG_B_TEST_DIST_PROFILE_ID" \
--message "Release Notes" \
--app "$AC_OUTPUT_DIR"/*.apk
```
The key point here is that we need two essential parameters to make this work.
- `ORG_B_PERSONAL_ACCESS_KEY` => Personal Access Key from Organization B.
- `ORG_B_TEST_DIST_PROFILE_ID` => Testing Distribution profile ID from Organization B.
- `$AC_OUTPUT_DIR` => Automatically defined by the system. See [Reserved Variables](/environment-variables/appcircle-specific-environment-variables/).
To generate Personal Access Key, follow this [documentation](/account/my-organization/security/personal-access-key#generatingmanaging-the-personal-access-keys)
To obtain the Testing Distribution profile ID, follow the steps below:
1. Log in to organization B.
2. Go to Testing Distribution module.
3. Select the desired Testing Distribution profile
4. Copy it from the URL. `https://my.appcircle.io/distribute/detail/123456f-7d89-4545-5454-123456789abc`
5. Then the Testing Distribution profile ID is => `123456f-7d89-4545-5454-123456789abc`
After collecting the required parameters, set the following values as [Environment Variables](/environment-variables/):
- `ORG_B_PERSONAL_ACCESS_KEY`
- `ORG_B_TEST_DIST_PROFILE_ID`
---
## Testing Distribution
The Testing Distribution module in Appcircle is designed to simplify and secure how you share mobile builds (iOS and Android) with testers before release. It allows you to manage who gets which builds, automate build delivery, and track usage through integrated reports.
:::tip Learn More
For a complete overview of the Appcircle Testing Distribution module capabilities, check out the [Appcircle's Testing Distribution Section](https://appcircle.io/testing-distribution).
:::
## [Distribution Profile](/testing-distribution/create-or-select-a-distribution-profile)
To share builds with testers, distribution profiles should be created and testing groups assigned to these profiles.
Distribution Profile
## [Testing Groups](/testing-distribution/testing-groups)
The testing group feature is used to manage and organize testers. Different versions of applications can be distributed to specific groups based on testing needs, such as OS versions, features, devices, and more.
Testing Groups
## [Re-sign Binaries](/testing-distribution/resigning-binaries)
Re-signing is the process of modifying an existing binary with a new signing certificate or keystore, required when an application needs to be published under a different developer account or when updating an existing application. This process involves removing the original signature and replacing it with a new one.
Re-sign Binaries
## [Testing Portal](/testing-distribution/testing-portal)
Appcircle has a separate distribution screen designed to make it easy for test group developers and testers download the distributed applications easily.
Testing Portal
## [Reporting](/testing-distribution/reports)
Optimize your application management with detailed reports. Utilize the App Sharing Report and App Versions Report to gain insights and make informed decisions about your app's distribution and evolution.
Reporting
---
## Reporting
# App Reports
Optimize your application management with detailed reports. Utilize the App Sharing Report and App Versions Report to gain insights and make informed decisions about your app's distribution and evolution.
## App Versions Report
This report can be accessed from the Testing Distribution.
The App Versions Report contains a list of binaries that have been deployed to a distribution profile within a given time period.
Create a Distribution Profile and Sharing with Testers
Each version is defined as an app binary for iOS and Android that has been deployed manually, automatically, or uploaded directly to a distribution profile. Even if a binary is deleted, it will still be visible in this report.
The date and time are displayed in the current timezone.
The report pages can be filtered according to the organization.
:::info
In the filtering options, only the organization and sub-organization to which you belong can be viewed and selected.
:::
## App Sharing Report
This report is accessible from the Testing Distribution.
The App Sharing Report lists the app versions that have been sent to testers within a given time period.
Each line indicates an individual share operation conducted using the "Share with Testers" feature, either manually or automatically, along with the number of testers with whom the app was shared. The number of testers is not unique and specifies the number of recipients for that specific share operation.
The date and time are displayed in the current timezone.
The report pages can be filtered according to the organization.
:::info
In the filtering options, only the organization and sub-organization to which you belong can be viewed and selected.
:::
---
## Re-sign Binaries
# Re-signing
Re-signing is the process of modifying an existing binary with a new signing certificate or keystore, required when an application needs to be published under a different developer account or when updating an existing application. This process involves removing the original signature and replacing it with a new one.
## Re-signing iOS Binaries
To sign an iOS binary, you need a valid certificate and provisioning profile. Appcircle supports both IPA and xcarchive files. The process of signing an iOS binary involves selecting the correct certificate and provisioning profile and specifying the bundle identifier and version number. Once these details are entered, Appcircle will generate a new signed binary with the updated information.
### iOS Re-sign Process
You can use manual re-sign to:
- Change the signing certificate or provisioning profile
- Update the bundle identifier to match the profile
- Modify the app display name
- Adjust version and build numbers before distribution
1. Select the binary.
You can either select the files from the list or upload IPA, xcarchive files by clicking the **Upload** button at the top of the list.
2. Click the ... button and select **Re-sign Binary**
Manual re-sign operations are performed per app version and the resulting output is stored as a new re-signed artifact.
:::info iOS Re-sign Configurations
For detailed information about Manual iOS Re-sign configurations, please refer to the [configuration](/testing-distribution/resigning-binaries#ios-auto-re-sign-configurations) section. The configuration structure for Manual and Auto Re-sign is the same. However, unlike Auto Re-sign, Manual Re-sign configurations must be reconfigured for each re-sign action.
:::
When you sign an app version through Testing Distribution Profile or upload a signed app version manually or automatically through the Build module, Testing Distribution Profile will display a **signed** badge when the corresponding app version is selected.
## Re-signing Android Binaries
To sign an Android binary, a valid keystore file is required. Both APK and AAB files are supported by Appcircle. The process of signing an Android binary involves selecting the correct keystore file. Once these details are entered, a new signed binary with the updated information will be generated by Appcircle.
### Android Re-sign Process
1. Select the binary.
Files can either be selected from the list or uploaded by clicking the **Upload** button at the top of the list for APK and AAB files.
2. Click the "..." button and select **Re-sign Binary**
You can use manual re-sign to:
- Replace the signing keystore
- Update the package name to match the profile
- Modify version code and version name values
- Convert AAB files to APK if required for distribution
:::info Android Re-sign Configurations
For detailed information about Manual Android Re-sign configurations, please refer to the [configuration](/testing-distribution/resigning-binaries#android-auto-re-sign-configurations) section. The configuration structure for Manual and Auto Re-sign is the same. However, unlike Auto Re-sign, Manual Re-sign configurations must be reconfigured for each re-sign action.
:::
When an app version is signed using the Testing Distribution Profile or uploaded manually or automatically through the Build module, a **signed** badge will be displayed on the Testing Distribution Profile for the corresponding app version.
## Auto Re-sign
In addition to manual resigning, the **Testing Distribution** module supports **Auto Re-sign Configurations** for both iOS and Android binaries.
The **Auto Re-sign** feature allows users to automatically re-sign their iOS (`.ipa`) and Android (`.apk`/`.aab`) applications with a different keystore, provisioning profile, or certificate before distribution.
You can enable the **Auto Re-sign** feature by navigating to Settings option and enabling Auto-resign toggle for iOS and/or Android.
Once it's enabled, you will need to configure the Auto Re-sign feature for iOS and Android. **Auto Re-sign Configurations** options can be found by clicking **...**.
### iOS Auto Re-sign Configurations
For iOS, you can configure:
- **Information**: Configure your binary's Bundle ID and update display name.
#### Bundle ID
Appcircle Testing Distribution profiles can accept binaries with different bundle identifiers. The binary defined for the profile serves as the reference for Auto Re-sign. When a binary with a different bundle identifier is uploaded, it is re-signed according to the bundle identifier of the profile. The bundle identifier of the resulting re-signed binary is updated to match the one associated with the profile.
#### Select a Pool
The Pool Selection field defines which organization pool will be used to execute the Auto Re-sign process.
:::caution Pool Selection Is Mandatory
Auto Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Auto Re-sign process will not start.
- Uploaded binaries will remain unsigned.
- No re-signed output will be generated for Testing Distribution profile.
Always ensure that a valid macOS pool is selected before saving the Auto Re-sign configuration.
:::
#### Update Display Name
With the Display Name parameter, you can change the visible name of the binary that will be re-signed. The re-signing process starts with the specified display name, and once completed, the `CFBundleDisplayName` value inside the binary is updated accordingly.
:::info
If `CFBundleDisplayName` is not present in the `info.plist`, changing the display name will not take effect.
:::
- **Versioning**: By utilizing the versioning capability of the Auto Re-sign feature, you can modify the version and build number of the incoming binary according to the defined strategy during the re-signing process.
- **Signing**: Choose provisioning profiles and entitlements required for re-signing.
#### App Store Connect Credential
Appcircle’s Auto Re-sign feature requires an **App Store Connect** credential. Therefore, selecting a credential is mandatory for both versioning and signing processes. This credential is used to download the necessary signing assets and retrieve version-related information when versioning is configured to use App Store data.
For more information, please visit the [App Store Connect API Key](/account/my-organization/security/credentials/adding-an-app-store-connect-api-key) documentation.
#### Signing Method
The **Signing Method** defines how Appcircle selects the provisioning profile during the re-signing process. This strategy determines whether Appcircle should use an existing provisioning profile. Selecting the appropriate signing strategy ensures compatibility with your target distribution method and proper signing of your binary.
For more information about these signing strategies, please visit the [Apple Profiles](/signing-identities/apple-profiles) documentation.
#### Certificates
In addition to the selected signing strategy, Appcircle requires a corresponding certificate to perform the auto re-sign process. Therefore, make sure that your certificates are uploaded under the **Apple Certificate** section in the Appcircle **Signing Identity** module. The re-signing process will begin using the certificate you have selected.
For more information, please visit the [Signing Identity](/signing-identities) Module and [Apple Certificates](/signing-identities/apple-certificates) documentations.
#### Create a New Provision Profile
If the **Create a New Provision Profile** option is enabled, Appcircle generates a valid provisioning profile for signing using the Apple API Key selected in the profile settings and your Apple Developer account. If this option is disabled, Appcircle matches an existing valid provisioning profile from your Apple Developer portal for the signing process.
:::caution Create a New Provision Profile
If you **do not** want to create the provisioning profile for signing, Appcircle will attempt to match a valid provisioning profile and use it for the signing process. When this option is disabled and a matching provisioning profile cannot be found, a new provisioning profile will be automatically created.
:::
### Android Auto Re-sign Configurations
For Android, you can configure:
- **Information**: Configure your binary's package ID.
#### Package ID
Appcircle Testing Distribution profiles can accept binaries with different package ID. The binary defined for the profile serves as the reference for Auto Re-sign. When a binary with a different package ID is uploaded, it is re-signed according to the package ID of the profile. The package ID of the resulting re-signed binary is updated to match the one associated with the profile.
#### Select a Pool
The Pool Selection field defines which organization pool will be used to execute the Auto Re-sign process.
:::caution Pool Selection Is Mandatory
Auto Re-sign will not work if a pool is not selected.
If no pool is defined:
- The Auto Re-sign process will not start.
- Uploaded binaries will remain unsigned.
- No re-signed output will be generated for Testing Distribution profile.
Always ensure that a valid macOS pool is selected before saving the Auto Re-sign configuration.
:::
- **Versioning**: By utilizing the versioning capability of the Auto Re-sign feature, you can modify the version and build number of the incoming binary according to the defined strategy during the re-signing process.
- **Signing**: Select the keystore for signing your `.APK` or `.AAB` files.
#### Keystores
The **Keystores** section is where you manage the signing credentials required for Android re-signing. To successfully perform the auto re-sign process, Appcircle needs access to a valid keystore. You must upload the keystore file, provide the necessary alias, and enter the key and store passwords within the **Android Keystores** section of the **Signing Identity** module. The re-signing will be executed using the selected keystore credentials.
:::caution Keystore
In order for Appcircle to initiate the auto re-sign process, a selected keystore must be available. Therefore, ensure that the keystore you want to use for signing is uploaded under the Android Keystores section in the Appcircle Signing Identity module.
For more information, please visit the [Signing Identity](/signing-identities) Module and [Android Keystores](/signing-identities/android-keystores) documentations.
:::
#### Convert AAB to APK
The **Convert AAB to APK** option allows you to automatically convert an Android App Bundle (AAB) file into an APK during the re-signing process. This is especially useful when your distribution channel requires an `.APK` instead of an `.AAB`. When enabled, Appcircle will handle the conversion and signing of the resulting APK seamlessly.
:::warning Sharing AAB
Testing Distribution profiles will not allow `.AAB` binaries to be shared with testers. It is recommended to keep this convert option enabled.
:::
:::info Auto Re-sign Behaviour
- Once Auto Re-sign is configured, every new binary uploaded to the Testing Distribution profile will automatically be re-signed.
- Signed binaries will be displayed with a **signed** badge, and hovering over it will show the certificate details used.
:::
## Re-sign History
1. Select the binary.
You can either select the files from the list or upload binaries by clicking the **Upload** button at the top of the list.
2. Click the... button and select **Resign History**
3. Each signing process will be listed for that binary. If you click the **View Log** button, you can get more details about the process.
:::info
You need the check the history of the original application that has been signed.
:::
---
## Testing Groups
The testing group feature is used to manage and organize testers. Different versions of applications can be distributed to specific groups based on testing needs, such as OS versions, features, devices, and more.
The testing groups feature allows for the definition of various groups for different audiences. For instance, in an enterprise, groups such as testing team, marketing, management, and other functional groups can be created. For an app developer, testing groups can be created for customers and apps. This enables streamlined management of binary sharing flows. Apps can be sent manually to these groups, or different distribution profiles can be associated with different groups for automatic distribution.
You can list, add, edit and manage your groups and testers from this module.
Click on the orange + button to create a new testing group. You can name groups according to your needs, such as "Alpha," "Beta," and so on. After typing the name of the new testing group, press enter to create it.
After a new testing group is created, tester email addresses can be added to the group. The input box at the top of the page should be used to enter the email address, and pressing enter will add it.
A list of your testers will now be displayed. Testers can be selected and deleted as needed.
Also by clicking on the edit button next to your testing group name from the list, you can rename, duplicate or delete your testing group if you need to.
### Managing Unsubscribed Users
When re-sharing the app with users who have previously unsubscribed, you can seamlessly re-engage them.
Click on the **Share with Testers** button from the distribution profile. Then, simply add the users who have unsubscribed to the recipients.
This action automatically removes them from the unsubscribed list, allowing them to receive emails once again.
A prominent orange warning message confirms the successful re-subscription process, ensuring a seamless experience.
:::info
If a user who has previously unsubscribed is included in a test group, they will not be re-subscribed when sharing with the test group.
:::
## Importing Testing Group Members via LDAP
If you have a LDAP Mapping in place for your users, you can import them into your Testing Group profile.
For LDAP configuration and mapping, please refer to the [LDAP](/account/my-organization/security/authentications/distribution-ldap-authentication) documentation.
1. **Create or Select a Testing Group**:
Either create a new Testing Group in Appcircle or select an existing one.
2. **Import Group Members from LDAP**:
- Click on the three dots in the top-right corner.
- Select the **Start Sync with LDAP** option.
**Note**: The Testing Group must not contain any members. If it does, attempting to import from LDAP will result in an error.
3. **Select LDAP Configuration**:
- Choose the LDAP configuration from the dropdown menu.
- Select the LDAP Group from which you want to import members.
4. **Preview LDAP Group Members**:
The members of the LDAP Group will be displayed in the UI as a preview. This allows you to review the members before importing. At this stage, the members are not yet imported into the Testing Group.
5. **Determine Sync Frequency**:
Select a time frame for automatic sync process. Once Testing Group linked to the LDAP Group, it will sync the group members periodically.
6. **Sync Group Members**:
Click the **Sync Now** button to import and store the LDAP group members in the Testing Group.
**Note:** Clicking **Save** to complete the process will also be sufficient to import the members.
7. **Update LDAP Group Configuration**:
After linking the Testing Group to the LDAP Group, you can update the LDAP configuration in the same way it was imported.
Testing Groups that use the LDAP sync feature will be marked with a tag displaying the selected LDAP group.
:::caution
It is not possible to add or remove members of Testing Group on UI manually after establishing a link to LDAP Group.
However, the testing group can still be renamed, duplicated and deleted.
:::
#### Disable LDAP Import Settings
Users can disable LDAP import settings for an LDAP-imported Testing Group by clicking the ‘Remove Sync with LDAP’ button in the top right corner.
Note that this option is only available for Testing Groups that have already imported their members via LDAP settings.
After disabling the settings, existing members will remain, and users can manually add or remove members as needed.
## Exporting Testing Group Members as CSV
You can export the list of testers in a Testing Group as a CSV file for record-keeping, reporting, or bulk operations outside the Appcircle.
Steps to Export Testers as CSV:
1. Navigate to Testing Distribution > Testing Groups from the sidebar.
2. Select the desired Testing Group (e.g., My Testers) from the list.
3. Click the three-dot menu (⋮) located on the top-right of the selected group panel.
4. From the dropdown menu, click Export as CSV.
5. The CSV file will automatically download to your browser’s default download location.
:::tip
If you need to export multiple groups, repeat the process for each group individually. You can use the exported CSV file to import your testing group members for a different Appcircle Organization.
:::
## Importing Testing Group Members via CSV
You can add your testers quickly and efficiently by using Import from CSV option. The Testing Group profile does not need to be empty in order to use this feature.
Also, after adding the users by CSV, you can still add or remove the tester emails as you see fit. The duplicated email addresses will be handled by Appcircle automatically.
- Click on the three-dot menu (•••) of the desired testing group.
- Select **Import from CSV** from the dropdown menu.
- Ensure the CSV file contains a column labeled Email. Each tester's email address should be listed under this column.
**Example format:**
- Upload the CSV file.
:::info
Importing a CSV file does not delete existing testers unless manually removed from the profile.
:::
## FAQ
### What is the tester limit for app distribution?
Appcircle provides a scalable solution, allowing you to add as many testers as you need without stringent limitations. This ensures you can conduct thorough testing across a wide range of devices and user scenarios. Appcircle also offers flexible group management, so you can easily organize testers into different groups based on testing needs.
### Why have I not received the e-mail after sharing the app version via Appcircle ?
There could be several reasons why you haven't received the email after sharing the app version with your testers:
- The recipient might be unsubscribed.
- The email may have arrived in the junk folder.
- Company firewall rules might cause delays of up to 30 minutes.
- The Appcircle domain may need to be whitelisted.
---
## Testing Portal
Appcircle has a separate distribution screen designed to make it easy for test group developers and testers download the distributed applications easily.
For iOS and Android, the testers can login from the link shared and then view all the versions shared with them. Downloading iOS and Android binaries are done through the specific flows of each OS.
## Login
When a build is shared with testers, each tester will receive an email with a link to download the binary file and other details like version number and release notes.
When the link is clicked, users will then be redirected to the testing portal.;
:::info
The accounts used in the testing portal are completely independent from Appcircle accounts and only used for downloading shared apps.
:::
:::info
Please note that the log out option is available only if an active authentication method is present in your testing distribution profile.
:::
:::warning
Please note that to login to the Testing Portal, you must enable cookies in your browser. Cookies help maintain your session and ensure secure access.
Refer to your browser's settings to enable cookies:
**Chrome**: Settings > Privacy and security > Cookies.
**Safari**: Preferences > Privacy.
:::
## Listing and Downloading Binary
Once logged in, users can now see the list of distributions separated by distribution profile and release version. Files can be downloaded with one click.
:::caution
For running iOS apps signed with an enterprise certificate, you may need to trust the certificate provider after installing the app.
For installing Android apps, you may need to grant the web browser "install apps from unknown sources" permission so that the apps downloaded from the portal can be installed.
:::
The Testing Portal will also display the size and the certificate type of each app version. For more information on certificate types, please visit the [Signing Identities](/signing-identities) section.
:::info
If your app version has an enterprise-type certificate, the Testing Portal will display a guidance message on how to proceed with the installation on your device.
:::
:::tip
The Testing Portal supports English, German, French, and Turkish.
For desktop usage, it will detect and apply your browser's language if it is supported.
For mobile devices, it will detect the device language.
If the detected language is not supported, the default language will be English.
:::
## Search Binary
The search bar can be used to filter the available app version list by *app names**, **app versions**, **release notes**, and **build numbers**.
### Search By Branch
The Testing Portal will provide a dropdown menu containing the source branches of the listed binaries, allowing users to quickly search for the required branch for a clearer display.
:::tip
If the branch filter is not visible, it may be because the binary was uploaded manually to the Testing Distribution module instead of being sent via the Build module.
:::
### Filter by OS
The Testing Portal includes an OS Filter that enables users to switch between different OS-specific binaries easily. This feature helps users manage and navigate their iOS and Android releases efficiently. These tabs will be available when the Testing Portal is accessed through a desktop or a laptop device.
#### Filter Options
The filter consists of three tabs:
- **All**: Displays both iOS and Android binaries together.
- **iOS**: Shows only iOS binaries.
- **Android**: Displays only Android binaries.
### Sort Binaries by Version & Date
The listed binaries on the Testing Portal can be sorted by version or the date they were shared, based on user preferences. This can be toggled using the Date and Version buttons located above the binary list.
## Navigating Between Shared App Profiles
Users can view other distributed app versions from different testing distribution profiles by selecting the menu icon in the top left corner.
The Shared App Profiles section allows testers to view other testing distribution profiles that have a shared app version associated with their email address.
The list will display the other testing distribution profiles along with their authentication methods.
:::caution
**Re-authentication Rules:**
- When switching between profiles that use different authentication methods (e.g., STATIC to SSO), users must log in again to access the new profile.
- If both the current and target profiles use SSO or LDAP, no re-authentication is needed when switching.
- If both profiles use STATIC authentication, re-authentication is required.
:::
For more information about authentication methods, please refer to the [Using Authentication for Distribution](/testing-distribution/create-or-select-a-distribution-profile#authentication) section.
:::info
**Profile Visibility:**
- If distribution link access is enabled for a profile, it will be visible and accessible from other profiles within the same organization in the testing portal, regardless of whether it has been shared via email.
- The visibility is based on the profile the user is currently logged into, and is not influenced by the type of authentication used.
- If a user gains access to the Testing Portal through a shared distribution link, they will not be able to navigate to profiles with distribution link access disabled unless those profiles have been shared with their email.
:::
For more information about using distribution links, please visit the [using distribution link](/testing-distribution/create-or-select-a-distribution-profile#distribution-link) documentation.
## Profile Information
#### Profile Card
When the user icon is selected, the distribution profile information will be displayed. This information can be updated from the [Info](/testing-distribution/create-or-select-a-distribution-profile#config) tab within the profile settings.
The Login Method for the Testing Distribution Profile will also be displayed.
In the example image, the profile has a static authentication method, so it is displayed as Static Login.
You can find out more about the login methods in the [using authentication for distribution](/testing-distribution/create-or-select-a-distribution-profile#authentication) section.
:::info
Please note that the Privacy and Terms URLs are optional. If they have not been configured within the Info tab of your profile settings, they will not be visible in the Testing Portal.
:::
---
## Android Versioning
## Enabling Version Management
In order to manage version code and version name with Appcircle, two requirements must be met:
- The build's Version Management toggle must be turned on and required input values must be entered.
- **Increment Build and Version Number** component `1.0.*` or higher must be in your workflow.
The Versioning tab manages the input values of the component. It is not recommended to change the values of the component with the workflow editor. Instead, it would be best if you always used the Versioning UI to manage the settings.
:::caution
Gradle files are written in Groovy language. Therefore it can use functions or environment variables during the build. This component doesn't cover all the edge cases. Please test your workflow thoroughly and make sure that it works as intended.
:::
### Managing Version Code
The versioning system needs a version code source and an offset to calculate the new version code. There are two source types for the version code.
**Version Code Source**
- Environment Variable
- Gradle
If you select **Environment Variable**, you need to write the source environment variable into `Version Code`. The default value for this input is `$AC_BUILD_NUMBER`. This variable increases after every build. You can also use other environment variables that you create or select from the config screen. Environment variables must start with the `$` sign.
If you select Gradle, the version code will be read from build.gradle file. If you want to use different flavor, please set them in the **Advanced Settings** section.
:::danger
Using a dynamic `versionCode` in the Gradle file is not supported for version incrementing. If you define `versionCode` dynamically, you may encounter a format error after selecting Gradle as the `Version Code Source`.
For a sample of a stable format, you can refer to the document below:
- [Android - Set app version information](https://developer.android.com/studio/publish/versioning#appversioning)
:::
**Offset**
If you select `$AC_BUILD_NUMBER` as your version code source, the version code in your project can be different. To synchronize version code, you can use the offset. The offset value is a number to be added or subtracted from the _Version Code Source_. Negative values can be written such as -10.
### Managing Version Name
The versioning system needs a version name source and an offset to calculate the new version name. There are two source types for the version name.
**Version Name Source**
- Environment Variable
- Gradle
If you select Environment Variable, you need to write the source environment variable into `Version Name` You can use any environment variable that you create or select from the config screen. Environment variables must start with the `$` sign.
If you select Gradle, the version name will be read from the given Android project.
:::danger
Using a dynamic `versionName` in the Gradle file is not supported for version incrementing. If you define `versionName` dynamically, you may encounter a format error after selecting Gradle as the `Version Name Source`.
For a sample of a stable format, you can refer to the document below:
- [Android - Set app version information](https://developer.android.com/studio/publish/versioning#appversioning)
:::
**Offset**
To synchronize version names, you can use the offset. The offset value is a number to be added or subtracted from the _Version Name Source_. Negative values can be written such as -10.
**Increment**
You can increase the major, minor, or patch value of the version name. For version name 2.5.1, values can be summarized below.
| Part | Value |
| ----- | ----- |
| Major | 2 |
| Minor | 5 |
| Patch | 1 |
:::warning
To increment the version name, please make sure it is in an integer format (`INT.INT.INT`). Incrementing non-integer version names is not supported.
:::
**Omit Zero Patch Version**
If true, omits zero in the patch version. So _42.10.0_ will become _42.10_ and _42.10.1_ will remain _42.10.1_. The default is false.
### Advanced Settings
This component works on standard build.gradle files. If you use flavors in your build.gradle, you can set the flavor name. However, please be aware that flavor support is not foolproof. Due to dynamic nature of build.gradle file, it may not cover all the cases.
### Output Variables
After the version code or version name update, new values will be written to two environment variables.
| Variable Name | Description |
| ------------------------------ | --------------------------------------------------------------- |
| `$AC_ANDROID_NEW_VERSION_CODE` | Represents the incremented version code applied to the project. |
| `$AC_ANDROID_NEW_VERSION_NAME` | Represents the incremented version name applied to the project. |
You can use the above values in the remaining steps of your workflow.
### Input Variables
The versioning system works by consuming environment variables. Even though it's easier to configure it by using UI, sometimes you may want to change them on the fly. Your commit messages or tags can be used to override those settings. The name of the variables and expected values can be found below.
| Variable Name | Description | Status |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If it runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_BUILD_NUMBER_SOURCE` | Version code source type (environment variable or gradle file). | Required |
| `$AC_ANDROID_BUILD_NUMBER` | Version code to set. If `$AC_BUILD_NUMBER_SOURCE` is set to gradle, this variable will be read from the project. | Optional |
| `$AC_BUILD_OFFSET` | The number to be added or subtracted from the `$AC_ANDROID_BUILD_NUMBER`. | Optional |
| `$AC_VERSION_NUMBER_SOURCE` | Version name source type (environment variable or gradle file). | Optional |
| `$AC_ANDROID_VERSION_NUMBER` | Version name to set. If `$AC_VERSION_NUMBER_SOURCE` is set to gradle, this variable will be read from the project. Version name must be in integer format (`INT.INT.INT`) to increase. | Optional |
| `$AC_VERSION_STRATEGY` | Version increment strategy (`major`, `minor`, `patch`, or `keep`). | Optional |
| `$AC_VERSION_OFFSET` | The number to be added or subtracted from the `$AC_ANDROID_VERSION_NUMBER`. | Optional |
| `$AC_PROJECT_PATH` | Specifies the project path. If the project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. | Optional |
| `$AC_VERSION_FLAVOR` | Build flavor. If you select a flavor from the [**Advanced Settings**](#advanced-settings) section, the versioning of the chosen flavor will be applied (for example, the Gradle file of the selected flavor will be used). | Optional |
| `$AC_OMIT_ZERO_PATCH_VERSION` | If `true`, it omits zero in the patch version. | Optional |
Since you can use any environment variables for the version code and version name, you can consume Appcircle's various environment variables during the build. Appcircle gives plenty of information related to your repo and project.
Let's see a couple of ways to utilize those values.
**Using Commit Messages**
We can extract the commit message and set the version name from the message. Commit message is stored inside `$AC_COMMIT_MESSAGE`. Let's say we want to use the version name from the commit message. Let's assume that the commit message is `[VERSION] 1.2.3` Since we will use a calculated value, we have to change our `$AC_VERSION_NUMBER_SOURCE` as well. We also set the offset value as 0 so that the calculated value can be applied directly. We can use the following custom script to extract this information.
```ruby
commit_message = ENV['AC_COMMIT_MESSAGE']
# extract commit message with regex
version = commit_message.match(/\[VERSION\] (.*)/)
if version
version = version[1]
open(ENV['AC_ENV_FILE_PATH'], 'a') { |f|
f.puts "AC_VERSION_NUMBER_SOURCE=env"
f.puts "AC_VERSION_OFFSET=0"
f.puts "AC_ANDROID_VERSION_NUMBER=#{version}"
}
end
```
Just add this script as a custom script above the Increment Android Version Component. The type of the script must be set as ruby.
**Using Tags**
It is also possible to extract the version name from the Git tags. The following example assumes that the commit has a single tag. If you tag your version with `release-1.2.3`, the following script will extract the version name from the tag.
```ruby
commit_message = ENV['AC_COMMIT_TAGS']
version = commit_message.match(/release-(.*)/)
if version
version = version[1]
open(ENV['AC_ENV_FILE_PATH'], 'a') { |f|
f.puts "AC_VERSION_NUMBER_SOURCE=env"
f.puts "AC_VERSION_OFFSET=0"
f.puts "AC_ANDROID_VERSION_NUMBER=#{version}"
}
end
```
### Versioning Playground
You can use the below playground to test the effect of different options
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-build-version-increment-component.git
---
## Versioning
Proper versioning is crucial for maintaining and updating mobile applications effectively. It helps in tracking different versions of your app, managing updates, and ensuring compatibility.
## [iOS Versioning](/versioning/ios-version)
iOS apps use `CFBundleShortVersionString` and `CFBundleVersion`:
- `CFBundleShortVersionString`: The release version number displayed to users.
- `CFBundleVersion`: The build number, which identifies an iteration of the app.
## [Android Versioning](/versioning/android-version)
Android apps use a combination of `versionCode` and `versionName` in their build configurations:
- `versionCode`: An integer value that represents the version of the application code, which is incremented with every release.
- `versionName`: A string value that represents the release version to the user.
This section provides resources and guidelines to understand and manage the versioning system for both iOS and Android platforms.
---
## iOS Versioning
## Enabling Version Management
In order to manage build and version numbers with Appcircle, two requirements must be met:
- The build's Version Management toggle must be turned on and required input values must be entered.
- **Increment Build and Version Number** component `2.0.*` or higher must be in your workflow.
The Versioning tab manages the input values of the component. It is not recommended to change the values of the component with the workflow editor. Instead, it would be best if you always used the Versioning UI to manage the settings.
### Managing Build Number
The versioning system needs a build number source and an offset to calculate the new build number. There are two source types for the build number.
**Build Number Source**
- Environment Variable
- Xcode
If you select **Environment Variable**, you need to write the source environment variable into `Build Number`. The default value for this input is `$AC_BUILD_NUMBER`. This variable increases after every build. You can also use other environment variables that you create or select from the config screen. Environment variables must start with the `$` sign.
If you select Xcode, the build number will be read from the given Xcode project. Archive configuration and the first app target will be used to read that value from the plist file. If you want to use different configurations or targets, please set them in the **Advanced Settings** section.
**Offset**
If you select `$AC_BUILD_NUMBER` as your build number source, the build number in your project can be different. To synchronize build numbers, you can use the offset. The offset value is a number to be added or subtracted from the _Build Number Source_. Negative values can be written such as -10.
### Managing Version Number
The versioning system needs a version number source and an offset to calculate the new version number. There are three source types for the build number.
**Version Number Source**
- Environment Variable
- Xcode
- App Store
If you select Environment Variable, you need to write the source environment variable into `Version Number` You can use any environment variable that you create or select from the config screen. Environment variables must start with the `$` sign.
If you select Xcode, the version number will be read from the given Xcode project. Archive configuration and the first app target will be used to read that value from the plist file. If you want to use different configurations or targets, please set them with Advanced settings.
The App Store option allows you to get the version number from the App Store directly. If you select App Store, the bundle id of your application must be entered. If your app is only available in selected countries, you must also enter an optional country code, ex: `us`
Please be aware that selecting this option is not a foolproof method. App Store endpoint may not be available during your build due to network issues or App Store instabilities.
**Offset**
To synchronize version numbers, you can use the offset. The offset value is a number to be added or subtracted from the _Version Number Source_. Negative values can be written such as -10.
**Increment**
You can increase the major, minor, or patch value of the build number. For version number 2.5.1, values can be summarized below.
| Part | Value |
| ----- | ----- |
| Major | 2 |
| Minor | 5 |
| Patch | 1 |
**Omit Zero Patch Version**
If true, omits zero in the patch version. So _42.10.0_ will become _42.10_ and _42.10.1_ will remain _42.10.1_. The default is false.
### Advanced Settings
This component updates all runnable targets. If you only want to update selected targets, enable the `MANUALLY SELECTED TARGETS` option and write the targets' names.
The versioning system will update the project's build or version number according to the target's release configuration. If you want to use another `xcconfig` please enable the `MANUALLY SELECTED XCCONFIG` toggle and write the name of the `xcconfig`.
### Output Values
After the build or version number update, new values will be written to two environment variables.
| Value | Explanation |
| ---------------------------- | ---------------------- |
| `$AC_IOS_NEW_BUILD_NUMBER` | Changed build number |
| `$AC_IOS_NEW_VERSION_NUMBER` | Changed version number |
You can use the above values in the remaining steps of your workflow.
### Input Variables
The versioning system works by consuming environment variables. Even though it's easier to configure it by using UI, sometimes you may want to change them on the fly. Your commit messages or tags can be used to override those settings. The name of the variables and expected values can be found below.
| Variable Name | Description | Status |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------- |----------|
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If it runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: `./appcircle.xcodeproj`. | Required |
| `$AC_SCHEME` | Specifies the project scheme for the build. | Required |
| `$AC_BUILD_NUMBER_SOURCE` | Build number source type(env variable or Xcode). | Optional |
| `$AC_IOS_BUILD_NUMBER` | Build number. The default variable is `$AC_BUILD_NUMBER`. | Optional |
| `$AC_BUILD_OFFSET` | Build incremeent offset. | Optional |
| `$AC_VERSION_NUMBER_SOURCE` | Version number source type(env variable, Xcode or App Store). | Optional |
| `$AC_IOS_VERSION_NUMBER` | Version number. | Optional |
| `$AC_VERSION_STRATEGY` | Version increment strategy `major`, `minor`, `patch`, or `keep`. The default variable is keep | Optional |
| `$AC_VERSION_OFFSET` | The number to be added or subtracted from the version number. Negative values can be written such as -10. The default variable is `0`. | Optional |
| `$AC_OMIT_ZERO_PATCH_VERSION` | If true omits zero in patch version (so `42.10.0` will become `42.10` and `42.10.1` will remain `42.10.1`), default is false. | Optional |
| `$AC_BUNDLE_ID` | If the build number source is `appstore`, this variable should have the bundle id of your application. | Optional |
| `$AC_APPSTORE_COUNTRY` | If the build number source is `appstore`, optional two letter country code. | Optional |
| `$AC_TARGETS` | Name of the targets to update. You can separate multiple targets by the pipe symbol. If you don't specify any target, all runnable targets will be updated. | Optional |
| `$AC_IOS_CONFIGURATION_NAME` | The build configuration to use. If you don't specify any configuration, the target's archive configuration will be used. | Optional |
Since you can use any environment variables for the build and version numbers, you can consume Appcircle's various environment variables during the build. Appcircle gives plenty of information related to your repo and project.
Let's see a couple of ways to utilize those values.
### Output Values
After the build or version number update, new values will be written to two environment variables.
| Value | Explanation |
| ---------------------------- | ---------------------- |
| `$AC_IOS_NEW_BUILD_NUMBER` | Changed build number |
| `$AC_IOS_NEW_VERSION_NUMBER` | Changed version number |
You can use the above values in the remaining steps of your workflow.
**Using Commit Messages**
We can extract the commit message and set the version number from the message. Commit message is stored inside `$AC_COMMIT_MESSAGE`. Let's say we want to use the version number from the commit message. Let's assume that the commit message is `[VERSION] 1.2.3` Since we will use a calculated value, we have to change our `$AC_VERSION_NUMBER_SOURCE` as well. We also set the offset value as 0 so that the calculated value can be applied directly. We can use the following custom script to extract this information.
```ruby
commit_message = ENV['AC_COMMIT_MESSAGE']
# extract commit message with regex
version = commit_message.match(/\[VERSION\] (.*)/)
if version
version = version[1]
open(ENV['AC_ENV_FILE_PATH'], 'a') { |f|
f.puts "AC_VERSION_NUMBER_SOURCE=env"
f.puts "AC_VERSION_OFFSET=0"
f.puts "AC_IOS_VERSION_NUMBER=#{version}"
}
end
```
Just add this script as a custom script above the Increment iOS Version Component. The type of the script must be set as ruby.
**Using Tags**
It is also possible to extract the version number from the Git tags. The following example assumes that the commit has a single tag. If you tag your version with `release-1.2.3`, the following script will extract the version number from the tag.
```ruby
commit_message = ENV['AC_COMMIT_TAGS']
version = commit_message.match(/release-(.*)/)
if version
version = version[1]
open(ENV['AC_ENV_FILE_PATH'], 'a') { |f|
f.puts "AC_VERSION_NUMBER_SOURCE=env"
f.puts "AC_VERSION_OFFSET=0"
f.puts "AC_IOS_VERSION_NUMBER=#{version}"
}
end
```
### Versioning Playground
You can use the below playground to test the effect of different options
---
## Android Build for UI Testing
The **Android Build for UI Testing** workflow step is tailored to [build your Android test application](https://developer.android.com/training/testing/instrumented-tests) using [Gradle Wrapper (gradlew)](https://docs.gradle.org/current/userguide/gradle_wrapper.html) for the designated architectures outlined in your project. This process employs the following gradle command: `./gradlew clean :assembleAndroidTest`
### Prerequisites
Before running the **Android Build for UI Testing** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | To initiate the **Android Build for UI Testing** process, the repository that needs to be built must be fetched from the branch. This is achieved as follows: Upon completion of the **Git Clone** step, it generates the `$AC_REPOSITORY_DIR` variable, which is then used as the input for the **Android Build for UI Testing** step. |
:::caution
If you're updating the version via Appcircle, ensure that the following step comes before the **Android Build for UI Testing** step:
- [**Android Increment Build and Version Number**](/workflows/android-specific-workflow-steps/increment-build-and-version-number)
:::
:::caution
If you're working with a **React Native Android** project, ensure that the following steps come before the **Android Build for UI Testing** step:
- [**Install Node**](/workflows/react-native-specific-workflow-steps/node-install)
- [**NPM/Yarn Commands**](/workflows/react-native-specific-workflow-steps/npm-yarn-commands)
:::
:::note
The **[Firebase Test Lab for Android](/workflows/android-specific-workflow-steps/firebase-test-lab)** step has been added as an example. You can use the APK you produce for UI testing in any component you choose.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| -------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If this step runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_MODULE` | This variable specifies the project module to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can locate the available modules for your project. For more information, please refer to this [Android document](https://developer.android.com/studio/projects#ApplicationModules). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `AC_APK_PATH` | Path for the generated **APK** file. This path will be created after the **Android Build for UI Testing** step runs. |
| `AC_TEST_APK_PATH` | Path for the generated `*androidTest.apk` file. This output can be utilized wherever necessary for UI testing. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-build-ui-test-component.git
---
## Android Build
The Appcircle Android Build step is designed to build your Android application for the architectures specified in your project.
### Prerequisites
Before running the **Android Build** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | To initiate the Android build process, the repository that needs to be built must be fetched from the branch. This is achieved as follows: Upon completion of the Git Clone step, it generates the `$AC_REPOSITORY_DIR` variable, which is then used as the input for the Android Build step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ----------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If this step runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_MODULE` | This variable specifies the project module to be build. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can locate the available modules for your project. For more information, please refer to [this Android document](https://developer.android.com/studio/projects#ApplicationModules). | Required |
| `$AC_VARIANTS` | This variable specifies the project variant to be build. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can find the available variants for your project. For more information, please refer to this [Android document](https://developer.android.com/build/build-variants). | Required |
| `$AC_OUTPUT_TYPE` | This variable specifies the output type for your build file (APK or AAB). This variable can also be set via the build [Configuration](/build/build-process-management/configurations). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. | Optional |
| `$AC_GRADLE_BUILD_EXTRA_ARGS` | Extra arguments were passed to build task. For more information, please refer to [this Gradle document](https://docs.gradle.org/current/userguide/writing_build_scripts.html#sec:extra_properties). | Optional |
:::info
If you have filled in the necessary variables in the **Configuration** section, you will not need to redefine these variables again in the Workflow. For more information about configurations, refer to the [Build Profile Configuration Overview](/build/build-process-management/configurations) document. The information you fill in the configuration will be used as input in the Android Build step. Please replace the example information with your own details:
1. The input corresponding to the 1st field: `$AC_MODULE`
2. The input corresponding to the 2nd field: `$AC_VARIANTS`
3. The input corresponding to the 3rd field: `$AC_OUTPUT_TYPE`
:::
:::tip
If you are using Gradle 4.3 and above in your project, you can just use the `--scan` flag in the build step to enable build scans. For existing projects, you may need to add the Gradle Scan (Gradle Enterprise) plugin. For more information, please refer to https://scans.gradle.com/
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `AC_APK_PATH` | Path for the generated **APK** file. This path will be created after the **Android Build** step runs. |
| `AC_AAB_PATH` | Path for the generated **AAB** file. This path will be created after the Android Build step runs and when `AAB` is selected. |
The resulting files will be either APK or AAB, depending on whether you choose the Android App in the project [Configuration](/build/build-process-management/configurations).
If your project has the [signing configuration](https://developer.android.com/studio/build/gradle-tips#sign-your-app) in Gradle, this step will generate a signed artifact.
:::caution
If you do not disable the **Android Sign** step and your project has no signing configuration defined in Gradle, your artifact will remain unsigned.
So, in order to sign your app using the keystore selected in the build configuration, you should enable the **Android Sign** step after **Android Build**.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-build-component.git
---
## FAQ
### How can I solve the `Out of memory error: Java heap memory` or set the heap memory during the build?
To resolve this issue, you need to adjust the Java heap size using the following parameters in the [system properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_system_properties):
> - [`-Xms:`](https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp999527), which sets the initial and minimum heap size
> - [`-Xmx:`](https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp999528), which sets the maximum heap size
>
> For example:
>
> ```bash
> java -Xms:1g -Xmx:1g MyApplication
> ```
>
> This starts up the JVM with a heap size fixed to 1 GB.
Please refer following documentation for more information:
https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/memman.html#wp1086978
You can implement this solution using one of the following methods:
#### Method 1: Using a Custom Script During the Build
If your project has varying heap size requirements, you can adjust the heap size during the build phase with a [**Custom Script**](/workflows/common-workflow-steps/custom-script) before the **Android Build** step. Your script should include the following command:
```bash
echo "org.gradle.jvmargs=-Xms1g -Xmx7168M" >> $AC_REPOSITORY_DIR/gradle.properties
```
- Adjust the `-Xms1g -Xmx7168M` values according to your project needs.
- Ensure the path `$AC_REPOSITORY_DIR/gradle.properties` matches your file's location. `$AC_REPOSITORY_DIR` represents the root project directory.
- You can extend the command with additional parameters as needed. For example, for Kotlin, you might add: `"org.gradle.jvmargs=-Xms1g -Xmx7168M kotlin.daemon.jvm.options=-Xms700m -Xmx7168M"`
#### Method 2: Modifying the `gradle.properties` File
If the heap size requirement is constant, you can directly add the following code to the end of your project's `gradle.properties` file. Feel free to modify this code to fit your specific project requirements:
```bash
org.gradle.jvmargs=-Xms1g -Xmx7168M
```
:::tip
Also, if you want to solve this issue via Android Studio you can follow this documentation:
[Android Developer documentation on adjusting heap size](https://developer.android.com/studio/intro/studio-config#adjusting_heap_size).
:::
### How can I generate an APK alongside an AAB?
To generate an APK alongside an AAB, you can use one of these two methods:
1. **Adding Another Android Build Step:**
1. **Configure for AAB:** Set up the build [configuration](/build/build-process-management/configurations) to generate an AAB.
2. **Add another Android Build Step:** Add an additional **Android Build** step, after the first **Android Build** step. To avoid confusion, you can add the generates file type to the step name.
3. **Modify Output Type:** Change the `$AC_OUTPUT_TYPE` [input variables](#input-variables) of the second **Android Build** step to APK. Now your build will generate an AAB and APK file.
If adding two **Android Build** steps makes the build process too lengthy, you can use the following alternative method:
2. **Generating APK from AAB file:**
1. **Configure for AAB:** Set up the build [configuration](/build/build-process-management/configurations) to generate an AAB.
2. **Add a Bundle Universal Apk Step:** Insert the [`Bundle Universal Apk`](/workflows/android-specific-workflow-steps/bundle-universal-apk) step in your workflow after the **Android Build** step.
3. **Configure the Bundle Universal Apk Step:** Complete the inputs for the **Bundle Universal Apk** step. To sign the APK via this step, you might need to upload your keystore file to the system if there is no uploaded.
4. **Convert AAB to APK:** This step will convert the generated AAB into an APK.
These steps will ensure that both an AAB and an APK are generated during your build process.
### How do I manage Android dependencies with artifactory repository manager?
Integrating an Artifactory repository manager into your Android build process is a robust approach to centralizing dependency management, improving build reliability, and ensuring reproducibility. Below, we’ll demonstrate this process using [**Nexus Repository Manager**](https://www.sonatype.com/products/sonatype-nexus-repository) as an example in conjunction with the Appcircle **Android Build** workflow step.
For detailed instructions on integrating Nexus Repository Manager with Appcircle, see our [Sonatype Nexus Configuration guide](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry#sonatype-nexus-configuration).
#### 1. Set up Nexus repository
- Ensure your Nexus Repository Manager is properly installed and configured. For hosted installations, follow the [official Nexus documentation](https://help.sonatype.com/repomanager3) to set up your Maven or Gradle repositories.
- Create a hosted Maven repository (or any repository format compatible with your project). Name the repository, for example, `android-repo`.
#### 2. Integrate Nexus into the Android project
In your Android project’s build.gradle (or settings.gradle if using Gradle Version Catalog), configure Nexus as a repository.
To fetch dependencies from a Nexus repository, add the following configuration to your Gradle file.
You can place this block in either the project-level or module-level `build.gradle` file, depending on your project structure.
If all modules in your project will use the same artifacts, it is recommended to place it in the project-level file:
```gradle
repositories {
maven {
url 'https://your-nexus-url/repository/android-repo/'
}
}
```
If the URL requires authentication for access, you can configure it as shown below:
```gradle
repositories {
maven {
url 'https://your-nexus-url/repository/android-repo/'
credentials {
username = "your-username"
password = "your-password"
}
}
}
```
To update your Gradle distribution URL with a Nexus repository, modify your `gradle-wrapper.properties` file and replace the `distributionUrl` value with the Nexus repository URL. Below is an example:
```gradle
distributionUrl=https://your-nexus-url/repository/gradle-distributions/gradle-8.8-bin.zip
```
#### 3. Run the build workflow
Trigger your build through Appcircle. The workflow will fetch dependencies from the Nexus repository as configured and compile the project with them. Logs will show dependency resolution status to confirm successful integration with Nexus.
---
## Android Dependency Report
The **Android Dependency Report** workflow step visualizes the whole dependency tree for every [configuration](https://docs.gradle.org/current/userguide/declaring_dependencies.html#sec:what-are-dependency-configurations) available in the project.
Rendering the dependency tree is particularly useful if you’d like to identify which dependencies have been resolved at runtime. It also provides you with information about any dependency conflict resolution that occurred in the process and clearly indicates the selected version. The dependency report always contains declared and transitive dependencies.
### Prerequisites
Before running the **Android Dependency Report** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|------------------------------------------------------------------------------------| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/build/build-process-management/configurations) | To initiate the **Android Dependency Report** process, the repository that needs to be built must be fetched from the branch. This is achieved as follows: Upon completion of the **Git Clone** step, it generates the `AC_REPOSITORY_DIR` variable, which is then used as the input for the **Android Dependency Report** step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ------------------------------ |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If this step runs after the [Git Clone](/build/build-process-management/configurations) step, the variable will be automatically populated. | Required |
| `$AC_MODULE` | This variable specifies the project module to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can locate the available modules for your project. For more information, please refer to this [Android document](https://developer.android.com/studio/projects#ApplicationModules). | Required |
| `$AC_DEPENDENCY_CONFIGURATION` | Specifies the [configuration](https://docs.gradle.org/current/userguide/declaring_dependencies.html#sec:what-are-dependency-configurations) to resolve for displaying dependency information. The default value is: `implementation`. | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. The default value is: `./` | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| ------------------------------------ | ---------------------------------------------------------------------- |
| `AC_ANDROID_DEPENDENCY_REPORT_PATH` | Specifies the path where the Android dependency report file is stored. |
:::danger
If you wish to review or download the **Android Dependencies Report**, you can find them directly from [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts). To do this, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step follows the **Android Dependency Report** workflow step.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-dependency-report.git
---
## Android Sign
**Android Sign** step signs your *APK* or *AAB* with the given Android *keystore* and exports a binary file compatible with Android devices.
:::info
This step follows the [**Android Build**](/workflows/android-specific-workflow-steps/android-build) step to sign the unsigned build output if the project doesn't include a *keystore*. If your project includes a *keystore*, the build application step will generate a signed artifact. If you do not disable this step, your artifact will be unsigned and then re-signed using the *keystore* selected in the **Configuration** or in this step.
:::
:::caution Debug Variant Signing
As noted in the [**Android Developer documentation**](https://developer.android.com/build/build-for-release):
> If the build variant you've selected is a debug build type, then the APK is signed with a debug key and it's ready to install. If you've selected a release variant, then, by default, the APK is unsigned and you must manually [sign the APK](https://developer.android.com/studio/publish/app-signing).
When you build your app with the **debug** variant and select a keystore in [configurations](/build/platform-build-guides/building-android-applications#signing), the **Android Sign** step will replace the default debug signing files and re-sign the app using the specified keystore files.
:::
### Prerequisites
Before running the **Android Sign** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step relies on the **Android Build** step and the **Git Clone** step is necessary for the **Android Build** step to run successfully. |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | The app required for this step is generated by the **Android Build** (or alternative build steps). |
:::caution
If a step other than the **Android Build** step is used to build an app, then the **Android Sign** step depends on this step.
:::
:::danger
To share the signed apps created as an output of this step or to view them on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your workflow after this step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-----------------------------|----------------------------------------------|--------|
| `$AC_APK_PATH` | The path of the *APK* file. This path is automatically generated in the **Android Build** step. You may need to modify this input variable to provide a different path. | Required |
| `$AC_AAB_PATH` | The path of the *AAB* file. This path is automatically generated in the **Android Build** step. You may need to modify this input variable to provide a different path. | Required |
| `$AC_ANDROID_KEYSTORE_PATH` | *Keystore* file can be selected in the **Configuration**. This value will be auto-generated depending on your *keystore* file selection in [signing configuration on Appcircle](/build/platform-build-guides/building-android-applications#signing). | Required |
| `$AC_ANDROID_KEYSTORE_PASSWORD` | Password for the selected *keystore* file. This value will be auto-generated based on your *keystore* file selection. | Required |
| `$AC_ANDROID_ALIAS` | Alias name for the selected *keystore* file. This value will be auto-generated depending on your **Configuration** |
| `$AC_ANDROID_ALIAS_PASSWORD` | Alias password for the selected *keystore* file. This value will be auto-generated depending on your **Configuration** |
| `$AC_V2_SIGN` | Defaults to false. Set true if the signature should be done using apksigner instead of jarsigner. For more information, [Apps targeting Android 11 require APK Signature Scheme v2](https://developer.android.com/about/versions/11/behavior-changes-11#minimum-signature-scheme) or the [Appcircle V2 Sign](/build/platform-build-guides/building-android-applications/android-signing-for-google-play#enable-v2-sign-in-appcircle) documentation. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|------------------------|---------------------------------------------|
| `AC_SIGNED_APK_PATH` | Path for the signed *APK* file output. If an *APK* file is provided as input, the signed app will also be in *APK* format. |
| `AC_SIGNED_AAB_PATH` | Path for the signed App Bundle file output. If an *AAB* file is provided as input, the signed app will also be in *AAB* format. |
:::tip
If both input value types (*AAB* and *APK*) are provided, the same type of signed app will be generated for both.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-sign-component.git
## FAQ
The **Android Sign** step is often where most Android-related issues arise. The most frequently asked questions are listed below:
### “Package invalid” Error After Installing an APK
Users may encounter a **“App not installed as package appears to be invalid.”** error when attempting to launch an application after successfully installing an APK on an Android device. Although the installation appears to complete without errors, the app fails to open.
This issue is typically related to APK integrity, signing configuration, or device compatibility.
Possible causes and solutions:
#### 1. APK Is Signed Incorrectly or Not Signed
**Cause:**
Android requires all APKs to be properly signed. An incorrect signing configuration or a missing signature can result in a “Package invalid” error at runtime.
**How to Check:**
* Use `apksigner verify` or `jarsigner -verify` to confirm the APK is signed.
* Verify that the correct **keystore**, **key alias**, and **passwords** are used in Appcircle.
**Solution:**
* Ensure the **Android Sign** step is configured correctly in your Appcircle workflow.
* Confirm that the signing key matches the one used for previous releases of the app.
#### 2. APK Is Corrupted or Incomplete
**Cause:**
The APK file may be partially uploaded, corrupted during download, or incorrectly generated during the build process.
**How to Check:**
* Try installing the APK on another device or emulator.
* Verify the APK file size and compare it with previous successful builds.
**Solution:**
* Rebuild the APK from Appcircle.
* Re-download the APK and ensure the transfer process completes successfully.
#### 3. Package Name Mismatch
**Cause:**
The APK’s `applicationId` (package name) does not match the already installed app on the device, or conflicts with an existing package signed with a different key.
**How to Check:**
* Inspect the `applicationId` in your Gradle configuration.
* Check whether another version of the app with the same package name is already installed on the device.
**Solution:**
* Uninstall any existing version of the app before installing the new APK.
* Ensure consistency between the package name and the signing key across builds.
#### 4. Unsupported Architecture or Android Version
**Cause:**
The APK targets an ABI (CPU architecture) or Android SDK version that is not supported by the device.
**How to Check:**
* Verify the device’s Android version and CPU architecture (ARM, ARM64, x86).
* Inspect the APK’s `minSdkVersion`, `targetSdkVersion`, and supported ABIs.
**Solution:**
* Build a universal APK or ensure the correct ABI splits are included.
* Adjust `minSdkVersion` if the device runs an older Android version.
#### Summary
A **“Package invalid”** error is most commonly related to signing issues, corrupted APK files, package name conflicts, or device incompatibility. Carefully validating the signing configuration and build outputs in Appcircle usually resolves the issue quickly.
If the problem persists after verifying the points above, rebuilding the application with a clean workflow and rechecking the **Android Sign** step is strongly recommended.
---
## Android Unit Tests
The **Android Unit Tests** workflow step executes the unit tests within your project, ensuring comprehensive test coverage. The results of these tests will be included in the artifact archive for further analysis and review.
Please check out this document for more information: [Running Android Unit Tests](/continuous-testing/android-testing/running-android-unit-tests)
### Prerequisites
Before running the **Android Unit Tests** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | To initiate the **Android Unit Tests** process, the repository that needs to be built must be fetched from the branch. This is achieved as follows: Upon completion of the **Git Clone** step, it generates the `$AC_REPOSITORY_DIR` variable, which is then used as the input for the **Android Unit Tests** step. |
:::danger
If you wish to view the test results on Appcircle's Test Reports page, it is essential to use the [Test Reports for Android](/workflows/android-specific-workflow-steps/test-reports-for-android) step after the **Android Unit Tests**. Please check out this document for more information: [Generating Test Report](/continuous-testing/android-testing/running-android-unit-tests#generating-test-report).
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| -------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If this step runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_MODULE` | This variable specifies the project module to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can locate the available modules for your project. For more information, please refer to this [Android document](https://developer.android.com/studio/projects#ApplicationModules). | Required |
| `$AC_VARIANTS` | This variable specifies the project variant to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can find the available variants for your project. For more information, please refer to this [Android document](https://developer.android.com/build/build-variants). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. The default value is: `./`. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| ---------------------- | -------------------------------------------------------------- |
| `AC_TEST_RESULT_PATH` | Specifies the directory where your JUnit XML report is stored. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-unit-test-component.git
---
## App Center Android Distribute
[App Center Distribute for Android](https://learn.microsoft.com/en-us/appcenter/sdk/distribute/android) enables developers to distribute their Android applications to testers and stakeholders for testing purposes. It provides a centralised dashboard where developers can upload their app packages, manage distribution to specific groups of testers, collect feedback, and monitor installation and usage metrics. With App Center Distribute, developers can streamline the testing process, gather valuable insights, and iterate on their apps before releasing them to the public.
The Appcircle **App Center Android Distribute** step allows you to seamlessly distribute your Android applications and mapping files to [App Center](https://appcenter.ms).
:::caution
Please note that you can also distribute your app via Appcircle. Utilizing Appcircle's distribution modules enhances manageability within the platform.
For more details, please refer to the following links:
- [Appcircle Testing Distribution](/testing-distribution)
- [Appcircle Enterprise App Store](/enterprise-app-store)
- [Appcircle Publish](/publish-to-stores-module)
:::
### Prerequisites
Before running the **App Center Android Distribute** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | The app required for this step is generated by the Android Build (or alternative build steps). |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If you intend to use a signed app, this step must be executed beforehand to process the output. If your app is already signed in the build step, you can skip this step. |
:::danger
If a step other than the **Android Build** or **Android Sign** step is used to build or sign the app, then the **App Center Android Distribute** step depends on this step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_APPCENTER_TOKEN` | Specifies the Appcenter API token. For more detail, please refer to this [App Center documentation](https://learn.microsoft.com/en-us/appcenter/api-docs/). | Required |
| `$AC_APPCENTER_APK_PATH` | Specifies the full path of the app build. Both APK (`$AC_APK_PATH`, `$AC_SIGNED_APK_PATH`) and AAB (`$AC_AAB_PATH`, `$AC_SIGNED_AAB_PATH`) files are supported. | Required |
| `$AC_APPCENTER_OWNER` | Specifies the owner of the app on the App Center. The app's owner can be identified in its URL, such as `https://appcenter.ms/users/JohnDoe/apps/myapp` for a user-owned app (where **JohnDoe** is the owner) and `https://appcenter.ms/orgs/Appcircle/apps/myapp` for an org-owned app (the owner is **Appcircle**). | Required |
| `$AC_APPCENTER_APPNAME` | The name of the app is in the App Center. The app's name can be identified in its URL, such as `https://appcenter.ms/users/JohnDoe/apps/myapp` for a user-owned app (where **myapp** is the app name) and `https://appcenter.ms/orgs/Appcircle/apps/myapp` for an org-owned app (the owner is **myapp**). | Required |
| `$AC_APPCENTER_GROUPS` | Specifies the group names in the App Center. For more than one group name to be distributed, you must separate them with a comma. For example: `group0,group1,..,groupn` | Optional |
| `$AC_APPCENTER_STORE` | Specifies the store name. For example: `App Store`, `Google Play`, and `Intune`. | Optional |
| `$AC_APPCENTER_RELEASE_NOTES_PATH` | Specifies the release note path. If you use the [**Publishing Release Notes**](/workflows/common-workflow-steps/publish-release-notes) component before this step, `release-notes.txt` will be used as release notes. The default value is `AC_OUTPUT_DIR/release-notes.txt`. | Optional |
| `$AC_APPCENTER_MAPPING_PATH` | Specifies the path of the `mapping.txt` file. Example: `$AC_REPOSITORY_DIR/build/app/outputs/mapping/release/mapping.txt`. | Optional |
| `$AC_APPCENTER_MANDATORY` | Specifies whether the update should be considered mandatory. The options are `true` and `false`. The default value is `false`. | Optional |
| `$AC_APPCENTER_NOTIFY` | Notify testers of this release. The options are `true` and `false`. The default value is `false`. | Optional |
| `$AC_APPCENTER_VERSION` | [App Center CLI](https://learn.microsoft.com/tr-tr/appcenter/cli/) version. The latest version will be used if no version is set. | Optional |
| `$AC_APPCENTER_EXTRA` | Extra command-line arguments for App Center. For example, add `--debug` for verbose logs. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-appcenter-distribute-component.git
---
## App Post-Processor
# Android App Post-Processor
This step performs the necessary system operations to identify and process the Android output binary files.
:::warning
This step also verifies whether the app is signed or not. If this step is not included in your workflow or if it is determined that there is no signed app as a result of this step, **the app cannot be distributed**.
:::
:::info Debug Variant Signing
As noted in the [**Android Developer documentation**](https://developer.android.com/build/build-for-release):
> If the build variant you've selected is a debug build type, then the APK is signed with a debug key and it's ready to install. If you've selected a release variant, then, by default, the APK is unsigned and you must manually [sign the APK](https://developer.android.com/studio/publish/app-signing).
This means that when you build your app with the **debug** variant, the **Android Post Processor** step in Appcircle will recognize the app as already signed, even if it was not signed in Appcircle or your repository.
:::
### Prerequisites
The workflow steps that need to be executed before running the **Android App Post-Processor** workflow step, along with their respective reasons, are listed in the table below.
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step relies on the **Android Build** step and the **Git Clone** step is necessary for the **Android Build** step to run successfully. |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | To process Android output, these outputs must be obtained from the build step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If a signed app is created, this step needs to be run beforehand to process this output. |
:::caution
If a step other than the **Android Build** or **Android Sign** step is used to build or sign the app, then the **Android App Post-Processor** step depends on this step.
:::
### Input Variables
There is no need to enter an input for this component. It will process Android files under the output directory (`$AC_OUTPUT_DIR`).
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|----------------------------------------|---------------------------------------------------|
| `AC_ANDROID_POST_PROCESS_OUTPUT_PATH` | Specifies the application post process file path. This file specifies the base name for each app and whether it is signed or not. |
:::info
The output post-processing JSON file should adhere to the following structure:
```jsx title="ac_post_process_output.json"
[
{
"signed": true|false,
"app_name": "app base name"
},
{...}
]
```
:::
:::caution
To share the signed apps created as a result of this step or to view them on the **Download Artifacts** page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your Workflow after this step.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-post-process-component.git
---
## Appdome Build-2Secure for Android
[Appdome Build-2Secure](https://apis.appdome.com/docs/integrate-in-cicd) automates the integration of advanced security features, adaptive protections, code-signing, and certification processes into mobile applications, enhancing security without the need for manual coding or code analysis.
For detailed information on the benefits that **Appdome Build-2Secure** adds to your mobile app, please refer to the following blog post:
https://appcircle.io/blog/elevate-your-mobile-app-security-with-appdome-integration
### Prerequisites
Before running the **Appdome Build-2Secure for Android** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | The app required for this step is generated by the **Android Build** (or alternative build steps). |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If you intend to use a signed app, this step must be executed beforehand to process the output. If your app is already signed in the build step, you can skip this step. |
:::danger
If a step other than the **Android Build** or **Android Sign** step is used to build or sign the app, then the **Appdome Build-2Secure for Android** step depends on this step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| `$AC_APPDOME_APP_PATH` | Specifies the URL or path of the app accessible from Appcircle. Default values are `$AC_APK_PATH` or `$AC_AAB_PATH` obtained from the **Android Build** step. | Required |
| `$AC_APPDOME_API_KEY` | Specifies the Appdome API key, which must be obtained from the Appdome account. Refer to [this document](https://apis.appdome.com/docs/getting-started#getting-and-resetting-your-appdomes-build2secure-api-token) for more information. | Required |
| `$AC_APPDOME_FUSION_SET_ID` | Specifies the Appdome Fusion Set ID, which must be obtained from the Appdome account. Refer to [this document](https://apis.appdome.com/docs/getting-started#getting-a-fusion-sets-id) for more information. | Required |
| `$AC_APPDOME_TEAM_ID` | Specifies the Appdome Team ID. Insert your team's ID if using a team account. Refer to [this document](https://apis.appdome.com/docs/getting-started#getting-a-teams-id) for more information. | Optional |
| `$AC_APPDOME_SIGN_METHOD` | Specifies the Appdome app signing method. Options are: `On-Appdome`, `Private-Signing`, and `Auto-Dev-Signing`. The default value is `On-Appdome`. For details, refer to [this document](https://www.appdome.com/how-to/devsecops-automation-mobile-cicd/automated-signing-secured-android-ios/automatic-code-signing-for-secured-android-apps-on-appdome/). | Required |
| `$AC_APPDOME_GP_SIGNING` | Specifies whether the app should be signed for Google Play. If set to `true`, the app is prepared for distribution via Google Play App Signing and requires the `AC_GOOGLE_SIGN_FINGERPRINT` environment variable to be defined. More details are available [here](https://www.appdome.com/how-to/devsecops-automation-mobile-cicd/automated-signing-secured-android-ios/automatic-code-signing-for-secured-android-apps-on-appdome/). | Required |
| `$AC_GOOGLE_SIGN_FINGERPRINT` | Fingerprint (SHA-1 or SHA-256) of the Google Play App Signing certificate. Required when Google Play Signing is enabled. This value must be defined as a secret under the [**Environment Variables**](/build/build-environment-variables). | Optional |
| `$AC_APPDOME_BUILD_LOGS` | If `true`, it enables diagnostic logs for troubleshooting secured apps. Details are available [here](https://www.appdome.com/how-to/devsecops-automation-mobile-cicd/test-secured-mobile-apps/appdome-diagnostic-logs-for-troubleshooting-secured-apps/). | Required |
---
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `AC_APPDOME_SECURED_APK_PATH` | Specified path of the secured APK file produced by **Appdome Build-2Secure**. This is available when the `Signing Method` is set to `On-Appdome` or `Private-Signing`. |
| `AC_APPDOME_SECURED_AAB_PATH` | Specified path of the secured AAB file produced by **Appdome Build-2Secure**. This is available when the `Signing Method` is set to `On-Appdome` or `Private-Signing`. |
| `AC_APPDOME_PRIVATE_SIGN_SCRIPT_PATH` | Specified path of the `.sh` sign script file produced by **Appdome Build-2Secure**. This is available when the `Signing Method` is set to `Auto-Dev-Signing`. |
| `AC_APPDOME_CERTIFICATE_PATH` | Specified path of the [**_Certified Secure_**](https://www.appdome.com/certified-secure-mobile-devsecops-certification/) certificate produced by **Appdome Build-2Secure** for your app is provided as a PDF file. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-appdome-component.git
---
## AppSweep Mobile Security Testing
[AppSweep Mobile Security Testing](https://www.guardsquare.com/appsweep-mobile-application-security-testing) is a comprehensive security solution designed to protect mobile applications from various threats and vulnerabilities. It offers advanced scanning capabilities to identify security flaws, privacy concerns, and compliance issues within mobile apps. By thoroughly analysing app code, configurations, and dependencies, AppSweep helps developers and organisations mitigate risks and ensure the integrity and safety of their mobile applications.
The Appcircle **AppSweep Mobile Security Testing** step allows you to comprehensively analyse your mobile applications for potential security vulnerabilities, privacy risks, and compliance issues, thereby ensuring the robustness and integrity of your software before deployment.
### Prerequisites
Before running the **AppSweep Mobile Security Testing** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The **AppSweep Mobile Security Testing** step requires the repository to be cloned from the Git provider before it can function properly. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ---------------------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_APPSWEEP_API_KEY` | Specifies the API key of the AppSweep account. You can create an API key in the API Keys section of your project settings on the AppSweep website. | Required |
| `$AC_APPSWEEP_VARIANT` | Specifies the project variant to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can find the available variants for your project. For more information, please refer to this [Android document](https://developer.android.com/build/build-variants). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| ------------------ | ------------------------------------------------------------- |
| `AC_APPSWEEP_URL` | A direct link to the scan results is on the AppSweep website. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-appsweep-component.git
---
## Azure DevOps Bot for Detekt Report
The **Azure DevOps Bot for Detekt Report** step analyzes your [Detekt report](https://detekt.dev/docs/introduction/reporting/) and posts the details to an open pull request in [Azure DevOps](https://learn.microsoft.com/en-us/azure/devops/). It also allows you to modify the [pull request status](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-statuses).
:::caution
[Danger](https://danger.systems/) operates on a similar principle, allowing use of the [Danger step](/workflows/common-workflow-steps/danger) with platforms such as [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), and [Bitbucket](https://bitbucket.org/product/guides/getting-started/overview#a-brief-overview-of-bitbucket). However, Danger currently does not support Azure DevOps.
For more information, refer to the Appcircle blog post about Danger:
- [**Danger in CI: Automate Your Mobile Code Reviews**](https://appcircle.io/blog/danger-in-ci-automate-your-mobile-code-reviews).
:::
### Prerequisites
Before running the **Azure DevOps Bot for Detekt Report** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|--------------------------------------------------|
| [**Detekt**](/workflows/android-specific-workflow-steps/detekt) | In order to generate the [Detekt report](https://detekt.dev/docs/introduction/reporting/), the **Detekt** step must be executed beforehand. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|----------------------------|------------------------------------------------|--------|
| `$AC_AZURE_ORG_NAME` | Specifies the name of the Azure DevOps organization. You can find it in the Azure DevOps URL: `https://dev.azure.com/{Your_Organization}`. Check out [this document](https://learn.microsoft.com/en-us/answers/questions/1080972/find-organization-name) to locate the organization name. | Required |
| `$AC_AZURE_PROJECT_NAME` | Specifies the name of the Azure DevOps project. You can find it in the Azure DevOps URL: `https://dev.azure.com/{Your_Organization}/{Your_Project}`. For more information about Azure DevOps projects, refer to [this document](https://learn.microsoft.com/en-us/azure/devops/user-guide/project-admin-tutorial?toc=%2Fazure%2Fdevops%2Forganizations%2Ftoc.json&view=azure-devops). | Required |
| `$AC_AZURE_REPO_NAME` | Specifies the name of the Azure DevOps repository. Check out [this document](https://learn.microsoft.com/en-us/azure/devops/repos/git/repository-settings) for more details about Azure DevOps repositories. | Required |
| `$AC_AZURE_BASE_URL` | Specifies the base URL of Azure DevOps. The default value is `https://dev.azure.com`. | Required |
| `$AC_AZURE_API_KEY` | Specifies the API key for Azure DevOps. Refer to [this document](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate) for details on how to obtain it. | Required |
| `$AC_DETEKT_FILE_PATH` | Specifies the file path of the Detekt report. If you used the **Detekt** step in the previous stage, this section will be automatically filled. The default value is `$AC_DETEKT_OUTPUT_PATH`, which represents the output of the **Detekt** step. | Required |
| `$AC_DOMAIN_NAME` | Specifies the domain name of Appcircle. The default value is `my.appcircle.io`, which is the domain for Appcircle Cloud. | Required |
| `$AC_AZURE_API_VERSION` | Specifies the version of the Azure API, for example: `7.1`. Refer to the [REST API versioning](https://learn.microsoft.com/en-us/azure/devops/integrate/concepts/rest-api-versioning) document for more information. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-azure-bot-for-detekt-component.git
---
## BrowserStack App Automate - Espresso
[BrowserStack App Automate - Espresso](https://www.browserstack.com/docs/app-automate/espresso/getting-started#4-execute-espresso-tests) is a testing solution provided by BrowserStack specifically designed for Android applications using the [Espresso](https://developer.android.com/training/testing/espresso) testing framework. It allows developers to run automated tests for their Android apps across a wide range of real devices hosted in the BrowserStack cloud infrastructure. This service enables efficient and comprehensive testing of Android applications, covering various scenarios and device configurations to ensure app quality and performance.
The Appcircle **BrowserStack App Automate - Espresso** step allows you to run automated tests on Android apps using the Espresso framework on real devices in the BrowserStack cloud.
### Prerequisites
Before running the **BrowserStack App Automate - Espresso** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Android Build for UI Testing**](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) | The **Android Build for UI Testing** step must be executed to obtain the necessary Android app outputs for processing. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_BROWSERSTACK_USERNAME` | Specifies the username of the BrowserStack account. Refer to [BrowserStack - Authenticate Test Runs](https://www.browserstack.com/docs/automate/cypress/authentication) for more details. | Required |
| `$AC_BROWSERSTACK_ACCESS_KEY` | Specifies the access key for the BrowserStack account. Refer to [BrowserStack - Authenticate Test Runs](https://www.browserstack.com/docs/automate/cypress/authentication) for more details. | Required |
| `$AC_APK_PATH` | Specifies the path of the **APK** file produced in the Appcircle workflow to be sent to BrowserStack. This field is automatically populated if the **Android Build for UI Testing** step was executed in previous steps. | Required |
| `$AC_TEST_APK_PATH` | Specifies the path of the **test APK** file produced in the Appcircle workflow to be sent to BrowserStack. This field is automatically populated if the **Android Build for UI Testing** step was executed in previous steps. | Required |
| `$AC_BROWSERSTACK_PAYLOAD` | Specifies the payload to be sent to BrowserStack from your Appcircle workflow.`$AC_BROWSERSTACK_APP_URL` and `$AC_BROWSERSTACK_TEST_URL` will be auto generated. Please refer to the [documentation](https://www.browserstack.com/docs/app-automate/api-reference/espresso/builds#execute-a-build) for more details about the payload. | Optional |
| `$AC_BROWSERSTACK_TIMEOUT` | Specifies the timeout in seconds for checking the BrowserStack plan. The default value is `600`. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-browserstack-espresso-component.git
---
## Bundle Universal Apk
The **Bundle Universal Apk** step creates a universal **APK** from an [**AAB**](https://developer.android.com/guide/app-bundle) file.
For additional details, please refer to the [**Bundletool**](https://developer.android.com/tools/bundletool) documentation.
### Prerequisites
Before running the **Bundle Universal Apk** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | This step is necessary to generate the **AAB** app that will be converted to an **APK**. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If you intend to use a signed app, this step must be executed beforehand to process the output. If your app is already signed in the build step, you can skip this step. |
:::caution
If a step other than the **Android Build** or **Android Sign** step is used to build or sign the app, then the **Bundle Universal Apk** step depends on this step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_BUNDLETOOL_VERSION` | Specifies the version of **Bundletool** to install. The default value is `1.11.2`. To install a different version, please refer to [this document](https://github.com/google/bundletool/releases). | Required |
| `$AC_SIGNED_AAB_PATH` | The optional path of the signed **AAB** file to convert the **APK**. If this step runs after the **Android Sign** step, the variable will be automatically populated. If the signing takes place in the build step and you want to directly enter the **APK** you received from the **Android Build** step here, you can change the variable to `$AC_APK_PATH`. | Required |
| `$AC_ANDROID_KEYSTORE_PATH` | (Autogenerated) The path to the keystore file selected via the build [Configuration](/build/build-process-management/configurations). For more details, please refer to the [Android Keystores](/signing-identities/android-keystores) documentation. | Required |
| `$AC_ANDROID_KEYSTORE_PASSWORD` | (Autogenerated) The password for the keystore file, generated according to the build [Configuration](/build/build-process-management/configurations). For more details, please refer to the [Android Keystores](/signing-identities/android-keystores) documentation. | Required |
| `$AC_ANDROID_ALIAS` | (Autogenerated) The alias for the Android Keystore, generated according to the build [Configuration](/build/build-process-management/configurations). For more details, please refer to the [Android Keystores](/signing-identities/android-keystores) documentation. | Required |
| `$AC_ANDROID_ALIAS_PASSWORD` | (Autogenerated) The password for the Android Keystore alias, generated according to the build [Configuration](/build/build-process-management/configurations). For more details, please refer to the [Android Keystores](/signing-identities/android-keystores) documentation. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| --------------------- | -------------------------------- |
| `AC_SIGNED_APK_PATH` | Path of the signed **APK** file. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-bundletool-component.git
---
## Detekt
[Detekt](https://detekt.dev/) is a static code analysis tool for [Kotlin](https://kotlinlang.org/) used in Android development. It identifies issues, enforces standards, and improves code quality by checking for code smells, performance issues, bugs, and adherence to best practices, with configurable rules and plugins for customization. Its integration into workflows promotes clean and efficient Kotlin codebases.
The Appcircle Detekt step executes the Detekt Gradle task. For further details, please refer to the [Run detekt using the Detekt Gradle Plugin](https://detekt.dev/docs/gettingstarted/gradle/) documentation.
### Prerequisites
Before running the **Detekt** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The **Git Clone** step is necessary to fetch the repository before conducting code checks and must precede the **Detekt** step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_DETEKT_TASK` | Specifies the name of the Detekt task. The default value is `detekt`. | Required |
| `$AC_DETEKT_EXTRA_PARAMETERS` | Additional command-line parameters for Detekt. | Optional |
| `$AC_DETEKT_SAVE_REPORT` | Specifies whether the Detekt report will be saved. If set to `true`, report files will be saved into the artifacts folder. The default value is `false`. | Optional |
| `$AC_DETEKT_OUTPUT_PATH` | Specifies the Detekt output path. If the `$AC_DETEKT_SAVE_REPORT` input is set to `true` and this value is not defined, then `/build/reports` will be used as the default path. | Optional |
:::danger
If `$AC_DETEKT_SAVE_REPORT` is set to `true`, place the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step after the **Detekt** step to ensure proper transfer of outputs to the [Download Artifacts](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) section.
:::
### Output Variables
The output is not stored in any variable. If `AC_DETEKT_SAVE_REPORT` is set to `true`, the file output will be saved in the `$AC_PROJECT_PATH/$AC_MODULE/build/reports` directory (check these variables on the [Appcircle-Specific Environment Variables](/environment-variables/appcircle-specific-environment-variables#ios--android-common-environment-variables) page). If you've added the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step after the **Detekt** step, this output will also be accessible in the [Download Artifacts](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) section.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-detekt-component.git
---
## Firebase Test Lab for Android
Appcircle is integrated with the [Firebase Test Lab](https://firebase.google.com/products/test-lab) for continuous testing. Your app can be built in Appcircle and directly deployed to the Firebase Test Lab to run automated tests.
## Prerequisites
Before running the **Firebase Test Lab for Android** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Android Build for UI Testing**](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) | The **Android Build for UI Testing** step must be executed to obtain the necessary Android application outputs for processing. |
In addition to the steps you need to run on Appcircle, there are also adjustments you need to make on the Firebase Test Lab side. These adjustments can be made as follows:
### 1. Setting Up a Firebase Project and a Service Account
To begin with the [Firebase Test Lab](https://firebase.google.com/products/test-lab), you need to have an associated Firebase Project, which is created in the [Firebase console](https://console.firebase.google.com). Go to the console, press the `Add Project` button, and specify the project name and other settings:
Once your project is created, go to the [Google Cloud Platform console](https://console.cloud.google.com/iam-admin/serviceaccounts/) to create a service account. Press the `Create Service Account` button and follow the prompts to create a service account with the **Editor** role:
After the service account is created, click on the three-dot (**⋮**) menu next to the service account and press `Create Key`.
Select the key format as `JSON` and download the created key. This key will be used by Appcircle to deploy apps to the Firebase Test Lab.
As the final step, go to the [Google Developers Console API Library page](https://console.developers.google.com/apis/library) and find and enable the following APIs:
- Google Cloud Testing API
- Cloud Tool Results API.
### 2. Build Workflow Configuration for Firebase Test Lab
To utilize the Firebase Test Lab in your builds, open the [workflow editor](/workflows) and add the **Firebase Test Lab for Android** step after the build or sign steps. If you want to run instrumentation tests, also add the **Android Build for UI Testing** step before the **Firebase Test Lab for Android** step.
:::caution
If you want to run **robo** tests, it is highly recommended not to add the **Android Build for UI Testing** step.
:::
If you want to use the UI Test Build output or the Signed Build output in the Firebase Test Lab, add any of these steps before the **Firebase Test Lab for Android** step and take note of the output path of these steps. You will need this environment variable for testing configuration.
## Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|---------------------------|----------------------------------------------------|----------|
| `$AC_FIREBASE_PROJECT_ID` | Specifies the name of the Firebase project created. | Optional |
| `$AC_FIREBASE_KEY_FILE` | Specifies the name of the key file uploaded as an environment variable (`$` is required before the key name). | Optional |
| `$AC_FIREBASE_TEST_TYPE` | Specifies the test type. `robo` and `instrumentation` are supported. | Required |
| `$AC_FIREBASE_BUCKET_NAME`| Specifies the bucket name to store the test results in a Google Cloud Storage bucket. | Optional |
| `$AC_APK_PATH` | The default value is the APK produced by the **Android Build** or **Android Build for UI Testing** step. You can specify a different environment variable to use the APK files produced in other steps. | Optional |
| `$AC_TEST_APK_PATH` | Specify the environment variable as the path of the APK build for UI testing. The default value is the APK produced by the **Android Build for UI Testing** step. | Optional |
| `$AC_FIREBASE_EXTRA_ARGS` | Firebase Test Extra Arguments `(e.g., --timeout=3m)`. For further configuration of the test run, please refer to the [Google Cloud CLI](https://cloud.google.com/sdk/gcloud/reference/firebase/test/android/run) documentation. | Optional |
Once everything is set up, press save to save your step configuration. Then you can configure and run your build just like any other app.
## Output Variables
This step does not produce any output as a variable. However, after your build is done, you can view the results of the **Firebase Test Lab for Android** step in the build logs.
The full details of the tests are accessible in the [Firebase console](https://console.firebase.google.com) and in your Google Cloud Storage bucket for analysis.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-firebase-test-lab-component
---
## Gradle Runner
The **Gradle Runner** workflow step executes the specified [Gradle task](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html) provided by the user.
### Prerequisites
Before running the **Gradle Runner** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | To initiate the **Gradle Runner** process, the repository that needs to be built must be fetched from the branch. This is achieved as follows: Upon completion of the **Git Clone** step, it generates the `$AC_REPOSITORY_DIR` variable, which is then used as the input for the **Gradle Runner** step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ---------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If this step runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_MODULE` | This variable specifies the project module to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can locate the available modules for your project. For more information, please refer to this [Android document](https://developer.android.com/studio/projects#ApplicationModules). | Required |
| `$AC_VARIANTS` | This variable specifies the project variant to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can find the available variants for your project. For more information, please refer to this [Android document](https://developer.android.com/build/build-variants). | Required |
| `$AC_OUTPUT_DIR` | Specifies the directory path for the generated app files. | Required |
| `$AC_GRADLE_TASK` | Specifies the name of the Gradle task. Refer to the documentation for detailed information: [List available tasks](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#list_available_tasks). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. The default value is: `./` | Optional |
| `$AC_GRADLE_TASK_EXTRA_PARAMETERS` | Extra arguments were passed to the Gradle task. For more information, please refer to [this Gradle document](https://docs.gradle.org/current/userguide/writing_build_scripts.html#sec:extra_properties). | Optional |
### Output Variables
As the output may vary depending on the task you execute, there is no specific output defined by default.
:::caution
If there is an output generated, ensure to use the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step afterward to ensure it is included in the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) page.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-gradle-task-component.git
---
## Android Increment Build and Version Number
This component increments the `versionCode` and `versionName` according to the provided strategies.
The **Android Increment Build and Version Number** step is managed with **Android Versioning**. Detailed information about this step, such as [**Prerequisites**](/versioning/android-version#enabling-version-management), [**Input Variables**](/versioning/android-version#input-variables), and [**Output Variables**](/versioning/android-version#output-variables) variables, can be found in the document below:
- [**Understanding Android Versioning**](/versioning/android-version)
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-build-version-increment-component.git
---
## Android Specific Workflow Steps
The steps listed below are specific to the Android build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [Android Build for UI Testing](/workflows/android-specific-workflow-steps/android-build-for-ui-testing)
Builds your test applications with gradlew. Runs `./gradlew clean ${module}:assembleAndroidTest`.
## [Android Build](/workflows/android-specific-workflow-steps/android-build)
This step builds your Android application for the architectures specified in your project.
:::tip
If you are using Gradle 4.3 and above in your project, you can just use the `--scan` flag in the build step to enable build scans. For existing projects, you may need to add the Gradle Scan (Gradle Enterprise) plugin. For more information, please refer to [https://scans.gradle.com/](https://scans.gradle.com)
:::
## [Android Dependency Report](/workflows/android-specific-workflow-steps/android-dependency-report)
This step visualizes the whole dependency tree for every [configuration](https://docs.gradle.org/current/userguide/declaring_dependencies.html#sec:what-are-dependency-configurations) available in the project.
## [Android Sign](/workflows/android-specific-workflow-steps/android-sign)
This step signs your APK or App Bundle with the given Android keystore and exports a binary file compatible with Android devices.
## [Android Unit Tests](/workflows/android-specific-workflow-steps/android-unit-tests)
This step runs the unit tests of the project.
## [App Center Android Distribution](/workflows/android-specific-workflow-steps/app-center-android-distribution)
Distribute APK, AAB, and mapping files to [App Center](https://appcenter.ms/). You need to enter your token, owner, app, and group names to distribute your binaries.
## [Android App Post-Processor](/workflows/android-specific-workflow-steps/app-post-processor)
This step performs necessary system operations to identify and process the Android output binary files.
## [Appdome Build-2Secure for Android](/workflows/android-specific-workflow-steps/appdome-build-to-secure-for-android)
Appdome Build-2Secure is a comprehensive automated solution that seamlessly integrates advanced security features, adaptive protections, code-signing, and certification processes into mobile applications, enhancing security without the need for manual coding or code analysis.
For detailed information on the benefits Appdome Build-2Secure adds to your mobile app, refer to the blog post:
[https://appcircle.io/blog/elevate-your-mobile-app-security-with-appdome-integration](https://appcircle.io/blog/elevate-your-mobile-app-security-with-appdome-integration)
## [AppSweep Mobile Security Testing](/workflows/android-specific-workflow-steps/appsweep-mobile-security-testing)
Scan your Android app using [AppSweep](https://appsweep.guardsquare.com)
## [Azure DevOps Bot for Detekt Report](/workflows/android-specific-workflow-steps/azure-bot-for-detekt-report)
This step sends the Detekt report to Azure DevOps.
## [BrowserStack App Automate - Espresso](/workflows/android-specific-workflow-steps/browserstack-app-automate-espresso)
Run your Espresso tests on BrowserStack App Automate. You need to add **Android Build for UI Testing** before this step to create the required `$AC_APK_PATH` and `$AC_TEST_APK_PATH` files.
## [Bundle Universal Apk](/workflows/android-specific-workflow-steps/bundle-universal-apk)
This step generates a universal APK from an AAB.
## [Detekt](/workflows/android-specific-workflow-steps/detekt)
This step runs detekt gradle task.
## [Firebase Test Lab for Android](/workflows/android-specific-workflow-steps/firebase-test-lab)
This step runs your Android tests on Firebase Test Lab.
## [Gradle Runner](/workflows/android-specific-workflow-steps/gradle-runner)
This step runs given Gradle task.
## [LambdaTest App Automate - Espresso](/workflows/android-specific-workflow-steps/lambdatest-app-automate-espresso)
[LambdaTest App Automate - Espresso](https://www.lambdatest.com/support/docs/getting-started-with-espresso-testing/) is a cloud-based testing solution designed for Android applications using the [Espresso](https://developer.android.com/training/testing/espresso) testing framework. It enables developers to run automated tests for Android apps across a wide range of real devices hosted in the LambdaTest cloud infrastructure. This solution allows efficient, scalable, and reliable testing of Android applications to ensure app quality and compatibility.
## [Android Increment Build and Version Number](/workflows/android-specific-workflow-steps/increment-build-and-version-number)
This step increments the version code and version name in the Android project.
## [Android Lint](/workflows/android-specific-workflow-steps/lint)
This step runs lint Gradle tasks on the source files of the project.
## [Test Reports for Android](/workflows/android-specific-workflow-steps/test-reports-for-android)
This component provides detailed reports and insights on the results of Android app tests conducted.
For detailed information on the usage of **Test Reports for Android**, please refer to the documentation:
- [Generating Test Report](/continuous-testing/android-testing/running-android-unit-tests#generating-test-report)
## [Wait for Android Emulator](/workflows/android-specific-workflow-steps/wait-for-android-emulator)
This step waits for Android Emulator to boot. You must use this step before running any UI tests.
---
## LambdaTest App Automate - Espresso
[LambdaTest App Automate - Espresso](https://www.lambdatest.com/support/docs/getting-started-with-espresso-testing/) is a cloud-based testing solution designed for Android applications using the [Espresso](https://developer.android.com/training/testing/espresso) testing framework. It enables developers to run automated tests for Android apps across a wide range of real devices hosted in the LambdaTest cloud infrastructure. This solution allows efficient, scalable, and reliable testing of Android applications to ensure app quality and compatibility.
The Appcircle **LambdaTest App Automate - Espresso** step allows you to run automated tests on Android apps using the Espresso framework on real devices in the LambdaTest cloud.
### Prerequisites
Before running the **LambdaTest App Automate - Espresso** step, ensure you have completed the following prerequisite:
| Prerequisite Workflow Step | Description |
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [**Android Build for UI Testing**](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) | The **Android Build for UI Testing** step must be executed to obtain the required app and test APK outputs. |
### Input Variables
This step includes several input variable(s) required for proper execution. See the table below for a detailed description:
| Variable Name | Description | Status |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_LT_USERNAME` | LambdaTest account username. Required to authenticate API requests. | Required |
| `$AC_LT_ACCESS_KEY` | LambdaTest account access key. Required to authenticate API requests. | Required |
| `$AC_LT_APK_PATH` | Path to the `APK` file to upload to LambdaTest. Auto-filled by prior Android build step. | Required |
| `$AC_LT_TEST_APK_PATH` | Path to the test `APK` file to upload to LambdaTest. Auto-filled by prior **Android Build** step. | Required |
| `$AC_LT_PAYLOAD` | JSON string that defines test configuration. App/Test `APK` URLs are auto-inserted. Refer to [LambdaTest API](https://www.lambdatest.com/support/docs/getting-started-with-espresso-testing/) documantation for payload structure. | Optional |
| `$AC_LT_TIMEOUT` | Timeout value in seconds for test execution. Default is `600`. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| ------------------------- | ------------------------------------- |
| `$AC_LT_TEST_RESULT_PATH` | Path to save test results. Must be writable. Defaults to a directory under `$AC_OUTPUT_DIR`. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-lambdatest-espresso-app-automate-component.git
---
## Lint
# Android Lint
[Android Lint](https://developer.android.com/studio/write/lint) is a static analysis tool provided by the Android SDK that helps identify potential issues in Android projects. It scans the source code for common programming errors, performance optimizations, usability issues, and other problems. **Android Lint** can detect a wide range of issues, such as unused resources, layout performance problems, memory leaks, and security vulnerabilities.
This step is used to run Lint Gradle tasks in your project via Appcircle.
### Prerequisites
Before running the **Android Lint** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | To start the **Android Lint** process, the repository that needs to be built must be fetched from the branch. This generates the `$AC_REPOSITORY_DIR` variable, which is then used as the input for the **Android Lint** step. |
:::caution
Please ensure that you insert the **Android Lint** step before using the **Android Build** step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| -------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_REPOSITORY_DIR` | This variable represents the path of the cloned Git repository. If this step runs after the [Git Clone](/workflows/common-workflow-steps/git-clone) step, the variable will be automatically populated. | Required |
| `$AC_MODULE` | This variable specifies the project module to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can locate the available modules for your project. For more information, please refer to this [Android document](https://developer.android.com/studio/projects#ApplicationModules). | Required |
| `$AC_VARIANTS` | This variable specifies the project variant to be built. This variable can also be set via the build [Configuration](/build/build-process-management/configurations). In Android Studio, you can find the available variants for your project. For more information, please refer to this [Android document](https://developer.android.com/build/build-variants). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. If your project that needs to be built is **not located** in the root directory where it was cloned from Git, you should provide the subpath as a relative path. | Optional |
:::info
If you have filled in the required variables in the **Configuration** section, you will not need to redefine these variables again on the [**Workflows**](/workflows/). For more information about configurations, refer to the [Build Profile Configuration Overview](/build/build-process-management/configurations) document.
1. The input corresponds to the 1st field: `$AC_MODULE`
2. The input corresponds to the 2nd field: `$AC_VARIANTS`
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `-` | Lint does not assign the XML/HTML file output to a variable. However, the resulting file from **Lint** appears in the output (`$AC_OUTPUT_DIR`) and report directory (`/$AC_MODULE/build/reports`). |
:::caution
To view the Lint report on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts/#download-exported-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps#export-build-artifacts) step is included in your **Workflow** after this step.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-lint-component
---
## Test Reports for Android
The Appcircle **Test Report** step displays your test results and code coverage in an aesthetically pleasing user interface.
This component supports the following test and coverage formats:
- [**JUnit**](https://junit.org)
- [**JaCoCo**](https://www.jacoco.org)
- [**Cobertura**](https://cobertura.github.io/cobertura)
- [**lcov.info**](https://lcov-viewer.netlify.app)
For additional details, please refer to the document:
- [**Generating Test Report**](/continuous-testing/android-testing/running-android-unit-tests#generating-test-report)
### Prerequisites
Before running the **Test Reports for Android** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------- |
| [**Android Unit Tests**](/workflows/android-specific-workflow-steps/android-unit-tests) | This step must be executed to obtain the test report output. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ------------------------ | ---------------------------------------------------------------- | --------- |
| `$AC_TEST_RESULT_PATH` | Specifies the directory and its subdirectories where compatible test files will be searched. | Required |
| `$AC_COVERAGE_RESULT_PATH`| Path to the directory containing the code coverage results (e.g., `$AC_REPOSITORY_DIR/jacoco/`). Used for generating coverage reports. | Optional |
| `$AC_JACOCO_COVERAGE_TYPE`| Determines the parameter in your JaCoCo report based on which the coverage will be calculated. This setting is necessary when using JaCoCo parseable coverage results and specifying the coverage result path. Types description can be found in this [documentation](/continuous-testing/android-testing/running-android-unit-tests#jacoco-test-coverage) | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------- | ---------------------------------------------------- |
| `AC_TEST_REPORT_JSON_PATH` | Specifies the path of the JSON report. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-test-report-component
---
## Wait for Android Emulator
The **Wait for Android Emulator** step waits for the Android Emulator to boot. You must use this step before running any UI tests.
For additional details, please refer to the [**Emulator**](/infrastructure/android-build-infrastructure#emulator) documentation.
:::danger
Ensure that you select the **Appcircle Linux Pool (x86_64)** in the Configuration tab, as the **Wait for Android Emulator** step will not function in the **Appcircle Standard macOS Pool (arm64)**. Please refer to [this documentation](/build/build-process-management/configurations#config-details) for selecting a pool in Configuration.
:::
### Prerequisites
Before running the **Wait for Android Emulator** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | This step is necessary to obtain the Android outputs required for processing. Without adding this step beforehand, the **Wait for Android Emulator** step will still function, but the app will not be installed. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If you intend to use a signed app, this step must be executed beforehand to process the output. Failure to add this step beforehand will result in the **Wait for Android Emulator** step still functioning, but since the app is not signed, there may be installation issues. If your app is already signed, you can skip this step. |
:::caution
If a step other than the **Android Build** or **Android Sign** step is used to build or sign the app, then the **Wait for Android Emulator** step depends on this step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_TEST_DEVICE` | Specifies the device for the test. The default value is `Pixel_3a`. If you use an emulator other than `Pixel_3a`, you need to create it manually. To install a different device, please follow [this document](/infrastructure/android-build-infrastructure#emulator). | Required |
| `$AC_TEST_ADB_WAIT_SECONDS` | Specifies the number of seconds the component must wait for the emulator to boot. The default value is `300`. | Optional |
| `$AC_TEST_ADB_ARGUMENTS` | ADB arguments for the device. For additional details about ADB arguments, please refer to the [Android Debug Bridge](https://developer.android.com/tools/adb) documentation. The default value is: `-no-window -no-audio -no-boot-anim -netdelay none -no-snapshot -wipe-data -gpu auto`. You may add new arguments, but don't change the default ones, such as `no-window`. | Required |
| `$AC_SIGNED_APK_PATH` | The optional full path of the signed APK file to install after the emulator boots. If this step runs after the **Android Sign** step, the variable will be automatically populated. If the signing takes place in the build step and you want to directly enter the APK you received from the **Android Build** step here, you can change the variable to `$AC_APK_PATH`. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-wait-emulator.git
---
## Active SSH Private Key
This step sets up your SSH key in the build machine if you used one to connect your repository. This allows the build machine to connect to your private repository using your SSH key.
### Prerequisites
There are no prerequisites required before using the **Active SSH Private Key** step.
:::caution
If you connect to your repository via SSH, use this step before the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. To securely clone repositories connected via SSH, you must define the SSH key for the relevant build agent.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_REPOSITORY_SSH_KEY` | SSH private key in RSA format. This value defaults to `$AC_REPOSITORY_SSH_KEY`. It is automatically defined as the [**Reserved Environment Variables**](/environment-variables/appcircle-specific-environment-variables) when an SSH connection is made. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `SSH_AUTH_SOCK` | This is the path to the SSH Auth Socket. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-activate-ssh-key-component
---
## Add a Badge to Your App Icon
With Appcircle's **Add Badge to Your App Icon** component, you can add badges and version information to your app icon, which you can also customize. This helps testers easily identify the version they are testing directly on the application icon.
|Original|Modified|
|--------|------|
|||
### Prerequisites
Before running the **Add a Badge to Your App Icon** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps#git-clone) | The repository needs to be cloned to begin the badge-adding process. After this step, the variable `$AC_REPOSITORY_DIR` will be set. |
:::caution
If you are using the [**Increment Build and Version Number**](/versioning/ios-version) component in your workflow and you want to print the current version information on the icon, this step should be used before the **Add Badge to Your App Icon** component.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_ICONS_PATH` | Specifies the path of icon files. For example: `MyProject/Assets.xcassets/AppIcon.appiconset`. The glob pattern can be used to select multiple image paths, for example, `app/src/main/res/mipmap*` to add badges to all PNGs under mipmap in this file path. | Required |
| `$AC_BADGE_TEXT` | The text to appear in the badge on the top right corner. | Optional |
| `$AC_BADGE_VERSION` | The version or build number to display at the bottom of the badge. | Optional |
| `$AC_BADGE_BGCOLOR` | You can specify a full color name (e.g., `orange`), hex codes (e.g., `#FFA500`), or RGB values (e.g., `rgb(255,165,0)`). | Optional |
| `$AC_BADGE_TEXTCOLOR` | You can specify a full color name (e.g., `white`), hex codes (e.g., `#FFFFFF`), or RGB values (e.g., `rgb(255,255,255)`). | Optional |
| `$AC_BADGE_CORNER_SHIFT` | This value determines how far the top‑right badge is shifted toward the bottom‑left, expressed as a percentage of the image’s dimensions. The default value is `5`. | Optional |
:::warning Badge Corner Shift
The `$AC_BADGE_CORNER_SHIFT` has a default starting value. If this value is increased too much (e.g., beyond 80% of the image size), the badge may shift too far toward the bottom-left and become partially or completely invisible.
:::
:::info
To use this component, you must provide the icon path from your project file. Here are some sample path usages:
- iOS Native: `MyProject/Assets.xcassets/AppIcon.appiconset`
- Android Native `app/src/main/res/`
- React Native iOS: `ios//MyProject/Assets.xcassets/AppIcon.appiconset/`
- React Native Android: `android/app/src/main/res/`
- Flutter iOS: `ios/Runner/Assets.xcassets/AppIcon.appiconset`
- Flutter Android: `android/app/src/main/res/`
**Note:** The glob pattern can be used to select multiple image paths. For example: `app/src/main/res/mipmap*` adds badges to all pngs under the mipmap in this file path.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-badge-component
---
## Appium Server
[**Appium Server**](https://appium.io/docs/en/latest/) is an open-source project and ecosystem of related software designed to facilitate the UI automation of many app platforms.
You can easily integrate the **Appium CLI** into your pipeline using Appcircle's Appium Server component by installing it.
### Prerequisites
There are no prerequisites required before using the **Appium Server** step.
### Input Variables
Below is a list of input variables that can be used with this component, with a description of each.
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_APPIUM_VERSION` | Specifies the version of Appium Server to install, such as `v1.22.3`. If you do not specify a version, the system installs the latest version. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-appium-component
---
## Artifactory Repository Management
# [Sonatype Nexus Integration](/workflows/common-workflow-steps/artifactory-repository-management/nexus-repository-management)
Learn how to integrate Sonatype Nexus with Appcircle to manage and optimize your dependency retrieval workflows. This section covers authentication, repository configuration, caching behavior, and best practices for accelerating build processes using Nexus repositories.
# [JFrog Integration](/workflows/common-workflow-steps/artifactory-repository-management/jfrof-repository-management)
Learn how to integrate JFrog Artifactory with Appcircle to efficiently manage dependency resolution and artifact distribution across your build workflows. This section explains authentication setup, repository configuration, caching optimizations, and recommended practices for improving build performance through Artifactory-backed pipelines.
---
## JFrog Integration
Integrating JFrog into your CI/CD workflows provides a unified and secure approach to managing build artifacts, dependencies, and release packages. By connecting Appcircle with JFrog Artifactory, development teams can automate artifact storage, versioning, and distribution while maintaining end-to-end traceability. This integration enhances software supply chain security through advanced vulnerability analysis and license compliance, ensuring that every artifact promoted through the pipeline meets organizational quality and security standards.
## JFrog Integration for iOS
Integrating JFrog Artifactory into iOS projects allows seamless management of CocoaPods and Swift Package Manager dependencies within a secure and centralized repository. This setup ensures consistent build environments, faster dependency resolution, and improved control over private libraries, all while maintaining compliance and traceability across your CI/CD workflows.
### Cocoapods Dependencies
CocoaPods dependencies can be seamlessly integrated with JFrog Artifactory to manage private and public iOS libraries efficiently, ensuring secure storage, version control, and faster dependency resolution during the build process.
To fetch CocoaPods dependencies from JFrog during the build process, you first need to create a CocoaPods repository in JFrog. For detailed steps, refer to the JFrog [**Create a CocoaPods Repository**](https://jfrog.com/help/r/jfrog-artifactory-documentation/create-a-cocoapods-repository) documentation.
#### Example 1: How can I fetch the all dependencies from JFrog with CocoaPods?
In the **CocoaPods Install** step, in order to pull dependencies from JFrog, you need to make some changes in the `Pods` file. For this, the `source url` value of the `Pods` file in the project must be replaced with the relevant artifactory. A short example is shown in the following bash script.
:::caution Configure JFrog Repository Authentication
If authentication to the repository is required, you need to authenticate to the repository with the [**Authenticate with Netrc**](/workflows/common-workflow-steps/authenticate-with-netrc) step or by using a [**Custom Script**](/workflows/common-workflow-steps/custom-script). If Custom Script is used, you can use the bash script given below.
For more information, please visit the [**JFrog Authentication**](https://jfrog.com/help/r/jfrog-artifactory-documentation/connect-cocoapods-cdn-to-artifactory) documentation.
```bash
$cat ~/.netrc
machine [JFrogPlatformURL]
login admin
password admin123
```
:::
```bash
platform :ios, '13.0'
source "https://[JFrogPlatformURL]/artifactory/api/pods/"
target 'MyApp' do
use_frameworks!
pod 'AFNetworking', '~> 4.0'
pod 'Alamofire', '~> 5.4'
end
.
.
. #Other Pod file codes
```
#### Example 2: How can I fetch some dependencies from different repositories?
If you want to fetch a dependency from a source other than this artifactory, you can set up your `Pod` file as shown below. This `Pod` file will pull any pods that are explicitly referenced from the specified URL, while all other dependencies will be retrieved directly from the default `source URL`.
```bash
platform :ios, '13.0'
source "https://[JFrogPlatformURL]/artifactory/api/pods/"
target 'MyApp' do
use_frameworks!
pod 'AFNetworking', '~> 4.0'
pod 'Alamofire', '~> 5.4'
pod 'MyPrivatePod', :git => 'https://git.mycompany.com/MyPrivatePod.git', :branch => 'main'
end
.
.
. #Other Pod file codes
```
After these changes;
- Trigger your build through Appcircle. The workflow will fetch dependencies from the JFrog CocoaPods repository as configured and compile the project with them.
- Logs will show dependency resolution status to confirm successful integration with JFrog.
### SPM (Swift Package Manager) Dependencies
Swift Package Manager (SPM) dependencies can also be integrated with JFrog Artifactory to manage Swift packages securely and efficiently. By configuring your package sources to point to artifactory, you can centralize package storage, improve dependency resolution speed, and maintain consistent access control and versioning across your iOS build environment.
To fetch SPM dependencies from JFrog during the build process, you first need to create a Swift repository in JFrog. For detailed steps, refer to the JFrog [**Create a Swift Repository**](https://jfrog.com/help/r/jfrog-artifactory-documentation/create-a-swift-repository) documentation.
#### How can I fetch the all dependencies from JFrog with SPM?
In the **Xcodebuild for Devices** step, to fetch SPM dependencies from JFrog, you need to make certain modifications to the `Package.swift` file within your project. For this, the relevant artifactory URL must be specified as the dependency URL in the `Package.swift` file. A short example is shown in the following bash script:
```bash
// swift-tools-version: 5.7
let package = Package(
name: "MyApp",
platforms: [
.iOS(.v13)
],
dependencies: [
// JFrog Swift repository üzerinden gelen bir paket
.package(url: "https://[JFrogPlatformURL]/artifactory/api/swift/swift-local/MyLibrary.git", from: "1.0.0")
],
targets: [
.target(
name: "MyApp",
dependencies: ["MyLibrary"]
)
]
)
```
- `JFrogPlatformURL` → Artifactory Domain (e.g. `https://company.jfrog.io`)
- `swift-local` → Repository name in JFrog
- `MyLibrary.git` → Dependency Git Repository URL
## JFrog Integration for Android
Integrating JFrog Artifactory into Android projects centralizes the management of Maven and Gradle dependencies and build artifacts. By configuring a module’s `build.gradle` or `settings.gradle` files to point to artifactory repositories, engineers enable reliable retrieval, caching, versioning, and distribution of libraries and modules. This integration accelerates build times, enforces consistent build environments, and enhances traceability across CI/CD workflows. Artifactory’s vulnerability scanning and license‑compliance checks further help maintain the integrity and security of the Android supply chain.
### Gradle Dependencies
Integrating JFrog Artifactory with Gradle enables centralized dependency management, artifact publishing, and version control within your Android build system. This setup helps development teams ensure reproducible builds, optimize caching, and maintain full traceability of artifacts across CI/CD pipelines.
#### 1. Configure Repositories in `build.gradle`
To integrate JFrog Artifactory into an Android project, you need to define your repository endpoints inside the project’s `build.gradle` or `settings.gradle` file.
**Example (Project-level `build.gradle`):**
```gradle
buildscript {
repositories {
maven {
url "https://[JFrogPlatformURL]/artifactory/[REPO_NAME]"
credentials {
username = project.findProperty("artifactory_user") ?: System.getenv("ARTIFACTORY_USER")
password = project.findProperty("artifactory_password") ?: System.getenv("ARTIFACTORY_PASSWORD")
}
}
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:8.1.0"
}
}
```
**Example (Module-level `build.gradle`):**
```gradle
repositories {
maven {
url "https://[JFrogPlatformURL]/artifactory/[REPO_NAME]"
credentials {
username = project.findProperty("artifactory_user") ?: System.getenv("ARTIFACTORY_USER")
password = project.findProperty("artifactory_password") ?: System.getenv("ARTIFACTORY_PASSWORD")
}
}
google()
mavenCentral()
}
dependencies {
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}
```
**Key Parameters:**
- `JFrogPlatformURL` → Your Artifactory domain (e.g. `https://company.jfrog.io`)
- `[REPO_NAME]` → The target repository (e.g. `gradle-release-local`)
- `credentials` → Authentication credentials from environment variables or Gradle properties
#### 2. Authentication with Artifactory
If authentication is required, use either:
- The **Authenticate with Netrc** step in Appcircle *(recommended for security and automation)*, or
- Store credentials in environment variables or encrypted Gradle properties (`gradle.properties`):
```properties
artifactory_user=yourUsername
artifactory_password=yourPassword
```
#### 3. Publishing Artifacts to Artifactory
You can also publish your own libraries or build outputs to Artifactory using the official **Gradle Artifactory Plugin**.
Add the plugin to your root `build.gradle`:
```gradle
plugins {
id "com.jfrog.artifactory" version "4.33.2"
}
```
Configure publishing settings:
```gradle
artifactory {
contextUrl = "https://[JFrogPlatformURL]/artifactory"
publish {
repository {
repoKey = "gradle-release-local"
username = project.findProperty("artifactory_user")
password = project.findProperty("artifactory_password")
}
defaults {
publications("release")
publishArtifacts = true
}
}
}
```
This allows the CI/CD pipeline (e.g. Appcircle) to automatically push your `.aar` or `.apk` artifacts to JFrog Artifactory after successful builds.
### Maven Dependencies
Integrating JFrog Artifactory with Maven allows you to manage dependencies, plugins, and project artifacts through a secure, centralized repository. This integration ensures reproducible builds, consistent dependency resolution, and full control over versioning and artifact promotion within your Android CI/CD workflows.
#### 1. Configure Repositories in `pom.xml`
To use Artifactory with Maven, define your repository endpoints inside your project’s `pom.xml` file under the `` and `` sections:
```xml
jfrog-releaseJFrog Release Repositoryhttps://[JFrogPlatformURL]/artifactory/[REPO_NAME]jfrog-pluginshttps://[JFrogPlatformURL]/artifactory/[PLUGIN_REPO_NAME]
```
#### 2. Authentication Configuration
To authenticate with Artifactory, add your credentials to the global Maven configuration file (`~/.m2/settings.xml`):
```xml
jfrog-release${env.ARTIFACTORY_USER}${env.ARTIFACTORY_PASSWORD}
```
- `JFrogPlatformURL` → Artifactory domain (e.g. `https://company.jfrog.io`)
- `[REPO_NAME]` → Target Maven repository (e.g. `libs-release-local`)
- `[PLUGIN_REPO_NAME]` → Repository for Maven plugins
This approach allows secure integration within Appcircle pipelines using environment variables or the **Authenticate with Netrc** step.
#### 3. Deploy Artifacts to Artifactory
To publish build artifacts (e.g., `.jar`, `.aar`) to Artifactory, use the Maven Deploy plugin or the **Artifactory Maven Plugin**.
**Example `distributionManagement` configuration:**
```xml
jfrog-releasehttps://[JFrogPlatformURL]/artifactory/libs-release-localjfrog-snapshothttps://[JFrogPlatformURL]/artifactory/libs-snapshot-local
```
#### 4. Using the JFrog Maven Plugin
Add the plugin to your `pom.xml` to automate uploads:
```xml
org.jfrog.buildinfoartifactory-maven-plugin3.5.4build-infopublishhttps://[JFrogPlatformURL]/artifactory${env.ARTIFACTORY_USER}${env.ARTIFACTORY_PASSWORD}libs-release-local
```
---
## Sonatype Nexus Integration
Integrating Sonatype Nexus into your CI/CD pipeline enables secure, efficient, and automated management of dependencies, artifacts, and container images. By connecting Appcircle with Nexus Repository Manager, teams can centralize artifact storage, enforce security policies, and ensure consistent version control across builds. This integration not only streamlines dependency resolution but also enhances supply chain security through vulnerability scanning and license compliance checks. Ultimately improving build reliability and traceability throughout the release process.
### Nexus Integration for iOS
Integrating an Artifactory repository manager into your iOS build process is a robust approach to centralizing dependency management, improving build reliability, and ensuring reproducibility. Below, we’ll demonstrate this process using **Sonatype Nexus Repository Manager** as an example in conjunction with the Appcircle **CocoaPods Install** workflow step. Please ensure your Sonatype Nexus Repository Manager is properly installed and configured. For more information, please visit the [official Sonatype Nexus documentation](https://help.sonatype.com/repomanager3).
:::info Supported Frameworks
Sonatype Sonatype Nexus only supports **CocoaPods** for iOS. There is no support for [**Carthage**](https://github.com/Carthage/Carthage) and [**SPM (Swfit Package Manager)**](https://www.swift.org/documentation/package-manager/).
For more information about supported frameworks, please visit [**Sonatype Sonatype Nexus Repository documentation**](https://help.sonatype.com/en/formats.html).
:::
:::tip Artifactory Management for SPM
Since Sonatype Nexus does not yet support **SPM**, it is **not** possible to manage SPM packages using Nexus.
For users with a Nexus infrastructure, an alternative approach to centralize and fetch SPM packages is to collect all SPM packages in a private Git repository. This way, all SPM packages are pulled only from a repository accessible to the user and included in the build process.
**Note**: With this method, the **SPM** packages collected in a single repository must be regularly checked and updated to ensure they remain up to date.
:::
:::caution Configure Sonatype Nexus Repository Authentication
If [anonymous access option](https://help.sonatype.com/en/anonymous-access.html) is turned off in Sonatype Nexus repository, you need to authenticate to the repository with the [**Authenticate with Netrc**](/workflows/common-workflow-steps/authenticate-with-netrc) step or by using a [**Custom Script**](/workflows/common-workflow-steps/custom-script). If Custom Script is used, you can use the bash script given below.
For more information, please visit the [**Sonatype Nexus Authentication documentations**](https://help.sonatype.com/en/cocoapods-repositories.html#configure-nexus-repository-authentication).
```bash
$cat ~/.netrc
machine https://Sonatype Nexus.example.com/repository/cocoapods-specs.git
login admin
password admin123
```
:::
For more information about Sonatype Nexus integration with CocoaPods, please visit the [Sonatype Nexus CocoaPods documentations](https://help.sonatype.com/en/cocoapods-repositories.html).
#### Example 1: How can I fetch the all dependencies from Sonatype Nexus with CocoaPods?
In the **CocoaPods Install** step, in order to pull dependencies from Sonatype Nexus or another artifactory, you need to make some changes in the `Pods` file. For this, the `source url` value of the `Pods` file in the project must be replaced with the relevant artifactory. A short example is shown in the following bash script.
For detailed server-side configuration steps, you can refer to [Appcircle’s Sonatype Nexus configuration guide](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry#sonatype-nexus-configuration).
:::info SSL Configuration
If you are using a self-signed SSL certificate, ensure that curl can work with it properly. Since the CocoaPods client uses the curl command to download Pod files from Nexus Repository, you can configure curl by adding the `--insecure` option to the .curlrc file in your home directory. If the file does not exist, simply create it. Example:
```bash
$cat ~/.curlrc
--insecure
```
For detailed information, please visit the [**Sonatype Nexus SSL Configuration documentations**](https://help.sonatype.com/en/cocoapods-repositories.html#configure-ssl).
:::
```bash
platform :ios, '13.0'
source 'https://Sonatype Nexus.example.com/repository/cocoapods-specs.git'
target 'MyApp' do
use_frameworks!
pod 'AFNetworking', '~> 4.0'
pod 'Alamofire', '~> 5.4'
end
.
.
. #Other Pod file codes
```
### Nexus Integration for Android
Integrating an Artifactory repository manager into your Android build process is a robust approach to centralizing dependency management, improving build reliability, and ensuring reproducibility. Below, we’ll demonstrate this process using [**Nexus Repository Manager**](https://www.sonatype.com/products/sonatype-nexus-repository) as an example in conjunction with the Appcircle **Android Build** workflow step.
For detailed instructions on integrating Nexus Repository Manager with Appcircle, see our [Sonatype Nexus Configuration guide](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry#sonatype-nexus-configuration).
#### 1. Set up Nexus repository
- Ensure your Nexus Repository Manager is properly installed and configured. For hosted installations, follow the [official Nexus documentation](https://help.sonatype.com/repomanager3) to set up your Maven or Gradle repositories.
- Create a hosted Maven repository (or any repository format compatible with your project). Name the repository, for example, `android-repo`.
#### 2. Integrate Nexus into the Android project
In your Android project’s build.gradle (or settings.gradle if using Gradle Version Catalog), configure Nexus as a repository.
To fetch dependencies from a Nexus repository, add the following configuration to your Gradle file.
You can place this block in either the project-level or module-level `build.gradle` file, depending on your project structure.
If all modules in your project will use the same artifacts, it is recommended to place it in the project-level file:
```gradle
repositories {
maven {
url 'https://your-nexus-url/repository/android-repo/'
}
}
```
If the URL requires authentication for access, you can configure it as shown below:
```gradle
repositories {
maven {
url 'https://your-nexus-url/repository/android-repo/'
credentials {
username = "your-username"
password = "your-password"
}
}
}
```
To update your Gradle distribution URL with a Nexus repository, modify your `gradle-wrapper.properties` file and replace the `distributionUrl` value with the Nexus repository URL. Below is an example:
```gradle
distributionUrl=https://your-nexus-url/repository/gradle-distributions/gradle-8.8-bin.zip
```
#### 3. Run the build workflow
Trigger your build through Appcircle. The workflow will fetch dependencies from the Nexus repository as configured and compile the project with them. Logs will show dependency resolution status to confirm successful integration with Nexus.
---
## Authenticate with Netrc
The `.netrc` file contains login and initialization information used by the auto-login process. You can use this component to add credentials for hosts such as your repositories or external hosts. Git automatically recognizes the `.netrc` file. However, if you want to use the `.netrc` file with curl, you need to append the `-n` command line parameter. You may also use the `--netrc-optional` parameter if you don't always use the `.netrc` file with curl.
### Prerequisites
There are no prerequisites required before using the **Authenticate with Netrc** step.
:::danger
Please note that you should use this step before your **Git Clone** step. If you want to connect to a repository that requires access permission or pull a private dependency, please pay attention to the step order.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger
When using the **Authenticate with Netrc** component, you need to specify a token or password in the `$AC_NETRC_PASS` parameter within the component. For security reasons, we recommend using [**Enviroment Variables**](/environment-variables) in steps where you need to specify the token and password.
:::
| Variable Name | Description | Status |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_NETRC_HOSTNAME` | Specifies the hostname of the server where the username and password will be used, for example, `github.com`. | Required |
| `$AC_NETRC_USER` | Specifies the username of the host. | Required |
| `$AC_NETRC_PASS` | The password or the `authentication-token`/`access-token` in the respective field, will be used by the host to authenticate you. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-netrc-component
---
## AWS Device Farm and Deploy
[AWS Device Farm](https://aws.amazon.com/device-farm/) is an application testing service that enables you to run your tests concurrently on multiple mobile devices to speed up the execution of your tests and generates videos and logs to help you quickly identify issues with your app.
Appcircle is integrated with the AWS Device Farm for continuous testing. You can build your app in Appcircle and deploy it directly to AWS Device Farm to run automated tests.
With the **AWS Device Farm Deploy and Run** step in Appcircle, you can directly deploy your binaries and test scripts during the build to the specified AWS Device Farm project and run tests.
The full details of the tests are accessible in the [AWS Device Farm console](https://console.aws.amazon.com/devicefarm/).
### Prerequisites
Before running the **AWS Device Farm and Deploy** step, you must complete certain prerequisites, as detailed in the table below:
:::caution
Pay attention to the dependent step on whichever platform you are working on.
:::
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Android Build for UI Testing**](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) | This step is tailored to build your Android test application using Gradle Wrapper (gradlew) for the designated architectures outlined in your project. |
| [**Xcodebuild Build for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) | This step builds your application and generates an IPA for testing so that it can be used in test automation frameworks. |
#### For iOS
#### For Android
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AWS_ACCESS_KEY_ID` | AWS Access Key ID. Please follow the [**AWS documentation**](https://docs.aws.amazon.com/IAM/latest/UserGuide/security-creds.html#access-keys-and-secret-access-keys). | Required |
| `$AWS_SECRET_ACCESS_KEY` | AWS Secret Access Key. Please follow the [**AWS documentation**](https://docs.aws.amazon.com/IAM/latest/UserGuide/security-creds.html#access-keys-and-secret-access-keys) | Required |
| `$AWS_DEFAULT_REGION` | AWS Default Region. The default value is `us-west-2`. For more information, please visit this [documentation](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). | Optional |
| `$AWS_PROJECT_ARN` | The ARN of the project for deploy and run. | Required |
| `$AWS_DEVICE_POOL_ARN` | The ARN of the device pool for the run. | Required |
| `$AWS_SCHEDULE_RUN_NAME_PREFIX` | The name prefix for the run to be scheduled. | Required |
| `$AWS_SCHEDULE_TEST_TYPE` | The type of the test for the run. Enter **BUILTIN_FUZZ** for sample test runs. [**See API Reference**](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_CreateUpload.html#API_CreateUpload_RequestSyntax). | Required |
| `$AWS_UPLOAD_TIMEOUT` | Time out duration (seconds) for the test file upload. The step is skipped if the time out is reached. | Required |
| `$AWS_TEST_TIMEOUT` | Time out duration (seconds) for the AWS Device Farm run. The step is skipped if this duration is reached, but the test execution continues in AWS Device Farm. | Required |
| `$AWS_APP_ARN` | The ARN of the application package to run tests against, created with CreateUpload. If you don't set this parameter, the subsequent App Upload File Name, App Upload Type and App Upload File Path parameters are required. | Optional |
| `$AWS_APP_UPLOAD_FILE_NAME` | The file to be uploaded. The name should not contain any forward slashes (/ ). If you are uploading an iOS app, the file must have an **IPA** extension. If you are uploading an Android app, the file must have an **APK** extension. | Optional |
| `$AWS_APP_UPLOAD_TYPE` | The upload type of the file. Enter **ANDROID_APP** or **IOS_APP** for simple APK or IPA uploads. | Optional |
| `$AWS_APP_UPLOAD_FILE_PATH` | The file path for the app upload. You can use predetermined environment variables like `$AC_APK_PATH`. | Optional |
| `$AWS_TEST_ARN` | The ARN of the uploaded test to be run. If you don't set this parameter, the subsequent Test Upload File Name, Test Upload Type and Test Upload File Path parameters are required. | Optional |
| `$AWS_TEST_UPLOAD_FILE_NAME` | The test file to be uploaded. The file must have a `.zip` extension. | Optional |
| `$AWS_TEST_UPLOAD_TYPE` | The upload type of the file. Enter **ANDROID_APP** or **IOS_APP** for simple APK or IPA uploads. | Optional |
| `$AWS_TEST_UPLOAD_FILE_PATH` | The file path for the app upload. You can use predetermined environment variables like `$AC_APK_PATH`. | Optional |
| `$AWS_TEST_SPEC_ARN` | The ARN of the uploaded test spec to be run. | Optional |
| `$AWS_TEST_SPEC_UPLOAD_FILE_NAME` | The test spec file to be uploaded. | Optional |
| `$AWS_TEST_SPEC_UPLOAD_TYPE` | The upload type of the test spec. | Optional |
| `$AWS_TEST_SPEC_UPLOAD_FILE_PATH` | The file path for the test spec upload. | Optional |
#### How to get the ARN values
To get the ARN values, you first need to install the AWS CLI. Please refer to the guide for your operating system to install it: [https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
Once the CLI is installed, first run the following command to list the projects and get the project ARN:
```bash
aws devicefarm list-projects
```
You can then get the ARN of the device pools of a specific project as follows. Replace `MyProjectARN` with the project ARN obtained from the previous command.
```bash
aws devicefarm list-device-pools --arn MyProjectARN
```
For the details of the other AWS Device Farm-specific parameters, please refer to the following documents:
https://docs.aws.amazon.com/cli/latest/reference/devicefarm/create-upload.html
https://docs.aws.amazon.com/cli/latest/reference/devicefarm/schedule-run.html
After you save your settings, you can run the build and the step will be executed accordingly. You can view the details of the AWS Device Farm Deploy and Run step in the build logs:
The full details of the tests are accessible in the [AWS Device Farm console](https://console.aws.amazon.com/devicefarm/).
### Output Variables
The outputs resulting from the operation of this component are as follows:
| Variable Name | Description |
| ---------------------------- | ---------------------------- |
| `AWS_RUN_ARN` | AWS Device Farm Run ARN. |
| `AWS_TEST_RESULT` | AWS Device Farm Test result. |
| `AWS_OUTPUT_DEVICEPOOL_ARN` | The ARN of the Device pool. |
| `AWS_OUTPUT_APPUPLOAD_ARN` | The ARN of the App Upload. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-aws-device-farm-deploy-and-run
---
## Azure Boards
Azure Boards is a standalone service within the Azure DevOps suite that helps teams plan, track, and discuss work across the entire software development process. It provides a flexible, customizable platform for managing work items, such as user stories, bugs, tasks, and issues, so you can track your work item's progress throughout the development lifecycle.
You can use the [Azure Boards Component](https://github.com/appcircleio/appcircle-azure-boards-component/) to add a comment and change the status of your issues according to the status of your workflow.
### Prerequisites
There are no prerequisites required before using the **Azure Boards** step. It depends on your business decision which step to use before or after in your workflow.
:::caution
Please note that once the **Azure Boards** component has run successfully, the status of the relevant article in your Azure Board account will be changed. If the build fails in Appcircle, an incorrect status may appear in your Azure Board account. Make sure you use it in the correct order in Workflow.
:::
### Configuration of Component
To add a comment, the issue ID `$AC_AZUREBOARD_WORKITEM` must be supplied to the component. We need to get this issue ID dynamically so that our workflow can work for multiple branches. Appcircle components use environment variables to pass the state. We can add a step just before the Azure Boards component to prepare the necessary environment variables.
Let's say you're working on a feature branch called feature/onboarding-1. You may use the below Ruby script to get issue ID 1 from the branch name and use this information with the Azure Boards component. Please see the [**Custom Script step documentation**](/workflows/common-workflow-steps/upload-files-to-amazon-s3) for this implementation.
```ruby
branch = ENV['AC_GIT_BRANCH']
issue_number = branch.split('-')[1]
puts issue_number
# Write Environment Variable
open(env_var_path, 'a') { |f|
f.puts "AC_AZUREBOARD_WORKITEM=#{issue_number}"
}
```
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| `$AC_AZUREBOARD_INSTANCE` | Your Azure Board subdomain. If you're using a self-hosted instance, write the instance URL. For example: `https://dev.azure.com` | Required |
| `$AC_AZUREBOARD_API_VERSION` | The version of the Azure DevOps Services REST API. The default value is `7.0` | Required |
| `$AC_AZUREBOARD_EMAIL` | Email of Azure user. Please use [**Environment Variables**](/environment-variables/). | Required |
| `$AC_AZUREBOARD_TOKEN` | Personal access token of the user. It can be created by visiting User settings. Please use [**Environment Variables**](/environment-variables/). | Required |
| `$AC_AZUREBOARD_ORG` | Azure Organization. The organization can be identified by its URL, such as for the `https://dev.azure.com/JohnDoe/MyProject/_boards/board/t/MyTeam/Issues` **JohnDoe** is the organization name. | Required |
| `$AC_AZUREBOARD_PROJECT` | Azure Project. The project can be identified by its URL, such as for the `https://dev.azure.com/JohnDoe/MyProject/_boards/board/t/MyTeam/Issues` **MyProject** is the project name. | Required |
| `$AC_AZUREBOARD_WORKITEM` | Azure work item ID. The work item ID (integer) is shown next to the issue. | Required |
| `$AC_AZUREBOARD_FAIL_STATE` | The state name for the failed step. If the previous state fails, you can optionally change the state of your issue. | Optional |
| `$AC_AZUREBOARD_SUCCESS_STATE` | The state name for the successful step. If the previous state succeeds, you can optionally change the state of your issue. | Optional |
| `$AC_AZUREBOARD_TEMPLATE` | This comment template will be used to post a comment. Variables donated with `$` will be replaced during the build. Please check [this document](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/update?view=azure-devops-rest-7.0) to learn more about possible updates. | Required |
:::tip
If you add state names for successful and failed steps (`$AC_AZUREBOARD_FAIL_STATE` and `$AC_AZUREBOARD_SUCCESS_STATE`), the Azure Boards component will automatically change the status of your issue according to the state of your workflow.
:::
### Changing Template
Appcircle provides a default template that adds the commit ID, branch name, and a couple of environment variables. When you're adding a comment, you may use HTML. This template can be edited and modified according to the Azure API. You can check [this document](https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/update?view=azure-devops-rest-7.0&tabs=HTTP/) to create your custom comments.
Please check the [Azure Boards Component](https://github.com/appcircleio/appcircle-azure-boards-component/) documentation for more information.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-azure-boards-component/
---
## Cache Pull
[**Cache Push**](/workflows/common-workflow-steps/build-cache/cache-push) uploads the cache archive file to a remote location, as we explained in detail in the **Cache Push** step. On the other hand, **Cache Pull** downloads and extracts that archive file in the build pipeline, restoring all files and folders to their original locations.
:::danger
[**Cache Push**](/workflows/common-workflow-steps/build-cache/cache-push) and **Cache Pull** components should work in coordination on the same cache file. Therefore, to download the pushed cache, the **Cache Pull** must have the same cache label as the **Cache Push**.
:::
:::info
If you need to use the cached folder in a separate project, you have the capability to modify the value of `$AC_BUILD_PROFILE_ID`. For further information, please check out the following documentation:
- [How to Share Files Between Build Profiles](/workflows/common-workflow-steps/build-cache/how-to-share-file-between-build-profiles)
This variables can be adjusted within the [cache label](#input-variables) field, as indicated by the red highlight in the accompanying image. Simply replace them with the project ID that corresponds to your intended usage.
If you need to use branch-based caching, you can modify the [cache label](#input-variables) input value. For more information, please check the following documentation:
- [How to Configure Branch-Base Caching](/workflows/common-workflow-steps/build-cache/how-to-configure-branch-based-caching)
:::
### Prerequisites
There are no prerequisites required before using the **Cache Pull** step.
:::caution
This component does not require any prerequisite steps for operation. The only thing necessary for the component to work as expected is to utilize the cached files before the step in which they will be used. Additionally, an important prerequisite for this step to function properly is that the files to be used must have been cached in previous builds.
For example, in the screenshot, to use cached files for Cocoapods, the **Cache Pull** step should be used before the [**Cocoapods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) step.
:::
:::danger
If there are no previously cached files and you attempt to use this step, the **Cache Pull** step will result in a **`not found error`** because it cannot locate the specified files at the remote location.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|----------------------------|------------------------------------------------|--------|
| `$AC_CACHE_LABEL` | User defined cache label to identify one cache from others. Both [**Cache Push**](/workflows/common-workflow-steps/build-cache/cache-push) and **Cache Pull** steps should have the same value to match. | Required |
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository path. This path will be generated after running the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-cache-pull-component
---
## Cache Push
Every single build at Appcircle runs in a clean state. It means that all files and folders that are not versioned in the Git repository are lost when the build pipeline is completed. For example, install dependencies or build artifacts. If you need to keep those files and folders, you can use the Appcircle **Cache Push** and [**Cache Pull**](/workflows/common-workflow-steps/build-cache/cache-pull) components.
:::danger Minimum Version Requirement
Please ensure you are using version **`1.0.4` or later** of the Cache Push component. Earlier versions are no longer compatible with Appcircle.
To make sure you always get the latest updates, it is recommended to use the latest wildcard version (e.g., `1.0.*`):
:::
With cache, you can persist any resource that is ignored by Git. So you can transfer files and folders between build pipelines. Sometimes it may speed up your build, or it may help if you have reliability issues with the original download location for dependencies. But keep in mind that the cache is uploaded to or downloaded from a remote location. It may help you in some cases, but **it's not a guaranteed way to speed up builds**. You should try and see the actual results of your project.
The cache is stored as a single archive file. **Cache Push** and [**Cache Pull**](/workflows/common-workflow-steps/build-cache/cache-pull) components work in coordination on the same cache file defined with a label. Cache labeling helps you organize your caches. With custom labels, you can create separate cache chunks, share caches between build profiles, or isolate them per branch. For further information, please check out the following documentation:
- [How to Configure Branch-Base Caching](/workflows/common-workflow-steps/build-cache/how-to-configure-branch-based-caching)
- [How to Share Files Between Build Profiles](/workflows/common-workflow-steps/build-cache/how-to-share-file-between-build-profiles)
:::warning Cache Storage Limits
Cache Push component enforces cache storage limits based on license tiers:
- **Starter**: 5 GB
- **Developer**: 10 GB
- **Professional**: 20 GB
- **Enterprise**: 30 GB
- **Self-hosted**: Customizable (see [documentation](/self-hosted-appcircle/install-server/linux-package/configure-server/advanced-configuration/cache-size-configuration))
These limits apply per build. Exceeding the limit will result in a failed cache upload.
:::
When you drag and drop the **Cache Push** component into your [workflow](/workflows), it comes with pre-defined values according to your project type. For example, in the case of Android projects, it comes with pre-defined [Gradle cache](https://docs.gradle.org/current/userguide/build_cache.html) paths, which should prove useful for most Android apps.
If you need more paths to cache or need to change paths according to your project, you can customize [included](#input-variables) and [excluded](#input-variables) paths as you wish. All path updates will be reflected in the archived cache file on your next build.
:::danger
You cannot delete a specific cache file from the UI, but if you have a problem with a cache file and need a fresh one, you can change your [cache label](#input-variables) to a new one to go on with a clean cache.
:::
:::info
The system automatically cleans unreachable and obsolete cache files periodically. For this reason, **it's not guaranteed to reach a previously used cache file by using the previous cache label in build**. Also, it’s a good idea to build your workflow in such a way that your **build won’t fail if the cache can’t be accessed**.
:::
### Prerequisites
Before running the **Cache Push** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | If the folders to be cached are in the repo directory, the **Git Clone** step must be used before. This step will generate the [`$AC_REPOSITORY_DIR`](#input-variables) path. |
:::danger
Keep in mind that included paths and the **Cache Push** step's workflow order are closely related to each other. For example, if you include a path from a repository and you place the **Cache Push** step before the **Git Clone** step, **Cache Push** won't find that path since it's not Git cloned yet. Although that's not a fatal error for **Cache Push**, it will inform you about unreachable paths on build logs. You can review and resolve those kinds of issues from build logs.
:::
:::caution
The other important prerequisite for this component to work is that it must be used after the step in which the generated artifact of the step is to be cached. For example, in the screen shot, to cache dependencies, the **Cache Push** step is used after the [**CocoaPods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|----------------------------|------------------------------------------------|--------|
| `$AC_CACHE_LABEL` | User defined cache label to identify one cache from others. Both **Cache Push** and **Cache Pull** steps should have the same value to match. | Required |
| `$AC_CACHE_INCLUDED_PATHS` | Specifies the files and folders that should be in the cache. Multiple glob patterns can be provided as a colon-separated list. For example; `.gradle:app/build` or `Pods:Podfile.lock`. | Required |
| `$AC_CACHE_EXCLUDED_PATHS` | Specifies the files and folders that should be ignored from the cache. Multiple glob patterns can be provided as a colon-separated list. For example, `.gradle/*.lock:*.apk`. | Optional |
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository path. This path will be generated after running the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Optional |
:::tip
**Cache Push** uses a pattern in order to select files and folders. Although the pattern is not a RegExp, it's closer to a shell glob. For example, `~/Library/Caches/CocoaPods` and `Pods` will select the `CocoaPods` folder from home and the repository direction as a whole. Or for an Android project, you can cache the `.gradle ` folder with `~/.gradle` include path and exclude all `.lock` files from there with `~/.gradle/**/*.lock` exclude path. Patterns that can be used in both included and excluded paths are explained in detail [here](https://github.com/appcircleio/appcircle-cache-push-component#included--excluded-paths).
:::
### Output Variables
You cannot reach the cache archive file directly by yourself. But you can see cache file updates and track changes to cache at the end of the build pipeline from '[Download Artifacts](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) > `ac_cache.zip`'. Also, build logs have some useful information about the cache mechanism and how included and excluded paths are processed. You can see the produced cache file size from the build logs. (The size of the cache file affects upload and download durations.)
:::caution
To view the generated artifacts on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in the [workflow](/workflows) after this step.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-cache-push-component
---
## How to Configure Branch-Base Caching
By default, Appcircle cache is shared across builds to improve performance. However, in some cases, you may want to create a separate cache for each branch to avoid conflicts between different build outputs or dependencies.
This document explains how to configure the Appcircle Cache structure so that each branch uses its own isolated cache, ensuring consistent and predictable builds when working with multiple active branches.
:::caution Performance Note
Branch-based caching is recommended for teams that require isolated cache usage per branch. However, this approach does not provide a performance advantage for the first build of a new branch, since no cache will exist for that branch initially.
Cache benefits will apply starting from the second and subsequent builds of the same branch, once the cache has been created.
:::
### Steps to Enable Branch-Based Caching
1. Open the **Cache Pull** step that you added to your pipeline by following the [Cache Pull](/workflows/common-workflow-steps/build-cache/cache-pull) documentation.
2. Update the default **Cache label** input as shown below:
```
$AC_BUILD_PROFILE_ID/cache
```
➜
```
$AC_BUILD_PROFILE_ID/$AC_BUILD_BRANCH_ID/cache
```
3. Save the changes in the Cache Pull step.
4. In the same pipeline, open the **Cache Push** step that you added by following the [Cache Push](/workflows/common-workflow-steps/build-cache/cache-push) documentation.
5. Update the default **Cache label** input as shown below:
```
$AC_BUILD_PROFILE_ID/cache
```
➜
```
$AC_BUILD_PROFILE_ID/$AC_BUILD_BRANCH_ID/cache
```
6. Save the changes in the Cache Push step.
### How It Works
By including the **branch ID** in the cache label, Appcircle creates a **separate cache namespace for each branch**. This prevents different branches from sharing the same cache and avoids potential conflicts between dependencies or build outputs.
When a branch is built for the first time, no cache will be available for that branch. Starting from the **second and subsequent builds**, the cache created by the Cache Push step will be reused by the Cache Pull step, improving build consistency.
---
## How to Share Files Between Build Profiles
With the build cache structure provided by Appcircle, cache files can be shared between different [**Build Profiles**](/build/manage-the-connections/connection-guides/). This sharing of files enables the faster generation of packages in different Build Profiles, reducing build time. Below is a simple, step-by-step example of how you can achieve this.
:::info
This simple example will use our [**CocoaPods**](https://cocoapods.org/) files in different build profiles. If you intend to use a cache other than dependencies, please refer to the documentation for the [**Cache Push**](/workflows/common-workflow-steps/build-cache/cache-push) component.
:::
:::caution
To share cache between Build Profiles, the [**Cache Pull**](/workflows/common-workflow-steps/build-cache/cache-pull) component must be added to the related pipeline.
:::
:::caution
As an example, **master** and **development** branches were used, but you can apply the same operations to different branches.
:::
:::danger
Please note that the organizational structure of Appcircle is designed in such a way as to prevent any **security vulnerabilities**. Consequently, exchanging files between organizations or sub-organizations **is not permitted**.
You can find detailed information about the Appcircle organizational structure in the documentation [**here**](/account/my-organization).
:::
1. Firstly, the caching of CocoaPods files is initiated in the **`Appcircle Team`** build profile. These files will subsequently be utilized in the **`Appcircle Team 2`** build profile. To accomplish this, the [**Cache Push**](/workflows/common-workflow-steps/build-cache/cache-push) step should be incorporated into the workflow after the **CocoaPods Install** step in the initial build profile.
2. After the successful completion of the build in the **`Appcircle Team`** build profile, the cached CocoaPods files are now available for use in the **`Appcircle Team 2`** build profile.
3. For the **`Appcircle Team 2`** build profile, the workflow steps need to be adjusted accordingly. To do this, the [**Cache Pull**](/workflows/common-workflow-steps/build-cache/cache-pull) step should be added to the workflow before the **CocoaPods Install** step for the relevant branch.
4. When the [**Cache Pull**](/workflows/common-workflow-steps/build-cache/cache-pull) step is entered, the **cache label** parameter is encountered, which is set as `$AC_BUILD_PROFILE_ID/$AC_GIT_BRANCH/cache` by default. Here, the value of `$AC_BUILD_PROFILE_ID` needs to be updated because a different profile is being used. To accomplish this, the build profile ID of the **`Appcircle Team`** where the files were cached will be used. This ID can be found directly at the **Appcircle URL**. For example, in the URL `my.appcircle.io/build/detail/edc136b9-85fc-4e0a-aa7c-602375a84f64`, `edc136b9-85fc-4e0a-aa7c-602375a84f64` represents the build profile ID. After setting the profile ID, the `$AC_GIT_BRANCH` value that was cached in the previous profile, **`Appcircle Team`**, is specified, which is set to the **development** branch. Consequently, the **cache label** parameter will appear as `edc136b9-85fc-4e0a-aa7c-602375a84f64/development/cache`.
5. After this parameter change, the CocoaPods dependencies that were cached in the **development** branch of the **`Appcircle Team`** build profile will be automatically pulled to the **master** branch of **`Appcircle Team 2`** and used directly in the pipeline.
:::danger
When sharing cache files between **Build Profiles**, please make sure that you spell your build profile ID and branch names correctly and use the [**Cache Push**](/workflows/common-workflow-steps/build-cache/cache-push) and [**Cache Pull**](/workflows/common-workflow-steps/build-cache/cache-pull) steps correctly in each profile.
:::
---
## Build Cache(Build-cache)
# [Cache Push](/workflows/common-workflow-steps/build-cache/cache-push)
Learn to streamline your workflows by pushing data to cache with our easy-to-follow cache-push tutorial. Ideal for improving build performance.
# [Cache Pull](/workflows/common-workflow-steps/build-cache/cache-pull)
Discover the essentials of cache retrieval in our cache-pull guide. Speed up your build processes by mastering the art of efficiently pulling cached data.
# [How to Share Files Between Build Profiles](/workflows/common-workflow-steps/build-cache/how-to-share-file-between-build-profiles)
Seamlessly share files between build profiles with our expert tips. This guide ensures consistent builds across profiles for better integration.
# [How to Configure Branch-Base Caching](/workflows/common-workflow-steps/build-cache/how-to-configure-branch-based-caching)
Explains how to configure the Appcircle Cache structure so that each branch uses its own isolated cache.
---
## Check Network Access
This component checks network access to common build endpoints used in Appcircle workflows. It validates connectivity to package managers, build services, APIs, and custom-defined URLs during build time.
This component uses the URLs listed in the [Network section](/self-hosted-appcircle/install-server/linux-package/configure-server/integrations-and-access/network-access) to validate access to external resources during the build on the Appcircle runner
The code checks predefined or custom URLs using `curl`, allows adding extra URLs via step inputs, logs details for non-2xx HTTP responses, and fails only on network or server errors.
:::info
- `2xx` responses indicate successful requests.
- `3xx` responses are logged as WARN (network is reachable, but the service may not respond as expected).
- `4xx`/`5xx` responses and curl transport errors (exit codes, timeouts, DNS issues, SSL errors) are treated as FAIL and stop the build.
The curl exit code is also used to determine whether the connection was established. If HTTP responses are received, their headers and bodies are logged (truncated) for further details.
:::
### Prerequisites
There are no prerequisites required before using the **Check Network Accessibility** step.
:::tip
Note that you can put the **Check Network Accessibility** component anywhere you want in the workflow. This code is used to check the accessibility of predefined endpoints and report their status.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_CHECK_NETWORK_GITHUB_APPCIRCLE` | If enabled, checks if the runner can access to `https://github.com/appcircleio/`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_RUBYGEMS` | If enabled, checks if the runner can access to `https://rubygems.org`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_INDEX_RUBYGEMS` | If enabled, checks if the runner can access to `https://index.rubygems.org`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_SERVICES_GRADLE_ORG` | If enabled, checks if the runner can access to `https://services.gradle.org`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_DL_GOOGLE_COM_ANDROID_REPOSITORY` | If enabled, checks if the runner can access to `https://dl.google.com/android/repository/repository2-1.xml`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_DL_SSL_GOOGLE_COM_ANDROID_REPOSITORY` | If enabled, checks if the runner can access to `https://dl-ssl.google.com/android/repository/repository2-1.xml`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_MAVEN_GOOGLE_COM` | If enabled, checks if the runner can access to `https://maven.google.com/web/index.html`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_REPO1_MAVEN_ORG_MAVEN2` | If enabled, checks if the runner can access to `https://repo1.maven.org/maven2/`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_CDCOAPODS_ORG` | If enabled, checks if the runner can access to `https://cdn.cocoapods.org`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_GITHUB_COCOAPODS_SPECS` | If enabled, checks if the runner can access to `https://github.com/CocoaPods/Specs`. Default: `true`. | Optional |
| `$AC_CHECK_NETWORK_FIREBASEAPPDISTRIBUTION_GOOGLEAPIS_COM` | If enabled, checks if the runner can access to `https://firebaseappdistribution.googleapis.com/$discovery/rest?version=v1`. Default: `true`. | Optional |
| `$AC_CHECK_CONNECTION_TIMEOUT` | Specifies the maximum time (**integer**, in seconds) allowed for establishing a connection to the server before the request is aborted. Default: `8` seconds. | Optional |
| `$AC_CHECK_CONNECTION_MAX_TIMEOUT` | Specifies the maximum total time (**integer**, in seconds) allowed for the entire request (including connection, data transfer, and response). Default: `20` seconds. | Optional |
| `$AC_CHECK_NETWORK_EXTRA_URL_PARAMETERS` | Additional URLs to check, defined as a comma-separated list (e.g. `https://url1.com`, `https://url2.com`). | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-check-network-access-component
---
---
## Custom Script from Git(Common-workflow-steps)
You can use **Custom Script from Git** to clone and run your own scripts directly from a Git repository as part of your Appcircle build. This step supports authenticated cloning (via username and PAT).
Before execution, the step will clone (or reuse) your repository, check out the specified branch, and execute the script based on its file extension (postfix).
If the `AC_SCRIPT_FILENAME` value includes a relative path (for example, `folder/test.sh`), the script will be located and executed from that path within the repository structure.
:::info
The step inspects your script file’s postfix (its extension—`.sh`, `.py`, `.rb`, `.pl`, `.js`, `.java`) to choose the execution path. It must match exactly.
Supported script types and their execution commands:
- `example-script.sh` → bash
- `example_script.rb` → ruby
- `example_script.py` → python
- `example-script.pl` → perl
- `example-script.js` → nodejs
- `ExampleScript.java` → java
:::
:::danger
When executing a `Java` file, the `script filename` and the `class name` within the script must match.
```ruby
javac ExampleScript.java
java ExampleScript
```
:::
:::caution
If you are seeing the following error in the build log, please ensure that both the `username` and the `personal access token` (PAT) are set correctly. This error is returned by the Git provider when authentication fails due to an `incorrect or missing username or PAT`:
```bash
fatal: could not read Username for Git provider
```
:::
### Prerequisites
There are no prerequisites required before using the **Custom Script from Git** step.
:::tip
Note that you can put the **Custom Script from Git** component anywhere you want in the workflow. This step is used to add different capabilities to the existing workflow. As well as the [**Custom Script**](/workflows/common-workflow-steps/custom-script).
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_SCRIPT_FILENAME` | Specifies the exact name of the script file to execute within the Git repository (e.g., test.sh, code.rb or relative_path/python.py). | Required |
| `$AC_SCRIPT_EXTRA_PARAMETERS` | Additional parameters to pass to the script (comma "," separated; if a parameter has an empty character, define it with " "; e.g. param1,param2,"param3 with spaces",param4). | Optional |
| `$AC_SCRIPT_REPO_DIR` | If the Git repository has already been cloned in a previous step of the same workflow, set the Repository Directory Output here. This input is required if `AC_SCRIPT_REPO_CLONE_URL` is not provided. | Optional |
| `$AC_SCRIPT_REPO_CLONE_URL` | Git repository clone URL. Required if the Repository Directory Output is not provided. (e.g. exampleGit.exampleRepo.git). This input is required if `AC_SCRIPT_REPO_DIR` is not provided. | Optional |
| `$AC_SCRIPT_GIT_USERNAME` | Git provider username for authentication. This is required if the AC_SCRIPT_REPO_DIR input is not provided and the Git repository is private. | Optional |
| `$AC_SCRIPT_GIT_PAT` | Git provider personal access token for authentication. This is required if the AC_SCRIPT_REPO_DIR input is not provided and the Git repository is private. | Optional |
| `$AC_SCRIPT_GIT_BRANCH` | Name of the branch to check out from the script repository. If not specified, the repository's default branch will be used. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
| `AC_SCRIPT_REPO_OUTPUT_DIR` | The directory path where the custom script repository is located on the runner. This output can be reused in subsequent workflow steps. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-custom-script-from-git-component
---
---
## Custom Script
You can use **Custom Script** steps for additional functionalities in your builds. Appcircle will run the commands in your custom scripts and perform the specified actions. These scripts will be run on the runner and you can use any functionality of the build environment as you need.
### Prerequisites
There are no prerequisites required before using the **Custom Script** step.
:::tip
Note that you can put the **Custom Script** component anywhere you want in the workflow. This step is used to add different capabilities to the existing workflow.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
If you need to use sensitive variable in your script, please do not use these sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `Execute` | You can run your script as **`Bash`**, **`Ruby`**, **`Python`**, or **`Nodejs`**, based on the selected **Execute With** environment. | Required |
| `Script` | With the **Script** input variable, you can add the script you want to run and run it directly in the selected language. If you leave this input blank, it will proceed to the next step without taking any action. | Optional |
:::caution
Note that the **Script** area works according to the selected language variable. If you want to run a script in any language, make sure that you select the language correctly.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-custom-script-component
---
## FAQ
### How to change Java version
Appcircle currently has `OpenJDK 17` (default), `OpenJDK 8`, `OpenJDK 11` and `OpenJDK 21`.
[Android Build](/workflows/android-specific-workflow-steps/android-build) step uses `OpenJDK 17` as default JDK version.
To switch JDK versions, you can now use the dedicated [**Select Java Version**](/workflows/common-workflow-steps/select-java-version) component, so there is no need to use **Custom Script** for this task. For further details on this component, refer to the documentation:
- [Select Java Version](/workflows/common-workflow-steps/select-java-version)
However, if you prefer to update or improve it manually on **Custom Script**, the source code is available here:
- [Select Java Version - Source Code](https://github.com/appcircleio/appcircle-select-java-version-component)
### How to install a new package to the build machine?
You can use the compatible package managers to install packages.
For the macOS build machines for iOS builds, \_brew \_is a commonly used package manager with commands like `brew install maven`
For the Linux (Debian) build machines for Android builds, _apt-get_ can be used for 3rd party packages such as `apt-get -y install maven`
### How to change the package name/application ID dynamically?
With custom scripts, you can edit the Info.plist and the build.gradle files.
```bash title="iOS sample for Info.plist"
cd $AC_REPOSITORY_DIR/Your-Target-Folder
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier io.myapp" "./Info.plist"
```
```bash title="Android sample for build.gradle"
cd $AC_REPOSITORY_DIR/app
sed -i '' 's/old-value/new-value/g' build.gradle
```
### How to access a file in the repository directory?
For each step in the workflow, you can view the input and output variables in the step configuration.
The repository directory is an output of the Git Clone step and its patch can be accessed with the `$AC_REPOSITORY_PATH` environment variable by any step added after the **Git Clone** step. An example is as follows:
```bash
cd $AC_REPOSITORY_DIR
cat README
```
### How to a add a file as a downloadable build artifact?
You can add any file to the output directory that contain the build artifacts using the `$AC_OUTPUT_DIR` environment variable. An example is as follows:
```bash
cd $AC_REPOSITORY_DIR/app/build/reports/
mv lint-results* $AC_OUTPUT_DIR/
```
### How to break pipeline on low test coverage
This document provides a sample custom script written in Ruby that can be integrated into your CI/CD pipeline to enforce a minimum test coverage threshold. The script is designed to break the pipeline if the covered test result falls below a specified percentage.
:::danger
Please note that this custom script must be placed after the [**Test Reports**](/continuous-testing/android-testing/running-android-unit-tests#generating-test-report) step in the workflow.
:::
```ruby
require 'json'
def env_has_key(key)
!ENV[key].nil? && ENV[key] != '' ? ENV[key] : abort("Missing #{key}.")
end
output_dir = env_has_key('AC_OUTPUT_DIR')
def read_json_file(test_result_file_path)
JSON.parse(File.read(test_result_file_path))
end
def extract_line_coverage(json_data)
json_data['coverage']['lineCoverage']
end
begin
test_result_file_path = "#{output_dir}/test_results.json"
json_data = read_json_file(test_result_file_path)
line_coverage = extract_line_coverage(json_data)
puts "Current Line Coverage: % #{line_coverage * 100}"
min_coverage = 2.0
puts "Minimum coverage percentage: #{min_coverage}"
if (line_coverage * 100) < min_coverage
puts "Coverage is #{line_coverage} and below minimum coverage percentage given #{min_coverage}. \nExiting."
exit (1)
else
puts "Coverage is above the threshold. It is clear."
end
rescue StandardError => e
puts "An error occurred: #{e.message}"
end
```
:::info
Please feel free to edit the following variables according to your own requirements:
- `test_result_file_path`: The file path of the test result file from which to retrieve the covered percentage value.
- `min_coverage`: The minimum percentage required for the pipeline to continue without breaking.
:::
### How to use environment variables along with the `sudo` command?
Both user-created and Appcircle-reserved [environment variables](/build/build-environment-variables#adding-key-and-text-based-value-pairs) can be used within a custom script with any required command. But, by default, commands that are triggered with `sudo` will not reach them since the user scope is changed.
In order to use all user environment variables with `sudo`, you should add the `-E` argument to the `sudo` command. The `-E` (preserve environment) option indicates to the security policy that the user wishes to preserve their existing environment variables.
For instance, you can check the list of environment variables in the build pipeline using the command below.
```bash
sudo -E printenv
```
### How can I send a custom email?
Appcircle provides a **ready-to-use email** structure in the [**Testing Distribution**](/testing-distribution/create-or-select-a-distribution-profile#share-binary) and [**Publish**](/publish-integrations/common-publish-integrations/get-approval-via-email) modules. This structure varies across the two modules. If desired, the user can customize this structure by using the [**Custom Script**](/workflows/common-workflow-steps/custom-script) below to send their own custom email.
The following Bash script is set to use a **Gmail SMTP Server**. For more information, please visit [**Gmail SMTP Server**](https://support.google.com/a/answer/176600?hl=en) documentation.
```bash
# Set SMTP server
CS_HOST="smtp.gmail.com"
CS_PORT="587"
CS_ACCOUNT="gmail"
# Make sure to replace CS_EMAIL, CS_USERNAME, and CS_PASSWORD with your account details
CS_EMAIL="your-email-address@gmail.com"
CS_USERNAME="your-email-address@gmail.com"
CS_PASSWORD="your-email-password"
# Set email details
CS_EMAIL_SUBJECT="Test Email Subject"
CS_EMAIL_TO="recipient-address@mail.com,recipient-2-address@mail.com"
# This part will be used for visualization
CS_EMAIL_FROM="Sender Name "
CS_EMAIL_BODY="This is the body of the sent email."
# Set TLS and SSL usage
CS_USE_TLS="True"
CS_USE_SSL="False"
# Detect operating system
os=""
if uname -a | grep -iq "darwin"; then
os="darwin"
elif uname -a | grep -iq "linux"; then
os="linux"
fi
# Create the .msmtprc file with appropriate permissions
cat < ~/.msmtprc
defaults
auth on
tls on
EOF
# Check if OS is supported and install necessary packages
if [ "$os" == "darwin" ]; then
if ! command -v brew > /dev/null 2>&1; then
echo "Can't find brew installation; make brew command visible or install homebrew and try again."
exit 1
fi
brew install mailutils
brew install msmtp
echo "set sendmail=/usr/local/bin/msmtp" | sudo tee -a /etc/mail.rc
{ echo -n "tls_fingerprint " && msmtp --serverinfo --tls --tls-certcheck=off --host=$CS_HOST --port=$CS_PORT | egrep -o "([0-9A-Za-z]{2}:){31}[0-9A-Za-z]{2}"; } >> ~/.msmtprc
elif [ "$os" == "linux" ]; then
if ! command -v apt > /dev/null 2>&1; then
echo "Apt is not installed; install apt and try again."
exit 1
fi
apt-get update
apt-get install -y mailutils msmtp msmtp-mta
echo "tls_trust_file /etc/ssl/certs/ca-certificates.crt" >> ~/.msmtprc
else
echo "Unsupported OS: $os. Darwin or Linux was expected."
exit 1
fi
cat <> ~/.msmtprc
logfile ~/.msmtp.log
account $CS_ACCOUNT
host $CS_HOST
port $CS_PORT
from $CS_EMAIL
user $CS_USERNAME
password $CS_PASSWORD
account default: $CS_ACCOUNT
EOF
# Restrict permissions for the .msmtprc file to avoid security issues
chmod 600 ~/.msmtprc
# Cleanup .msmtprc whether script ends with success or failure
function cleanup {
cat /dev/null > ~/.msmtprc
}
trap cleanup EXIT
# Send email
echo "From: $CS_EMAIL_FROM
To: $CS_EMAIL_TO
Subject: $CS_EMAIL_SUBJECT
$CS_EMAIL_BODY" | msmtp --debug --from=$CS_EMAIL -t $CS_EMAIL_TO
```
:::info Script Execution
This script is written in `Bash`. When running with **Custom Script**, you need to set the `Execute With` parameter as `Bash`. For more information, please visit the [**Custom Script Input Variables**](/workflows/common-workflow-steps/custom-script#input-variables) documentation section.
:::
:::note Input Variables
When using your own SMTP server credentials for the three variables below, using **Environment Variables** is strongly suggested since this prevents sensitive information, such as passwords, from being exposed to unauthorized individuals.
For more detailed information, please refer to the [**Environment Variables**](/build/build-environment-variables) documentation.
- **$CS_EMAIL**: SMTP Server email address.
- **$CS_USERNAME**: Sender email address.
- **$CS_PASSWORD**: Sender email address password.
Otherwise, to send an email, you need to have some information, such as the email subject, sender email, and recipient email. You can use these parameters to:
- **$CS_EMAIL_SUBJECT**: Subject of sending email
- **$CS_EMAIL_TO**: Recipient email address.
- **$CS_EMAIL_FROM**: Sender email address.
- **$CS_EMAIL_BODY**: Content of sending email.
:::
:::tip Recipient Email Address
If you want to send an email to multiple email addresses instead of a single email address, in the `$CS_EMAIL_TO` parameter, it will be enough to write all the addresses to send an email separated by commas. For example, `$CS_EMAIL_TO=example@email.com,example2@email.com`
:::
:::danger Sensitive Informations
Since the variables mentioned above, which need to be provided by the user, contain **sensitive** information like **passwords**, please use [**Environment Variables**](/build/build-environment-variables#adding-key-and-text-based-value-pairs) for these types of values.
To do this, comment out or remove the sensitive variables such as `$CS_EMAIL`, `$CS_USERNAME`, and `$CS_PASSWORD` defined at the top of the script, and add them as environment variables instead.
For other variables that need to be defined, you can also make use of environment variables.
:::
:::caution Self-hosted Runners
If you're using self-hosted runners and they're not starting to build pipelines with clean states as in Appcircle Cloud, this custom script can be insecure to use since the consecutive pipelines are using the same build environment, and it might have last sent email sensitive configuration in some cases.
In order to send email, the script persists SMTP configuration to the `~/.msmtprc` file. Although the script has a cleanup mechanism that works for success or failure cases, it cannot work on all conditions. For example, the "cancel build" case should be considered. In this case, the `~/.msmtprc` might not be cleaned, and it can be read in the next pipeline.
If you have configured runners similar to the Appcircle Cloud pools and they are wiped off after a build is executed to provide a fresh environment for every build, then there is nothing to consider; it's safe.
:::
:::info Username and Password for Google SMTP Users
When you want to send an email with your Gmail account using **Google's SMTP** server, you must first **authenticate** to the Google SMTP server. For this process, you need to enter your **App Password** in the password field.
In order to generate this password, **2FA authentication** must be turned on in your **Google account**. You can generate and retrieve this password from the **App Passwords** section under **Google Account management**. For detailed information about **App Passwords**, please visit the [**Google App Password**](https://support.google.com/accounts/answer/185833?hl=en) documentation.
:::
:::tip Protocols and SMTP Host
This script uses the TLS protocol for SMTP server usage. Since the **Gmail SMTP** server is used in the script, the required protocols are pulled from **Google's SMTP** server using the `$CS_HOST` parameter. If you are using your own SMTP server, don't forget to change the `$CS_HOST` value here.
On the other hand, to change **TLS or SSL** usage, you can change the protocol by setting the `$CS_USE_TLS` or `$CS_USE_SSL` parameters in the script to `true` or `false`. Note that you need to change the `$CS_PORT` parameter when using **SSL** and **TLS**.
For more information about protocols, please visit the [**Google's TLS and SSL**](https://support.google.com/a/answer/100181) documentation.
:::
:::danger Sender Email and Spoofing
To use an SMTP server, this script first installs the necessary certificates, then authenticates to the server with the required credentials and sends the prepared email content to the recipient's email address. In order to change the sender's email address, the SMTP server must allow it by providing the necessary permissions. Otherwise, SMTP servers will send the email using the authenticated email address to prevent spoofing (impersonating someone else).
:::
### How can I send the Appcircle build log to another platform?
To send your build log to another platform using an API, you can access the log in your workflow through `$AC_LOGFILE`.
Here is an example using Dropbox's [file-upload](https://www.dropbox.com/developers/documentation/http/documentation#files-upload) API. Replace it with the appropriate API for your platform. If you are going to use DropBox, you can follow the document below to obtain the access token:
- [Generate an access token for your own account](https://dropbox.tech/developers/generate-an-access-token-for-your-own-account)
:::danger
Ensure sensitive data, like access tokens, are defined as private environment variables. Learn more:
- [Adding key and text-based value pairs](/build/build-environment-variables#adding-key-and-text-based-value-pairs)
:::
```bash
current_datetime=$(date +"%Y-%m-%d-%H-%M")
dropbox_log_filename="/home/appcircle-logs/ac-log-$current_datetime.txt"
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header "Authorization: Bearer $DROPBOX_ACCESS_TOKEN" \
--header "Dropbox-API-Arg: {\"autorename\":false,\"mode\":\"add\",\"mute\":false,\"path\":\"$dropbox_log_filename\",\"strict_conflict\":false}" \
--header "Content-Type: application/octet-stream" \
--data-binary @"$AC_LOGFILE"
```
This script generates a timestamped log file (e.g., `ac-log-2024-10-01-14-55.txt`) in the `/home/appcircle-logs` in Dropbox.
:::caution
Ensure that the **Custom Script** step runs after the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step to capture the full log.
:::
### How can I print the status of workflow steps with detailed information?
If you want to track or share the status of your workflow or individual steps during a build, you can use the following environment variables:
- **`$AC_BUILD_STATUS`**: Displays the running status of the workflow so far.
- **`$AC_BUILD_STEPS_STATUS`**: Displays detailed information about each executed step.
:::caution
The **runner** version must be **1.8.0 or later** to use the above two environment variables.
:::
However, the output of `$AC_BUILD_STEPS_STATUS` is in raw JSON format, which may not be easy to read directly. To make it more readable, you can use the following Ruby script to format and print the information in a user-friendly way:
```ruby
require 'json'
puts "AC_BUILD_STATUS: #{ENV['AC_BUILD_STATUS']}"
# Read the environment variable
json_data = ENV['AC_BUILD_STEPS_STATUS']
begin
# Parse and beautify the JSON
parsed_data = JSON.parse(json_data)
pretty_json = JSON.pretty_generate(parsed_data)
# Output the formatted JSON
puts "AC_BUILD_STEPS_STATUS:"
puts pretty_json
rescue JSON::ParserError => e
puts "Failed to parse JSON: #{e.message}"
end
```
:::info
The script above is written in Ruby. To execute it, select `Ruby` as the `Execute with` option in the **Custom Script** step.
:::
:::warning
To ensure your script works even if one of the steps in the workflow fails (and you want to capture the failed status as well), enable the **"Always run this step even if the previous steps fail"** option.
:::
If you add a **Custom Script** step with the code above after the **Git Clone** step in your workflow, the script will generate an output similar to this:
```json
AC_BUILD_STATUS: Success
AC_BUILD_STEPS_STATUS:
[
{
"StepName": "Activate SSH Private Key",
"BuildStatus": "Success",
"Duration": 0.133102,
"StartDate": "2024-12-30T16:48:47.919386Z",
"FinishDate": "2024-12-30T16:48:48.052488Z"
},
{
"StepName": "Git Clone",
"BuildStatus": "Success",
"Duration": 1.90708,
"StartDate": "2024-12-30T16:48:48.186532Z",
"FinishDate": "2024-12-30T16:48:50.093612Z"
}
]
```
:::info
Steps that are disabled in the workflow will not appear in the above output.
:::
Simply include this script in your workflow to better understand and monitor the status of your workflow steps.
### How to generate the build log URL during the build time?
When a build is triggered in Appcircle, the build log starts to generate. If you need access to the build log URL, you can retrieve two different output links by adding the Bash script below to the relevant workflow.
:::warning Log URL Changes After Build is Finished
Please note that the links for the **in-progress** and the **completed** build logs are different, so be sure to use them according to your specific needs.
No specific action is required for these variables, except that the base URL (`base_url`) may need to be updated if you are using a self-hosted Appcircle.
In the script only base_url may need to be updated if you are using self-hosted Appcircle.
:::
The related build profile can be used simply by adding the Custom Script in Bash.
Assignments are made automatically using environment variables defined by the system, which are represented by values starting with `$`. These variables are explained in detail in the [**Reserved Variables**](/environment-variables/appcircle-specific-environment-variables) section.
```bash
build_id=$AC_QUEUE_ID
profile_id=$AC_BUILD_PROFILE_ID
commit_id=$AC_COMMIT_ID
base_url="https://my.appcircle.io/build/detail"
AC_IN_PROGRESS_BUILD_LOG_URL="${base_url}/${profile_id}?modal=/build/modal/Logs&profileId=${profile_id}&commitId=${commit_id}&scope=build&buildId=fakeID${build_id}"
echo "In-Progress Build Log URL: $AC_IN_PROGRESS_BUILD_LOG_URL"
AC_COMPLETED_BUILD_LOG_URL="${base_url}/${profile_id}?modal=/build/modal/Logs&profileId=${profile_id}&commitId=${commit_id}&buildId=${build_id}&scope=build&method=get"
echo "Completed Build Log URL: $AC_COMPLETED_BUILD_LOG_URL"
# To use these URL variables in later steps within the same workflow, add them to ENV_FILE_PATH as shown below; otherwise, they will not be accessible.
echo "AC_COMPLETED_BUILD_LOG_URL=$AC_COMPLETED_BUILD_LOG_URL" >> $AC_ENV_FILE_PATH
echo "AC_IN_PROGRESS_BUILD_LOG_URL=$AC_IN_PROGRESS_BUILD_LOG_URL" >> $AC_ENV_FILE_PATH
```
### How do I store and re-use custom scripts from a Git repository?
If you are looking for a modular way to manage your Appcircle CI custom scripts, you can host your script files in a Git repository and pull them dynamically into the build environment. This approach helps keep your workflow clean and allows centralized version control for your custom scripts.
This section explains how to clone a private Git repository and execute a specific script file from it using the Custom Script step.
The following Bash script has been tested on multiple Git providers using personal access tokens (PAT) for authentication.
:::info
If you are using a public repository, you do not need to obtain an access token. In this case, you can use the Git clone command directly in your script without including any authentication.
:::
To use this approach, you must first convert your Bash, Ruby, Python, or Nodejs script into a Git repository. This means placing your script file into a Git repository and pushing it to your preferred Git provider (e.g., GitHub, GitLab, Bitbucket, Azure).
:::caution
It is recommended to create a repository specifically for the desired custom script as a Bash, Ruby, Python, or Nodejs file.
:::
:::warning Required Permissions
To successfully clone a repository, your personal access token (PAT) must have at least read access to the repository.
Write or admin permissions are not required for this use case.
Note: When creating a personal access token with GitLab, the token must have at least Reporter access level.
Note: Bitbucket requires a user-level personal access token for Git operations such as cloning. Repository-level access tokens are not supported for Git over HTTPS and will result in authentication errors if used.
:::
This script demonstrates how to fetch a Bash script from a private GitHub Cloud repository as an example. Adjustments are required when using a different Git provider or executing Ruby code.
:::tip Advantages of Git-Based Custom Script Management
Using a Git repository to manage your custom scripts provides several key advantages:
Reusability: The same script repository can be used across multiple workflows and build profiles without duplication.
Traceability: Every change to the script is version-controlled and can be audited or rolled back via Git history.
Collaboration: Multiple team members can contribute and review changes through pull requests.
CI/CD Compatibility: Changes in scripts are automatically reflected in builds without needing to manually update workflows.
Branching Support: Different versions of scripts can be maintained using Git branches and referenced independently.
This approach significantly improves scalability, maintainability, and consistency in teams managing multiple CI pipelines.
:::
```bash
#! /bin/bash
set -e
# Git clone URL
CS_GIT_CLONE_URL="https://example.org/exampleuser/examplerepo.git"
CS_GIT_USERNAME="$YOUR_GIT_USERNAME"
CS_GIT_PAT="$YOUR_GIT_PAT"
CS_GIT_BRANCH="main" # or desired branch name
CS_GIT_SCRIPT_FILE="test.sh" # or "Example.rb"
# Create authorization header using Base64 encoding
AUTH_STRING="$CS_GIT_USERNAME:$CS_GIT_PAT"
ENCODED_AUTH=$(printf "%s" "$AUTH_STRING" | base64)
HEADER_VALUE="Authorization: Basic $ENCODED_AUTH"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
CS_ROOT_FOLDER="Cloned_Script_$TIMESTAMP"
mkdir -p "$CS_ROOT_FOLDER"
cd "$CS_ROOT_FOLDER"
# Clone the repository using the authorization header
echo "Cloning the repository..."
git -c http.extraheader="$HEADER_VALUE" clone "$CS_GIT_CLONE_URL"
# Navigate into the cloned repository
CS_FOLDER_NAME=$(basename "$CS_GIT_CLONE_URL" .git)
cd "$CS_FOLDER_NAME" || { echo "Failed to enter the directory."; exit 0; }
# Switch to the target branch
git checkout "$CS_GIT_BRANCH"
# Run the script file if it exists
if [ ! -f "./$CS_GIT_SCRIPT_FILE" ]; then
echo "Script file not found: $CS_GIT_SCRIPT_FILE"
exit 1
fi
case "$CS_GIT_SCRIPT_FILE" in
*.sh)
chmod +x "./$CS_GIT_SCRIPT_FILE"
./"$CS_GIT_SCRIPT_FILE"
;;
*.rb)
ruby "$CS_GIT_SCRIPT_FILE"
;;
*)
echo "Unsupported script type: $CS_GIT_SCRIPT_FILE"
exit 1
;;
esac
```
:::caution
If you are seeing the following error in the build log, please ensure that both the username and the personal access token (PAT) are set correctly. This error is returned by the Git provider when authentication fails due to an incorrect or missing username or PAT:
```bash
fatal: could not read Username for Git provider
```
:::
---
## Danger
[Danger](https://danger.systems/ruby/) automates code reviews through CI tools, aiding both code reviewers and developers who submit pull requests. It reduces the time reviewers spend on routine tasks, allowing more efficient code evaluation.
You can easily automate opened PRs with Appcircle's Danger integration.
For detailed information on the benefits that Danger, please refer to the following blog post:
https://appcircle.io/blog/danger-in-ci-automate-your-mobile-code-reviews
:::danger
This tool does not support AzureDevOps. Therefore, if your repository is hosted on AzureDevOps, this tool will not function. Please use the [**Azure Bot for Swiftlint**](/workflows/ios-specific-workflow-steps/azure-bot-for-swiftlint)(for iOS) and [**Azure Bot for Detekt Report**](/workflows/android-specific-workflow-steps/azure-bot-for-detekt-report)(for Android) components instead.
:::
:::info
Danger integration currently supports Ruby only. For more details, see [**Danger for Ruby**](https://danger.systems/ruby/).
:::
:::info Danger Version
Please remember that you must use the one of **latest** versions of **Danger** in your project. To avoid encountering any errors while working with Danger on Appcircle, you must have the latest version of Danger installed in your Gemfile.
**Example Gemfile:**
```ruby
source "https://rubygems.org"
gem "danger", "9.5.3"
.
.
.
. //Other Gems
```
:::
### Prerequisites
Before running the **Danger** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The repository needs to be cloned to begin the code review process. After this step, the variable `$AC_REPOSITORY_DIR` will be set. |
:::caution
Note that this component synchronizes with the [**Appcircle Triggers**](/build/build-process-management/build-manually-or-with-triggers/#managing-triggers-for-builds). Without a setup trigger, opening a PR will not trigger the pipeline, and Danger will not function.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
:::caution Danger Inputs
The Danger component requires the following inputs to work with Git providers. Define the input information required by your Git provider in the Appcircle Environment Variable and provide it directly to the component input.
This way, when the build starts, Appcircle will register these environment variables to the runner, and the Danger component will automatically use this information.
For more information, please visit the [**Environment Variables**](/build/build-environment-variables) documentation.
:::
| Variable Name | Description | Status |
|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_DANGER_PATH` | Specifies path of Dangerfile. This path comes from `$AC_REPOSITORY_DIR`. If DangerFile is in main directory of your repository. Do not change. | Required |
| `$AC_DANGER_EXTRA_PARAMETERS` | Extra command line parameters. For Example: enter `--verbose` for verbose mode. | Optional |
| `$DANGER_GITHUB_API_TOKEN` | Github Access Token for the bot user. | Optional |
| `$DANGER_GITHUB_HOST` | The host that GitHub is running on. For example: `git.corp.com` | Optional |
| `$DANGER_GITHUB_API_BASE_URL` | The host that the GitHub Enterprise API is reachable on. For example: `https://git.corp.com/api/v3` | Optional |
| `$DANGER_GITLAB_API_TOKEN` | GitLab Access Token for the bot user. | Optional |
| `$DANGER_GITLAB_HOST` | The host that GitLab is running on. For example: `git.corp.com` | Optional |
| `$DANGER_GITLAB_API_BASE_URL` | The host that the GitLab API is reachable on. For example: `https://git.corp.com/api/v4` | Optional |
| `$DANGER_BITBUCKETCLOUD_USERNAME` | Bitbucket username for the bot user. | Optional |
| `$DANGER_BITBUCKETCLOUD_PASSWORD` | Bitbucket password for the bot user. | Optional |
| `$DANGER_BITBUCKETCLOUD_UUID` | Bitbucket UUID of the bot user. | Optional |
| `$DANGER_BITBUCKETSERVER_USERNAME` | Bitbucket username for the bot user. | Optional |
| `$DANGER_BITBUCKETSERVER_PASSWORD` | Bitbucket password for the bot user. | Optional |
| `$DANGER_BITBUCKETSERVER_HOST` | The host that Bitbucket is running on. For example: `git.corp.com` | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-danger-component
---
## FAQ
### How can I solve the `bundler: command not found: danger` error?
This error occurs when the Danger gem is missing in your environment.
To fix it, add the following line to your Gemfile:
```
gem 'danger'
```
---
## Data Theorem Mobile Secure
The **Data Theorem Mobile Secure** step integrates the [Data Theorem Mobile Secure](https://www.datatheorem.com/products/mobile-secure/) service into the CI/CD workflow on Appcircle. This step allows users to automatically scan their mobile applications for security vulnerabilities and compliance issues, facilitating proactive security testing. Developers can identify and resolve potential security threats before deploying their mobile applications.
### Prerequisites
Before running the **Data Theorem Mobile Secure** step, you must complete certain prerequisites, as detailed in the table below:
#### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | Generates the app required for the **Data Theorem Mobile Secure** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | Required if using a signed app. Processes the output for signing. If already signed, this step can be skipped. |
#### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
#### For Android Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps#flutter-build-for-android) | Generates the app required for the **Data Theorem Mobile Secure** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | Required if using a signed app. Processes the output for signing. If already signed, this step can be skipped. |
#### For iOS Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps#flutter-build-for-ios) | Prepares the Flutter project for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter). |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ----------------------- | ---------------------------------------------------------------------------------------------- | -------- |
| `$AC_DT_FILE_PATH` | Specifies the file path to the IPA or APK to upload. For Android, use `$AC_APK_PATH` or `$AC_SIGNED_APK_PATH`. For iOS, use `$AC_EXPORT_DIR/Myapp.ipa`. | Required |
| `$AC_DT_UPLOAD_API_KEY` | Specifies the Data Theorem Mobile Secure Upload API Key. You need to obtain your organization's Upload API key from the portal. For more details, refer to [this document](https://docs.securetheorem.com/mobile_security_devops/uploading_mobile_apps.html). | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-datatheorem-component
---
## Export Build Artifacts
# Export Build Artifact
Exports the specified build artifacts from the build agent to the Appcircle dashboard. The exported files will be available for download in the artifacts section of the completed build.
:::danger
Sending applications to **Publish**, **Enterprise App Store**, or **Testing Distribution** will not work without this step.
:::
### Prerequisites
There are no prerequisites required before using the **Export Build Artifact** step.
:::note
We **recommend** using it as the **last** step in your workflow.
:::
:::danger
Remember, if you set a step to run after this step, artifacts generated after this step **will not be exported**. This step only exports the artifacts produced before it.
:::
### Download Exported Artifacts
You can access and download the exported artifacts by clicking on the three dots (**⋮**) in the Build list and selecting download artifact.
:::caution
If you use the **Default Workflow** templates, the option "**Always run this step even if the previous steps fail**" is already enabled for the **Export Build Artifacts** step by default. However, **if you want to ensure that the build log and any extracted artifacts are available even if the pipeline fails, you need to turn on this option.**
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_UPLOAD_DIR` | If a folder path is specified, the files in this folder will be exported as artifacts. If a file path is specified, that file will be exported as an artifact. Uploading files with a 0 byte size in the specified path will be skipped. The default folder path is **`$AC_OUTPUT_DIR`**. | Required |
| `$AC_DISABLE_UPLOAD_ON_FAIL` | The Delete Artifact for failed build variable is **false** by default. This variable allows you to export artifacts if a build succeeds, so that they do not take up disk space. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-export-build-artifacts
---
## Fastlane
Appcircle supports [**Fastlane**](https://fastlane.tools/) for build automation as a supplementary feature to Appcircle's own build automation.
With Appcircle, you can automate your build and signing processes with the flexible workflow structure, and you can also use Fastlane as a workflow step within the build workflows.
### Prerequisites
Before running the **Fastlane** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The repo needs to be cloned in order to start the Fastlane process. After the clone, Fastlane will be installed. After this step works, the variable `$AC_REPOSITORY_DIR` will be created. |
:::caution
Fastlane needs project files to work. If there is no **Git Clone** step in your workflow, it will give an error because it cannot find the relevant files of the project.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_FASTLANE_DIR` | This path is Fastlane's path in the project. By default, it is `$AC_REPOSITORY_DIR`. If your Fastlane file is in a different location in the repo, please change it. | Required |
| `$AC_FASTLANE_LANE` | Fastlane lane. For example: `android deploy` or `ios release`. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-fastlane-component
---
## FAQ
### How to run a Fastlane plug-in directly?
With Appcircle's Fastlane integration, you can easily run the [lane](https://docs.fastlane.tools/advanced/lanes/) you want with the Fastfile in your project. But you can also run a [Fastlane plugins](https://rubygems.org/search?query=fastlane-plugin-) directly in the pipeline without any Fastlane integration.
You can easily add the [Fastlane plugins](https://rubygems.org/search?query=fastlane-plugin-) you want to run, which are not included in your Fastfile and are available on the Fastlane plugins, to the pipeline via a [**Custom Script**](/workflows/common-workflow-steps/custom-script) and run them easily. For all available plugins, please visit the [**Fastlane plugins**](https://docs.fastlane.tools/plugins/available-plugins/) documentation.
The example `Bash` script below shows how to run the Fastlane plugin with a gem file. In this example, `fastlane-plugin-json` is used as a Fastlane plugin. Add a **Custom Script** step to your [**Workflows**](/workflows) to run the following script.
```bash
cd $AC_REPOSITORY_DIR
gem install fastlane-plugin-json
echo "gem 'fastlane-plugin-json'" >> Gemfile
fastlane run read_json json_path:./example.json
```
The same command sequence should be used to run different Fastlane plugins. Once the plugin is installed, it is run with the `fastlane run` command. The necessary actions must be completed for the plugin to work correctly. The command used to run Fastlane plugin is as follows:
```bash
fastlane run [action] parameter:value
```
- `Action`: The plugin will be run.
- `Parameter`: Input parameter expected by the plugin.
- `Value`: Input value to be entered.
If the plugin you are using contains more than one parameter, you can use the parameters side by side as below.
```bash
fastlane run [action] parameter1:value1 parameter2:value2
```
For plugin details and the actions they contain, visit the repository of the [**Fastlane plugins**](https://docs.fastlane.tools/plugins/available-plugins/).
---
## File Size Check
The **File Size Check** component checks the size of your generated **IPA**, **APK** or **AAB** file. It compares it against the size you have given and if the size is exceeded, it either breaks the pipeline or shows it as a warning.
### Prerequisites
The workflow steps that need to be executed before running the **File Size Check** workflow step, along with their respective reasons, are listed in the table below.
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) | If your project is an **iOS** project using **Objective-C/Swift** or **React Native**, you should use this step to generate the file before checking the app file size. This step generates the **IPA** file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps/flutter-build-for-ios) | If your project is an **iOS** project using **Flutter**, you should use this step to generate the file before checking the app file size. This step generates an **IPA** file. |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | If your project is an **Android** project using **Java/Kotlin** or **React Native**, you should use this step to generate the file before checking the app file size. This step generates **APK** or **AAB** files. |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps/flutter-build-for-android) | If your project is an **Android** project using **Flutter**, you should use this step to generate the file before checking the app file size. This step generates **APK** or **AAB** files. |
:::danger
If you use a different build step than the ones mentioned above to generate the app, then the **File Size Check** step depends on this particular step.
:::
#### For iOS
#### For Android
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::note
When you enter this component detail, you need to specify the **File Size** and **Check Action**. The file size parameter here represents the **maximum allowable** size of the **IPA**, **APK** or **AAB** file. If the archived application size exceeds this size, the pipeline will be **broken** or **warned** according to the **fail** or **warn** option you specify in the check action parameter.
If you select **warn**, this is how it will appear in your build list:
:::
| Variable Name | Description | Status |
|----------------------------------|------------------------------------------------|--------------------------|
| `$AC_ANALYZER_SOURCE_PATH` | Full path of the **APK**, **AAB** or **IPA** file. Don't change it to use default artifacts. This path will be generated after the build steps. | Required |
| `$AC_ANALYZER_FILESIZE_THRESHOLD`| File size threshold of the artifacts in megabytes. Enter **0** to disable the check. The default variable is **200MB**. | Required |
| `$AC_ANALYZER_FILESIZE_ACTION` | Specifies whether to issue a warning or fail the workflow if the threshold limit is exceeded. The options are **warn** and **fail**, with the default being **fail**. | Optional |
:::caution
Note that this step only controls the size of the application generated according to the size variable you specify.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-filesize-component
---
## Firebase App Distribution
[**Firebase App Distribution**](https://firebase.google.com/docs/app-distribution) is a platform provided by [Google Firebase](https://firebase.google.com/) that enables developers to distribute pre-release versions of mobile apps to testers and stakeholders. This platform streamlines the distribution of Android and iOS apps and offers features such as targeted distribution, release notes, and feedback collection.
The Appcircle **Firebase App Distribution** step enables you to efficiently distribute your mobile applications to testers and relevant parties directly from your Appcircle workflow. With this integration, you can optimize the distribution process and gather valuable feedback to iterate on your app before its public release.
:::caution
Please note that you can also distribute your app via Appcircle. Utilizing Appcircle's distribution modules enhances manageability within the platform.
For more details, please refer to the following links:
- [**Appcircle Testing Distribution**](/testing-distribution/)
- [**Appcircle Enterprise App Store**](/enterprise-app-store/)
- [**Appcircle Publish**](/publish-to-stores-module/)
:::
### Prerequisites
Before running the **Firebase App Distribution** step, you must complete certain prerequisites, as detailed in the table below:
#### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | Generates the app required for the **Firebase App Distribution** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | Required for signing the app; processes the app for signing. This step can be skipped if the app is already signed. |
#### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
#### For Android Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps#flutter-build-for-android) | Generates the app required for the **Firebase App Distribution** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | Required for signing the app; processes the app for signing. This step can be skipped if the app is already signed. |
#### For iOS Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps#flutter-build-for-ios) | Prepares the Flutter project for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter). |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_FIREBASE_VERSION` | Specifies the Firebase version to be used. Enter your Firebase version, such as `v11.11.0`, for a specific version. The default value is `latest`. | Required |
| `$AC_FIREBASE_APP_PATH` | Specifies the full path of the build. For example, `$AC_EXPORT_DIR/Myapp.ipa` or `$AC_APK_PATH`. | Required |
| `$AC_FIREBASE_APP_ID` | Specifies your app's Firebase App ID. You can find the app ID in the [Firebase console](https://console.firebase.google.com/u/0/). | Required |
| `$AC_FIREBASE_TOKEN` | Specifies a refresh token that's printed when you authenticate with the `firebase login:ci` command. **Select either a Firebase token or a Google Service account**. | Optional |
| `$GOOGLE_APPLICATION_CREDENTIALS` | Specifies the path of the Google Service Account JSON. Upload the service account as a file to your environment group and name it `GOOGLE_APPLICATION_CREDENTIALS`. **Select either a Firebase token or a Google Service account**. | Optional |
| `$AC_FIREBASE_RELEASE_NOTES` | Specifies the release notes for this build. If you want to use a file for release notes, leave this field empty and configure the next section. | Optional |
| `$AC_FIREBASE_RELEASE_NOTES_PATH` | If you use the Publish Release Notes component before this step, `release-notes.txt` will be used as release notes. | Optional |
| `$AC_FIREBASE_GROUPS` | Specifies the Firebase tester groups you want to invite. | Optional |
| `$AC_FIREBASE_EXTRA_PARAMETERS` | Specifies extra command line parameters. Enter `--debug` for debug mode. | Optional |
:::info Output Variables
The **Firebase App Distribution** step generates no output variables. The step succeeds if the app is distributed successfully; otherwise, it fails.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-firebase-distribution-component
---
## Fortify on Demand Mobile Assessment
[Fortify on Demand Mobile Assessment](https://www.opentext.com/products/fortify-on-demand) provides a robust solution for securing mobile applications by identifying vulnerabilities before they can be exploited. This comprehensive cloud-based service streamlines the security testing process, ensuring your mobile apps meet the highest standards of security.
You can seamlessly integrate Fortify on Demand Mobile Assessment into your workflow with Appcircle, facilitating easy setup and utilization within your existing development processes.
### Prerequisites
Before running the **Fortify on Demand Mobile Assessment** step, you must complete certain prerequisites, as detailed in the table below:
#### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) | This step will build your application in ARM architecture and generate an `IPA` and `dSYM` file. |
#### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | The app required for this step is generated by the **Android Build** (or alternative build steps). |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If you create a signed app, you must run this step beforehand to process the output. |
#### For iOS Flutter
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) | This step will build your application in ARM architecture and generate an `IPA` and `dSYM` file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps/flutter-build-for-ios) | Generates the app required for the **Fortify on Demand** step. |
#### For Android Flutter
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps/flutter-build-for-android) | Generates the app required for the **Fortify on Demand** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | If you create a signed app, you must run this step beforehand to process the output. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|-----------------------------------------------------------------------------------------------------------|----------|
| `$AC_FOD_CLIENT_ID` | Authenticating with client credentials. The client credentials are the API keys generated in the portal. | Required |
| `$AC_FOD_CLIENT_SECRET` | Authenticating with client credentials. The client credentials are the API keys generated in the portal. | Required |
| `$AC_FOD_CLIENT_DATACENTER` | Select the datacenter assigned to you upon your onboarding with Fortify on Demand. | Required |
| `$AC_FOD_ENTITLEMENT_ID` | The ID assigned to your current entitlement. You can retrieve this value in the Fortify on Demand portal. | Required |
| `$AC_FOD_RELEASE_ID` | The ID assigned to the created release. This value can be retrieved in the Fortify on Demand portal. | Required |
| `$AC_FOD_ASSESSMENT_TYPE` | Assessment type for this mobile assessment. | Required |
| `$AC_FOD_FRAMEWORK_TYPE` | Framework type for this mobile assessment. | Required |
| `$AC_FOD_PLATFORM_TYPE` | Platform type for this mobile assessment. | Required |
| `$AC_FOD_FILE_PATH` | Full path of the `IPA` or `APK` file. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-fod-mobile-assessment
---
## FTP Upload
Appcircle's FTP Upload (File Transfer Protocol) integration lets you easily upload any file generated within the pipeline to your chosen FTP server.
### Prerequisites
There are no prerequisites required before using the **FTP Upload** step.
:::caution
This step has no prerequisites but must follow the artifact production step. For example, as the screenshot below demonstrates, use it right after the [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) step. This setup ensures the IPA file produced in the pipeline is sent to any **FTP server**.
:::
:::caution
Note that to send a file to an **FTP server**, the file must be generated within the pipeline. Therefore, deploy this step only after the file production step. Failing to do so means the **FTP Upload** step cannot find the file, resulting in an error.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| `$AC_FTP_HOST` | Hostname of the FTP server. For example: `ftp.example.com:21` | Required |
| `$AC_FTP_USER` | FTP server username. | Required |
| `$AC_FTP_PASS` | FTP server password. | Required |
| `$AC_FTP_SOURCE` | Source file or path to upload. For example: the file path can be set to `$AC_OUTPUT_DIR/Myapp.ipa`. Ensure that the file name is correct.| Required |
| `$AC_FTP_TARGET` | The target path is on the FTP server. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ftp-upload-component
---
## Git Clone
The **Git Clone** step is used to fetch the source code repository from a Git provider, such as [**GitHub**](/build/manage-the-connections/connection-guides/connecting-to-github), [**GitLab**](/build/manage-the-connections/connection-guides/connecting-to-gitlab), [**Bitbucket**](/build/manage-the-connections/connection-guides/connecting-to-bitbucket), or [**Azure DevOps**](/build/manage-the-connections/connection-guides/connecting-to-azure), and clone it into the runner where the build and deployment processes take place. This step ensures that the latest version of the codebase is available for subsequent build and deployment steps.
### Prerequisites
Before running the **Git Clone** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Activate SSH Private Key**](/workflows/common-workflow-steps/active-ssh-private-key) | This step sets up your SSH key on the build machine **if you used one to connect your repository with SSH**. |
:::caution
If you have not connected your repo via SSH, the **Git Clone** does not have any dependency on the **Activate SSH Private Key** step.
:::
:::info
We recommend using this step at the beginning of the workflow to avoid any problems in the workflow.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger
After connecting the repository, the following [**Reserved Environment Variables**](/environment-variables/appcircle-specific-environment-variables), which **Git Clone** uses as input, will be automatically populated. Ensure that the variable you provide has a value if you intend to make any changes. **The required variables must not be left empty**.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_GIT_URL` | URL of the repository. After the [**provider connection**](/build/manage-the-connections/connection-guides) is completed with the Git provider, these values will be set automatically. | Required |
| `$AC_GIT_COMMIT` | Commit of the repository. This value will come from the Git provider. When a new commit is pushed, Appcircle fetches the details of the latest commit. | Optional |
| `$AC_GIT_BRANCH` | Branch of the repository. You can find more details about [**branch management**](/build/build-process-management/build-profile-branch-operations). The branch information selected before starting manual build on the interface is automatically included here. | Optional |
| `$AC_GIT_TAG` | Tag of the repository. If you have tags in your repository, Appcircle can start a build according to the tags. | Optional |
| `$AC_GIT_LFS` | Used to specify whether large files will be downloaded. The default value is `false`. | Optional |
| `$AC_GIT_SUBMODULE` | Used to specify whether the submodule should be cloned. | Optional |
| `$AC_GIT_CACHE_CREDENTIALS` | If this variable is set to `true`, the credentials will be cached. This can be useful if the same credentials are used for multiple repositories. The default value is `true`. | Optional |
| `$AC_GIT_EXTRA_PARAMS` | If this variable is set, it sends additional parameters for Git requests. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `AC_REPOSITORY_DIR` | Specifies the root directory of the cloned repository. This path is automatically generated after the repository is cloned. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-git-clone-component
---
## FAQ
### How can I solve unexpected `Operation timed out` problem?
If there is a limiting upload limit on your Git provider, you will see an error like below in the **Git Clone** step.
```
error: RPC failed; curl 56 Recv failure: Operation timed out
error: 5237 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
```
Users utilizing a self-hosted Git provider need to grant network access to use Appcircle. Access to private repositories can be achieved by whitelisting Appcircle’s IP addresses. If the upload speed of the provider is restricted, Appcircle may take longer than expected to clone the repository.
Appcircle runners have an approximate internet speed of 10 Gbps. If your Git provider imposes a maximum upload speed limit, the **Git Clone** step in Appcircle will be restricted by this limit and **cannot** exceed it. As a result, the **Git Clone** step may take significantly longer to complete.
For detailed information, please visit our [**Accessing Repositories Within Internal Networks**](/build/manage-the-connections/accessing-repositories-in-internal-networks-firewalls) documentation.
#### How can I check source of the "unexpected disconnect" error?
When repository access is granted for self-hosted Git providers, Appcircle directly attempts to clone the repository from the provider. If the upload speed limit set for your Git provider is too low, the **Git Clone** step will take a significantly longer time. Due to the prolonged download process, the Git provider may eventually reset the connection, resulting in an unexpected disconnection. To avoid such errors during unexpectedly long **Git Clone** steps, these titles can be checked.
- Checking the upload limit defined for the Git provider.
- If Appcircle is used through a firewall, you can check the rules set for that firewall.
- If there is no problem with your firewall and Git provider speed limits, you can contact the security teams and check whether there is a problem in terms of security.
---
## Common Workflow Steps
The steps listed below are common across all build profiles regardless of the target OS and platform.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [Activate SSH Key](/workflows/common-workflow-steps/active-ssh-private-key)
This step sets up your SSH key in the build machine if you used one to connect your repository. This allows the build machine to connect to your private repository using your SSH key.
## [Add a Badge to Your App Icon](/workflows/common-workflow-steps/add-badge-app-icon)
With Appcircle's **Add Badge to Your App Icon** component, you can add badges and version information to your app icon, which you can also customize. This helps testers easily identify the version they are testing directly on the application icon.
## [Appium Server](/workflows/common-workflow-steps/appium-server)
This step installs [Appium Server](https://appium.io/) and starts it.
## [Authenticate with Netrc](/workflows/common-workflow-steps/authenticate-with-netrc)
The `.netrc` file contains login and initialization information used by the auto-login process. You can use this component to add credentials for hosts such as your repositories or external hosts. Git automatically recognizes the .netrc file. However, if you want to use the .netrc file with curl, you need to append the `-n` command line parameter. You may also use the `--netrc-optional` parameter if you don't always use the `.netrc` file with curl.
## [AWS Device Farm and Deploy](/workflows/common-workflow-steps/aws-device-farm-and-deploy)
**AWS Device Farm** is an application testing service that enables you to run your tests concurrently on multiple mobile devices to speed up the execution of your tests and generates videos and logs to help you quickly identify issues with your app.
## [Cache Push](/workflows/common-workflow-steps/build-cache/cache-push)
Learn to streamline your workflows by pushing data to cache with our easy-to-follow cache-push tutorial. Ideal for improving build performance.
## [Cache Pull](/workflows/common-workflow-steps/build-cache/cache-pull)
Discover the essentials of cache retrieval in our cache-pull guide. Speed up your build processes by mastering the art of efficiently pulling cached data.
## [Check Network Access](/workflows/common-workflow-steps/check-network-access)
This component checks network access to external services commonly used in Appcircle build workflows. It validates connectivity to package managers, build services, APIs, and custom-defined URLs during build time.
## [Custom Script](/workflows/common-workflow-steps/custom-script)
You can use **Custom Script** steps for additional functionalities in your builds. Appcircle will run the commands in your custom scripts and perform the specified actions. These scripts will be run on the runner and you can use any functionality of the build environment as you need.
## [Custom Script from Git](/workflows/common-workflow-steps/custom-script-from-git)
You can use **Custom Script from Git** to clone and run your own scripts directly from a Git repository as part of your Appcircle build. This step supports authenticated cloning (via username and PAT).
## [Code Reviews with Danger](/workflows/common-workflow-steps/danger)
**Danger** runs during your CI process and gives teams the chance to automate common code review chores. This provides another logical step in your build, through this Danger can help lint your rote tasks in daily code review. You can use Danger to codify your team’s norms. Leaving humans to think about harder problems.
https://blog.appcircle.io/article/danger-in-ci-automate-your-mobile-code-reviews
## [Data Theorem Mobile Secure](/workflows/common-workflow-steps/data-theorem-mobile-secure)
This component scans your app using Mobile Secure.
## [Export Build Artifacts](/workflows/common-workflow-steps/export-build-artifacts)
Exports the specified build artifacts from the build agent to the Appcircle dashboard. The exported files will be available for download from the artifacts section of the completed build.
## [Fastlane](/workflows/common-workflow-steps/fastlane)
Appcircle supports **Fastlane** for build automation as a supplementary feature to Appcircle's own build automation.
With Appcircle, you can automate your build and signing processes with the flexible workflow structure, and you can also use Fastlane as a workflow step within the build workflows.
## [File Size Check](/workflows/common-workflow-steps/file-size-check)
This component checks the file size and either warn or fail the workflow.
## [Firebase App Distribution](/workflows/common-workflow-steps/firebase-app-distribution)
Send your apps to be distributed via Firebase App Distribution.
https://github.com/appcircleio/appcircle-firebase-dsym-upload-component
## [Fortify On Demand](/workflows/common-workflow-steps/fod-mobile-assesment)
This step installs [Fortify on Demand](https://www.microfocus.com/en-us/cyberres/application-security/fortify-on-demand/) and submits a Fortify on Demand Mobile Assessment.
## [FTP Upload](/workflows/common-workflow-steps/ftp-upload)
This component uploads file or folders to given FTP server.
## [Git Clone](/workflows/common-workflow-steps/git-clone)
Clones the Git repository to the build agent with the given arguments.
## [KOBIL Appshield Scanner for Android/iOS](/workflows/common-workflow-steps/kobil-appshield-scanner)
KOBIL Appshield Scanner performs dynamic runtime scans/analysis and AI supported static (file-based) inspections for mobile app files (APK, AAB, IPA) to detect existing security mechanisms and indicates whether an app is secure or not.
## [Maestro Cloud Upload](/workflows/common-workflow-steps/maestro-cloud-upload)
This component uploads both your app binary and flows to Maestro Cloud.
## [Repeato Mobile Test Automation](/workflows/common-workflow-steps/repeato-test-runner)
This component creates and automates UI tests for iOS and Android.
## [Release Notes](/workflows/common-workflow-steps/publish-release-notes)
You can use **Release Notes** component to create release notes during your workflow.
## [Repeato Test Runner](/workflows/common-workflow-steps/repeato-test-runner)
**Repeato** is a test automation platform designed for mobile applications. It enables developers to create, manage, and execute automated tests for mobile apps across different platforms and devices. Repeato supports various testing frameworks and provides features for test script creation, test execution, result analysis, and reporting. It helps streamline the testing process, improve test coverage, and enhance the overall quality of mobile applications.
## [Saucectl Run](/workflows/common-workflow-steps/saucectl-run)
The `saucectl` command line interface orchestrates the relationship between your tests in your framework, and the rich parallelization, test history filtering, and analytics of Sauce Labs. saucectl performs the underlying business logic to access the tests in your existing framework, runs them in the Sauce Labs Cloud, then securely transmits the test assets to the Sauce Labs platform, where you can review, share, and evaluate your test outcomes at scale.
## [Select Java Version](/workflows/common-workflow-steps/select-java-version)
The **Select Java Version** step updates the JDK and Java version to the selected one during the build process.
## [Set Environment Variable](/workflows/common-workflow-steps/set-environment-variable)
The **Set Environment Variable** step enables the setting of environment values for specified keys. Although creating environment variables via the Environment Variables page is typically recommended, this step provides flexibility to modify environment variables directly within the build workflow when necessary.
## [Snyk Scan Security](/workflows/common-workflow-steps/snyk-scan-security)
By utilizing this step, you will be able to test your project dependencies for vulnerabilities during builds and use **Snyk** to monitor your projects.
## [SonarQube](/workflows/common-workflow-steps/sonarqube)
You can use **SonarQube** component to check your code quality.
## [Testinium Upload App](/workflows/common-workflow-steps/testinium-steps/testinium-upload-app)
The **Testinium Upload App** step uploads mobile apps from Appcircle to Testinium, supporting both cloud and enterprise environments.
## [Testinium Run Test Plan](/workflows/common-workflow-steps/testinium-steps/testinium-run-test-plan)
The **Testinium Run Test Plan** step allows you to run automated tests on your mobile applications directly from Appcircle, whether using Testinium cloud or enterprise setup.
## [Testinium](/workflows/common-workflow-steps/testinium-steps/testinium)
The **Testinium** step allows users to upload their mobile applications to **Testinium** and run a test plan for Testinium cloud users.
## [Upload Files to Amazon S3](/workflows/common-workflow-steps/upload-files-to-amazon-s3)
The **Upload Files to Amazon S3** step in Appcircle enables direct uploading of any file or folder to the designated Amazon S3 bucket during the build process.
---
## Jira Comment
Jira is a software development tool used for issue tracking, project management, and agile software development. It allows users to plan, track, and release software projects. Jira's core functionality includes the ability to create and assign tasks, track progress and status, and collaborate with team members.
By adding Appcircle's [**Jira Comment**](https://github.com/appcircleio/appcircle-jira-component/) component to your workflow, you can add comments or change their status according to your workflow.
## Prerequisites
There are no prerequisites required before using the **Jira Comment** step.
:::caution
Please note that once the **Jira Comment** has run successfully, the status of the relevant article in your Jira account will be changed. If the build fails in Appcircle, an incorrect status may appear in your Jira account. Make sure you use it in the correct order in Workflow.
:::
:::danger
To ensure that the **Jira Comment** step runs even if your workflow fails, please enable the `Always run this step even if the previous steps fail` switch.
:::
## Configuration of Jira Comment
To add a comment, the issue ID must be supplied to the component. We need to get this issue ID dynamically so that our workflow can work for multiple branches. Appcircle components use environment variables to pass the state. We can add a step just before the **Jira Comment** to prepare the necessary environment variables.
For example, you're working on a feature branch called `feature/jiraissue-1`. You may use the below Ruby script to get `jiraissue-1` from the branch name and use this information with the **Jira Comment**. Please see the [**Custom Script documentation**](/workflows/common-workflow-steps/custom-script) for this implementation.
```ruby
branch = ENV['AC_GIT_BRANCH']
feature_name = branch.split('/')[1].upcase
puts feature_name
# Write Environment Variable
open(ENV['AC_ENV_FILE_PATH'], 'a') { |f|
f.puts "AC_JIRA_ISSUE=#{feature_name}"
}
```
### Jira REST API Version Reference
**Jira Comment** input types depend on the [Jira REST API version](https://developer.atlassian.com/server/jira/platform/rest-apis/#uri-structure). Therefore, you can select the appropriate Jira REST API version from the component version selection list. Here's how:
- For [Jira REST API version 2](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#version): This version can be used by both Jira On-Prem and Jira Cloud users. Choose `2.*.*` from the selection list.
- For [Jira REST API version 3](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#version): This version can only be used by Jira Cloud users. Choose `3.*.*` from the selection list.
### Changing Template
Appcircle provides a default template that adds commit id, branch name, time in UTC, and a couple of environment variables. The structure of the Jira comment template depends on the version of the Jira REST API you're utilizing.
If you're utilizing [API version 2](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-post), commenting is limited to string type only. On the other hand, for [Jira API version 3](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-post), you have the flexibility to send comments in any format using the Atlassian Document Format (ADF). To create custom comments for version 3, you can leverage tools like the [ADF Builder](https://developer.atlassian.com/cloud/jira/platform/apis/document/playground/).
## Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
:::info
The required inputs for authorization vary based on the type of Jira instance (On-Prem or Cloud). Below is a summary of the required inputs:
**For [Jira On-Prem](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html) Users:**
- `AC_JIRA_EMAIL`: Not required
- `AC_JIRA_TOKEN`: Not required
- `AC_JIRA_PAT`: Required
**For [Jira Cloud](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) Users:**
- `AC_JIRA_EMAIL`: Required
- `AC_JIRA_TOKEN`: Required
- `AC_JIRA_PAT`: Not required
:::
| Variable Name | Description | Status |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_JIRA_HOST` | Your Jira subdomain. For example: `mysubdomain.atlassian.net` | Required |
| `$AC_JIRA_EMAIL` | The email associated with your Jira account. This field is required for using API tokens instead of PAT. | Optional |
| `$AC_JIRA_TOKEN` | User's API Token. If this value is fill, the Jira e-mail field must be filled. Only Jira Cloud users can use API Token. You can create token from [here](https://id.atlassian.com/manage-profile/security/api-tokens) | Optional |
| `$AC_JIRA_PAT` | Specify the Personal Access Token for Jira authentication. Only Jira On-Prem users can use PAT. | Optional |
| `$AC_JIRA_ISSUE` | The ID or key of the issue. Refer to this [header](/workflows/common-workflow-steps/jira-comment#configuration-of-jira-comment) for instructions on extracting this information from branch names or commit messages. | Required |
| `$AC_JIRA_FAIL_TRANSITION` | Transition ID or name for the failed step. Optionally change the status of your issue if the previous state fails. Ensure that the `Always run this step even if the previous steps fail` switch is enabled for this feature to work. | Optional |
| `$AC_JIRA_SUCCESS_TRANSITION` | Transition ID or name for the successful step. Optionally change the status of your issue if the previous state succeeds. | Optional |
| `$AC_JIRA_TEMPLATE_V2` | The comment template used to post a comment if [Jira REST API Version 2](#jira-rest-api-version-reference) is selected. Variables prefixed with `$` will be replaced during the build process. Refer to [this header](#changing-template) to modify the template. | Required |
| `$AC_JIRA_TEMPLATE_V3` | The comment template used to post a comment if [Jira REST API Version 3](#jira-rest-api-version-reference) is selected. Variables prefixed with `$` will be replaced during the build process. Refer to [this header](#changing-template) to modify the template. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-jira-component
---
## KOBIL Appshield Scanner
# KOBIL Appshield Scanner for Android/iOS
KOBIL Appshield Scanner starts its analysis by accepting the application file (AAB/APK for Android, IPA for iOS) and performs dynamic runtime tests after initial file and format validations.
It is important to note that while many scanning solutions use ARM/x86_64 based emulators and sandbox environments, Appshield performs all these dynamic tests on **real/physical Android and/or iOS devices.**
At the end of the dynamic test session, Appshield indicates which security measures/hardenings are present and implemented in the app. If some test cases were to fail due to unforeseen errors or cannot be tested due to various bypass mechanisms implemented by the app itself, Appshield then starts a static, AI-powered analysis for the mentioned test cases to gather additional findings and then reaches a final verdict.
### Prerequisites
For Android, APK or AAB format (signed) and for iOS, IPA format (signed) is required for **KOBIL Appshield Scanner**.
Before running the **KOBIL Appshield Scanner** step, here are some example steps/flows to obtain a signed AAB/APK/IPA file, illustrated below:
#### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | Generates the app required (APK or AAB) for the **KOBIL Appshield Scanner** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | Required for signing the app (APK or AAB). If app is already signed, this step can be skipped. |
#### For Android Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps#flutter-build-for-android) | Generates the app required (APK or AAB) for the **KOBIL Appshield Scanner** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | Required for signing the app (APK or AAB). If app is already signed, this step can be skipped. |
#### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
#### For iOS Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps#flutter-build-for-ios) | Prepares the Flutter project for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter). |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ---------------------------------------------------------------------------------------------------- | -------- |
| `AC_APPSHIELD_APP_FILE_PATH` | Path to the AAB/APK/IPA file for KOBIL Appshield Scanner to test. | Required |
| `AC_APPSHIELD_API_KEY` | User API key for starting a test session. If not provided, default value from Appcircle can also be used by the component. | Required |
| `AC_APPSHIELD_USER_MAIL` | Specifies the user e-mail if user wants to receive a detailed PDF report regarding the analysis. | Optional |
| `AC_APPSHIELD_UPLOAD_TIMEOUT` | File upload timeout in seconds. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AC_APPSHIELD_IS_APP_SECURE` | Boolean variable indicating whether the app is properly hardened and contains the security/defense mechanisms. "true" indicates app is secure, "false" indicates app is not completely secure (has missing security measures), and "null" indicates the testing has failed for some internal reason. | |
:::warning
When the app is not secure, this step fails and breaks the pipeline.
To prevent pipeline interruption, enable "[Continue with the next step even if this step fails](/build/build-process-management/build-workflows#editing-workflow-steps)" toggle.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-kobil-appshield-scanner.git
## FAQ
### What is KOBIL Appshield Scanner?
KOBIL Appshield Scanner is a mobile application security analysis tool for Android and iOS apps. It evaluates application security by combining dynamic runtime testing on real, physical devices with AI-supported static (file-based) analysis to determine whether an app is properly protected against common runtime attacks and tampering techniques.
### What is KOBIL Appshield Scanner used for?
KOBIL Appshield Scanner is used to verify the presence and effectiveness of mobile app security hardening mechanisms. It helps development and security teams understand whether their Android or iOS applications are protected against threats such as debugging, hooking, code injection, screen capture, and device compromise (root or jailbreak).
### What types of mobile apps can KOBIL Appshield Scanner analyze?
KOBIL Appshield Scanner supports Android and iOS mobile applications. It accepts AAB or APK files for Android and IPA files for iOS, performing both dynamic runtime testing and static analysis to evaluate the app’s overall security posture.
### How is Appshield Scanner different from emulator-based security scanners?
Unlike many security scanners that rely on ARM or x86_64 emulators and sandbox environments, KOBIL Appshield Scanner performs dynamic runtime tests on real, physical Android and iOS devices. This approach allows more accurate detection of security mechanisms and reduces false positives or missed findings caused by emulator detection or bypass techniques.
### What security protections does Appshield Scanner check for?
Appshield Scanner detects a wide range of mobile app security measures, including (but not limited to):
- Root and jailbreak detection
- Anti-debugging mechanisms
- Frida and anti-hooking protections
- Anti code injection defenses
- Screenshot and screen recording detection
- Screen mirroring detection
- Keylogger detection
- Tapjacking protection
### What happens if some dynamic tests fail or cannot be executed?
If certain dynamic test cases fail due to unexpected runtime issues or because the app actively blocks analysis, Appshield Scanner automatically performs a static, AI-powered analysis for those specific test cases. The findings from both dynamic and static analysis are then combined to produce a final security verdict.
### How can I tell if my app is considered secure after the scan?
After the scan completes, Appshield Scanner provides the output variable `AC_APPSHIELD_IS_APP_SECURE`:
- `true` indicates the app is properly hardened and contains the required security mechanisms
- `false` indicates some security measures are missing
- `null` indicates the scan failed due to an internal or unexpected issue
---
## Maestro Cloud Upload
[Maestro Cloud](https://cloud.mobile.dev) is a cloud-based mobile device farm for testing and debugging mobile applications, offering developers and QA teams access to a wide range of real devices for comprehensive testing across various platforms, operating systems, and device configurations.
The Appcircle **Maestro Cloud Upload** step enables users to upload their mobile applications directly to Maestro, a cloud-based mobile device farm for testing and debugging applications. This integration simplifies the process of distributing apps for testing purposes across various devices and platforms supported by Maestro. Users can configure this step within their CI/CD workflows to deploy their apps to Maestro's cloud infrastructure, facilitating efficient and comprehensive testing procedures.
## Prerequisites
Before running the **Maestro Cloud Upload** step, you must complete certain prerequisites, as detailed in the table below:
### For All Platforms
| Prerequisite Workflow Step | Description |
| -------------------------- | --------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/#git-clone) | Fetches the repository to be built from the specified branch, ensuring that the [Maestro CLI](https://maestro.mobile.dev/getting-started/installing-maestro) can run on the repository path. |
### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | Generates the app required for the **Maestro Cloud Upload** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | This step is required for signing the app. It processes the output for signing but can be skipped if the app is already signed. |
### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
### For Android Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps#flutter-build-for-android) | Generates the app required for the **Maestro Cloud Upload** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | This step is required for signing the app. It processes the output for signing but can be skipped if the app is already signed. |
### For iOS Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps#flutter-build-for-ios) | Prepares the Flutter project for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter). |
## Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|---------------------------------------------------------------------------------------------------------|-----------|
| `$AC_MAESTRO_API_KEY` | The API key is required for accessing Maestro Cloud services. | Required |
| `$AC_MAESTRO_APP_FILE` | **Android**: Specify the path to an x86 compatible APK file. **iOS**: Provide a zip archive containing an x86 compatible simulator build. | Required |
| `$AC_MAESTRO_WORKSPACE` | Specifies the directory or file path where Maestro flows are located. By default, it looks for a `.maestro` folder in the project root. Override with a workspace argument if needed. | Required |
| `$AC_MAESTRO_UPLOAD_NAME` | Specifies the custom name for the upload. | Optional |
| `$AC_MAESTRO_ASYNC` | Toggle to enable asynchronous mode for running flows. | Optional |
| `$AC_MAESTRO_ENV` | Pass environment variables to the flows. Separate variables using a new line, or `\n`. | Optional |
| `$AC_MAESTRO_ANDROID_API_LEVEL` | Set the Android API level for devices to run. The default value is `30`. | Optional |
| `$AC_MAESTRO_INCLUDE_TAGS` | Run only flows containing the specified tags (comma-separated). | Optional |
| `$AC_MAESTRO_EXCLUDE_TAGS` | Exclude flows with the specified tags (comma-separated). | Optional |
| `$AC_MAESTRO_EXPORT_TEST_REPORT` | Toggle to export the test suite report (JUnit). | Optional |
| `$AC_MAESTRO_EXPORT_OUTPUT` | Specify the output file for the test file output. The default is `report.xml`. | Optional |
| `$AC_MAESTRO_MAPPING_FILE` | **Android**: Include the Proguard mapping file. **iOS**: Include the generated .dSYM file. | Optional |
| `$AC_MAESTRO_BRANCH` | The branch from which the upload originated. | Optional |
| `$AC_MAESTRO_REPO_NAME` | The name of the repository (e.g., GitHub repo slug). | Optional |
| `$AC_MAESTRO_REPO_OWNER` | The owner of the repository (e.g., GitHub organization or user slug). | Optional |
| `$AC_MAESTRO_PULL_ID` | The ID of the pull request from which the upload originated. | Optional |
| `$AC_MAESTRO_CLI_VERSION` | The version of the Maestro CLI is to be downloaded in your CI environment. The default value is the `latest` version. | Optional |
:::info Output Variables
The **Maestro Cloud Upload** step generates no output variables. The results are shown in the build log.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-maestro-cloud-upload-component.git
---
## Marathon Cloud
[**MarathonLabs**](https://marathonlabs.io) provides infinite virtual devices and will automatically shard, sort, distribute, and retry your tests, allowing all tests to be completed. We recommend you refer to the [**Marathon Cloud documentation**](https://docs.marathonlabs.io/intro/overview) for the details of the platform.
The **Marathon Cloud** component is an integrated test automation workflow step for the Appcircle pipeline. You can easily include it in your workflow on Appcircle with the necessary parameters and run your UI tests.
### Prerequisites
Before running the **Marathon Cloud** step, you must complete certain prerequisites, as detailed in the table below:
:::caution
Please note that this component works separately on both the native **Android** and **iOS** platforms. The requirements for both platforms are different.
:::
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) | After the Xcodebuild for Testing step runs, the test IPA paths `$AC_TEST_IPA_PATH` and `$AC_UITESTS_RUNNER_PATH` will be created automatically. So that the **Marathon Cloud** component depends on these paths. |
| [**Android Build for UI Testing**](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) | Once the Android Build for UI Testing step is completed, the test APK paths `$AC_APK_PATH` and `$AC_TEST_APK_PATH` are automatically generated. The **Marathon Cloud** component relies on these paths. |
:::danger
When using this component for the **iOS platform**, do not forget to change the **`Destination`** value in the **Xcodebuild for Testing** step. This value will be `generic/platform=iOS` by default. This means that it creates a generic test `IPA` for all iOS devices. Since the Marathon Cloud component runs on a specific test device, you need to change this value. For example, `platform=iOS Simulator,name=iPhone 15 Pro,OS=17.2`.
Please note that if you do not change this parameter, the Marathon Cloud component will fail and the pipeline will break. For further information, please follow the [**Xcodebuild for Testing documentation**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing).
:::
#### For Android
#### For iOS
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_MARATHON_API_KEY` | Marathon Cloud API key. To get an API key, please follow the Marathon Cloud [**documentation**](https://docs.marathonlabs.io/?_gl=1*fsz3tj*_ga*MTYyMzE3NDMwOC4xNzA2Njk3MzA5*_ga_7RE7PPY2QW*MTcxMTAwMzEyNC4yNS4xLjE3MTEwMDU5ODYuMjQuMC4w*_gcl_au*MjA1NTI4NzUyNC4xNzA2Njk3MzUw#api-key). | Required |
| `$AC_MARATHON_TEST_NAME` | This name will be shown on the Marathon Cloud dashboard test run list. | Required |
| `$AC_MARATHON_APP_PATH` | Specify the path to the application binary. This application is generated by the corresponding testing step (**Android Build for UI Testing** or **Xcodebuild for Testing**). The default value is `$AC_APK_PATH ` for Android or `$AC_TEST_IPA_PATH` for iOS. | Required |
| `$AC_MARATHON_UITEST_RUNNER_APP_PATH` | Specifies the path to the test application binary. This application is generated by the corresponding testing step (**Android Build for UI Testing** or **Xcodebuild for Testing**). The default value is `$AC_TEST_APK_PATH ` for Android or `$AC_UITESTS_RUNNER_PATH` for iOS. | Required |
| `$AC_OUTPUT_DIR` | Specifies the path for Marathon Cloud outputs. This path will be automatically defined. Do not change if it is not necessary. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-marathonlabs-component
---
## Publish Release Notes
You can use the **Publish Release Notes** step to generate release notes during your workflow. These release notes can be enriched with environment variables or Ruby snippets, and you also have the option to include your own release notes file by specifying its path. This component generates a `release-notes.txt` file with the provided options and copies it to the `$AC_OUTPUT_DIR` path. The generated release notes will be utilized in the following areas:
- Distribution Portals (such as [Appcircle Testing Distribution](/testing-distribution) or [Firebase App Distribution](/workflows/common-workflow-steps/firebase-app-distribution) step)
- [Enterprise App Store](/enterprise-app-store)
- Publishing (to [Google Play](/publish-integrations/android-publish-integrations/publish-to-google-play) or Approval Email steps)
:::caution
Appcircle currently does not publish release notes to TestFlight, as TestFlight does not allow uploading a changelog with the binary. You can only upload the "what to test" section **AFTER** the binary is processed, which may take several hours.
:::
### Prerequisites
There are no prerequisites required before using the **Publish Release Notes** step.
:::danger
To create rich release notes, the Release Notes component should be included in your workflow. It is recommended to place it just before the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step so that you can have access to all build artifacts, such as git commit messages, test results, or build logs.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_RELEASE_NOTES_PATH` | Specifies the path of the release notes. You can override the `$AC_RELEASE_NOTES_PATH` environment variable or provide its full path, e.g., `./release-notes.txt`. If the path is empty, release notes will be auto-generated. | Optional |
| `$AC_RELEASE_NOTES_TEMPLATE` | This variable is an ERB template. You can enrich the contents of your release notes with environment variables or Ruby snippets. | Optional |
### Output Variables
This step creates the `release-notes.txt` file. It does not keep this file in a variable, but you can access this file via [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts).
:::danger
Don't forget to use the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step to access the release notes output and distribute it after the build.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-release-notes-component
---
## Repeato Test Runner
[Repeato](https://www.repeato.app) is a test automation platform designed for mobile applications. It enables developers to create, manage, and execute automated tests for mobile apps across different platforms and devices. Repeato supports various testing frameworks and provides features for test script creation, test execution, result analysis, and reporting. It helps streamline the testing process, improve test coverage, and enhance the overall quality of mobile applications.
The **Repeato Test Runner** integrates as a service within the Appcircle CI/CD workflow, streamlining the execution of automated tests directly within Appcircle. This service enables developers to validate the functionality and performance of their mobile applications before deployment, ensuring releases of high quality.
For more information, please check out this blog post:
https://appcircle.io/blog/streamline-project-integration-and-test-automation-with-repeato-and-appcircle
### Prerequisites
Before running the **Repeato Test Runner** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/#git-clone) | The repository that needs to be built must be fetched from the branch. Upon completion of the **Git Clone** step, it generates the `$AC_REPOSITORY_DIR` variable, which is then used as the input for the Android Build step. |
:::danger
If you wish to view the test results on Appcircle's Test Reports page, it is essential to use the [Test Reports](https://github.com/appcircleio/appcircle-test-report-component) step after the **Repeato Test Runner**. Please check out this document for more information: [Generating Test Report](/continuous-testing/android-testing/running-android-unit-tests#generating-test-report)
:::
### Input Variables
Specific input variables are required for the **Repeato Test Runner** to function correctly:
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_REPEATO_CLI_VER` | Specifies the Repeato CLI version compatible with your workspace tests. | Optional |
| `$AC_REPEATO_WORKSPACE_DIR` | The workspace path is required by the Repeato test runner to set up the workspace before executing the batch. Example: `./mypath`. | Required |
| `$AC_REPEATO_BATCH_ID` | Provides the batch ID for test execution. For more details, please refer to [this document](https://www.repeato.app/documentation/continuous-integration/#appcircle). | Required |
| `$AC_REPEATO_LIC_KEY` | Provides a license key for test execution. | Required |
| `$AC_REPEATO_LOG_LEVEL` | Switch to `DEBUG` if you encounter issues while running your batches. This prints additional information to the log. Options: `INFO`, `DEBUG`, `WARN`. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------- | -------------------------------------------------------- |
| `AC_REPEATO_REPORT` | Report of Repeato batches that have been executed. |
| `AC_REPEATO_JUNIT_REPORT` | Report of Repeato executed tests in JUnit XML format. |
| `AC_TEST_RESULT_PATH` | The directory where your JUnit XML report will be saved. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-repeato-component
---
## Saucectl Run
> The `saucectl` command line interface orchestrates the relationship between your tests in your framework, and the rich parallelization, test history filtering, and analytics of Sauce Labs. `saucectl` performs the underlying business logic to access the tests in your existing framework, runs them in the Sauce Labs Cloud, then securely transmits the test assets to the Sauce Labs platform, where you can review, share, and evaluate your test outcomes at scale.
For more information, please visit the [Saucectl documentation](https://docs.saucelabs.com/dev/cli/saucectl/). This document will guide you on how to use the `saucectl` command and [Sauce Labs](https://docs.saucelabs.com/sauce-basics/) through Appcircle.
### Prerequisites
Below are the workflow steps required before running the **Saucectl** step, listed with their reasons. Prerequisites vary by platform:
#### For Android
| Prerequisite Workflow Step | Description |
| --------------------------- | ----------------------------------------------------------------------------- |
| [Android Build for UI Testing](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) | This step generates the required Android test application outputs needed for testing on Sauce Labs. |
#### For iOS
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps#xcodebuild-for-testing) | After the [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps#xcodebuild-for-testing) step runs, the test IPA and APP paths (`$AC_TEST_IPA_PATH` and `$AC_TEST_APP_PATH`) will be created automatically. So that the **Saucectl Run** component depends on these paths. |
:::info
For this step to work, ensure that a `config.yml` file is available. You can set this file as an environment variable in Appcircle or include it directly in your repository.
Here’s a sample `config.yml` file for [Espresso](https://docs.saucelabs.com/mobile-apps/automated-testing/espresso-xcuitest/espresso/):
```yml title="/.sauce/config.yml"
apiVersion: v1alpha
kind: espresso
defaults: {}
showConsoleLog: false
sauce:
region: eu-central-1
concurrency: 2
espresso:
app: $AC_APK_PATH
testApp: $AC_TEST_APK_PATH
suites:
- name: espresso - Google Pixel .* - Android GoogleAPI Emulator
devices:
- name: Google Pixel .*
emulators:
- name: Android GoogleAPI Emulator
platformVersions:
- "12.0"
artifacts:
download:
match:
- '*'
when: always
directory: artifacts
```
And sample `config.yml` file for [Xcuitest](https://docs.saucelabs.com/mobile-apps/automated-testing/espresso-xcuitest/xcuitest/):
```yml title="/.sauce/config.yml"
apiVersion: v1alpha
kind: xcuitest
sauce:
region: us-west-1
concurrency: 3
metadata:
tags:
- e2e
- release team
- other tag
build: Release $CI_COMMIT_SHORT_SHA
xcuitest:
app: $APP
testApp: $TEST_APP
suites:
- name: "saucy xcuitest"
devices:
- name: "iPhone.*"
options:
carrierConnectivity: false
deviceType: ANY
private: false
artifacts:
download:
when: always
match:
- "junit.xml"
directory: ./artifacts/
reporters:
spotlight:
enabled: true
```
:::
### Input Variables
For each component, specific input variables are required for its operation on your system. The input variables necessary for the **Saucectl Run for Android** are as follows:
| Variable Name | Description | Status |
|---------------------------|------------------------------------------------------------------------------------------------------------------|----------|
| AC_SL_CONFIG_PATH | Path to the Sauce Labs configuration file. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--config) documentation for the option details. Default value is `.sauce/config.yml`. | Required |
| AC_SL_USERNAME | Sauce Labs username. It must be set as a secret environment variable. | Required |
| AC_SL_ACCESS_KEY | Sauce Labs access key. It must be set as a secret environment variable. | Required |
| AC_RUN_ONLY_VIA_CONFIG | Whether to run only using the configuration file. If set to `true`, no need to fill in the other options. Default is `false`. Options: `true, false`. | Required |
| AC_SL_SELECT_SUITE | Specifies a test suite to execute by name rather than all suites defined in the config file. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--select-suite) documentation for details. Default value is `$AC_SL_SELECT_SUITE`. | Optional |
| AC_SL_APP_PATH | Path to the main application file that will be tested. This should be the location of the app (APK for Android or IPA for iOS) within the Sauce Labs environment or your build process. If not provided, app will be used as default in `config.yml`. If set to `AC_APK_PATH`, [Android Build for UI Testing](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) step output will be loaded automatically. Or if set to `AC_TEST_APP_PATH` for iOS, [Xcodebuild for Testing](/workflows/ios-specific-workflow-steps#xcodebuild-for-testing) step output will be loaded automatically. | Optional |
| AC_SL_TEST_APP_PATH | Path to the test application file, which contains the test code to be run against the main app. This is usually a separate test APK for Android or an additional test bundle for iOS. If not provided, app will be used as default in `config.yml`. If set to `AC_TEST_APK_PATH`, [Android Build for UI Testing](/workflows/android-specific-workflow-steps/android-build-for-ui-testing) step output will be loaded automatically. Or if set to `AC_TEST_IPA_PATH` for iOS, [Xcodebuild for Testing](/workflows/ios-specific-workflow-steps#xcodebuild-for-testing) step output will be loaded automatically. | Optional |
| AC_SL_ARTIFACT_CLEANUP | Clear the artifacts directory before downloading new test data. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--artifactscleanup) documentation for details. Default is `false`. Options: `true, false`. | Optional |
| AC_SL_DOWNLOAD_DIR | Specifies the path to the folder location in which to download artifacts. A separate subdirectory is generated in this location for each suite for which artifacts are downloaded. Must be set in conjunction with `Sauce Labs Download Match` and `Sauce Labs When to Download Artifacts`. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--artifactsdownloaddirectory) documentation for details. Default value is `$AC_SL_DOWNLOAD_DIR`. | Optional |
| AC_SL_DOWNLOAD_MATCH | Specifies which artifacts to download based on whether they match the name or file type pattern provided. Supports the wildcard character *. Must be set in conjunction with `Sauce Labs Download Directory` and `Sauce Labs When to Download Artifacts`. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--artifactsdownloadwhen) documentation for details. Default value is `$AC_SL_DOWNLOAD_MATCH`. | Optional |
| AC_SL_WHEN_ARTIFACT_DOWNLOAD | Criteria for downloading assets. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--artifactsdownloadwhen) documentation for details. Default is `never`. Options: `always, never, pass, fail`. | Optional |
| AC_SL_ASYNC | Launch tests without waiting for preceding test results. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--async) documentation for details. Default is `false`. Options: `true, false`. | Optional |
| AC_SL_BUILD | Associates the tests with a build to support easy filtering of related test results in the Sauce Labs UI. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--build) documentation for details. Default value is `$AC_SL_BUILD`. | Optional |
| AC_SL_CCY | Maximum tests to run concurrently. If the config defines more suites than the max, excess suites are queued and run in order as each suite completes. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--ccy) documentation for details. Default value is `$AC_SL_CCY`. | Optional |
| AC_SL_ENV | An environment variable key value pair that may be referenced in the tests executed by this command. Expanded environment variables are supported. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--env) documentation for details. Default value is `$AC_SL_ENV`. | Optional |
| AC_SL_FAIL_FAST | Stop suite execution after the first failure. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--fail-fast) documentation for details. Default is `false`. Options: `true, false`. | Optional |
| AC_SL_REGION | Specifies the Sauce Labs data center through which tests will run. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--region) documentation for details. Default is `eu-central-1`. Options: `us-west-1, us-east-4, eu-central-1`. | Required |
| AC_SL_RETRIES | Number of times to rerun a failed test suite. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--retries) documentation for details. Default value is `1`. | Optional |
| AC_SL_ROOT_DIR | Specifies the project directory. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--root-dir) documentation for details. Default value is `$AC_REPOSITORY_DIR`. | Optional |
| AC_SL_SAUCEIGNORE | Specifies the path to the `.sauceignore` file. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--sauceignore) documentation for details. Default value is `$AC_SL_SAUCEIGNORE`. | Optional |
| AC_SL_SHOW_CONSOLE_LOG | Include the `console.log` contents in the output for all tests. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--show-console-log) documentation for details. Default is `true`. Options: `true, false`. | Optional |
| AC_SL_TAGS | Keywords that may help you distinguish the test in Sauce Labs, and also help you apply filters to easily isolate tests based on metrics that are meaningful to you. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--tags) documentation for details. Default value is `$AC_SL_TAGS`. | Optional |
| AC_SL_TIMEOUT | Global timeout that limits how long saucectl can run in total. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--timeout) documentation for details. Default is `10m`. | Optional |
| AC_SL_TUNNEL_NAME | Use a running Sauce Connect tunnel to test. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--tunnel-name) documentation for details. Default value is `$AC_SL_TUNNEL_NAME`. | Optional |
| AC_SL_TUNNEL_OWNER | The tunnel owner, if it is not the testing account. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--tunnel-owner) documentation for details. Default value is `$AC_SL_TUNNEL_OWNER`. | Optional |
| AC_SL_TUNNEL_TIMEOUT | How long to wait for the specified tunnel to be ready. Check [saucectl](https://docs.saucelabs.com/dev/cli/saucectl/run/#--tunnel-timeout) documentation for details. Default value is `$AC_SL_TUNNEL_TIMEOUT`. | Optional |
### Output Variables
The artifacts generated from the **Saucectl Run** step are saved in the directory specified by **Sauce Labs Download Directory** (`AC_SL_DOWNLOAD_DIR`). You can control the format of these outputs using the **Sauce Labs Download Match** (`AC_SL_DOWNLOAD_MATCH`) parameter and determine when they are downloaded using the **Sauce Labs When to Download Artifacts** (`AC_SL_WHEN_ARTIFACT_DOWNLOAD`) parameter.
To access all saved artifacts, go to the [Download Artifacts](/build/build-process-management/binary-actions#download-artifacts) section in Appcircle at the end of the build log.
---
## Select Java Version
The **Select Java Version** step updates the JDK and Java version to the selected one during the build process.
If your project requires a different JDK or Java version than the default in your runner, you can use this step to switch to the selected version. To check the default Java version used in Appcircle, refer to this document:
- [Android Build Stacks - Java Version](/infrastructure/android-build-infrastructure#java-version)
Note that available Java versions may vary based on the runner you are using.
For self-hosted users, the versions listed for the cloud Appcircle runner may not apply. Refer to the FAQ below for guidance:
- [How do I check available Java versions in the Appcircle runner?](#how-do-i-check-available-java-versions-in-the-appcircle-runner)
:::tip Check Java Version for Android
If you are unsure which Java version is required for your Android project, you can find it by following the steps in this FAQ:
- [How can I check the Java version of my Android project?](#how-can-i-check-the-java-version-of-my-android-project)
:::
## Prerequisites
There are no prerequisites required before using the **Select Java Version** step.
:::caution
If you have a step that necessitates changing the Java version (e.g., the [**Android Build**](/workflows/android-specific-workflow-steps/android-build) step), the **Select Java Version** step should run before that step in the [workflow](/workflows).
:::
For reference, you can see the workflow sequence in the image below:
:::caution
If your runner is self-hosted, ensure that the selected Java version is available in your environment. If not, you must install the required version before the **Select Java Version** step.
:::
## Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_SELECTED_JAVA_VERSION` | Specify the Java version to switch to. The default value is `17`. Options: `8`, `11`, `17`, and `21`. | Required |
:::info
If the selected Java version is not available on the runner, an error message will indicate that `this version is not found` and will display the available Java versions for your runner. Beforehand, check available Java versions for cloud runner [here](/infrastructure/android-build-infrastructure#java-version).
:::
## Output Variables
This step does not produce any visible output. However, if run successfully, it will update both the default Java version (`$JAVA_HOME`) and the system JDK version to the selected version.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-select-java-version-component
---
## FAQ
### How do I check available Java versions in the Appcircle runner?
To view the Java versions available in the Appcircle runner, you can run the following [Custom Script](/workflows/common-workflow-steps/custom-script) in your workflow:
```bash
echo "Default Java version:" $JAVA_HOME
echo "OpenJDK 8:" $JAVA_HOME_8_X64
echo "OpenJDK 11:" $JAVA_HOME_11_X64
echo "OpenJDK 17:" $JAVA_HOME_17_X64
echo "OpenJDK 21:" $JAVA_HOME_21_X64
```
Any variables that output non-empty values indicate the available Java versions in your runner.
### How can I check the Java version of my Android project?
You can determine the required SDK version by looking at the `compileSdk` field in your `build.gradle` file under the **module** used in your Android project. The table below lists the Java versions corresponding to these SDK versions:
| Android | Java |
| ------------- | -------- |
| 14 (API 34) | 17 |
| 13 (API 33) | 11 |
| 12 (API 32) | 11 |
| 11 and lower | .. |
The Java version for API level 11 and lower is not specified in the Android document. For more details, please refer to the Android documentation linked below:
- [Which Java APIs can I use in my Java or Kotlin source code?](https://developer.android.com/build/jdks#compileSdk)
---
## Set Environment Variable
The **Set Environment Variable** step enables the setting of environment values for specified keys. Although creating environment variables via the [Environment Variables](/environment-variables/) page is typically recommended, this step provides flexibility to modify environment variables directly within the build workflow when necessary.
### Prerequisites
There are no prerequisites required before using the **Set Environment Variable** step. It can be implemented at any point within the workflow as necessary.
:::danger
Please note that you must use the **Set Environment Variable** step before the step in which you intend to use the environment variable.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ------------------ | --------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_SETENV_KEYS` | Specifies the key of the environment variable to be set. This should be a space-separated list of environment variable keys. | Required |
| `$AC_SETENV_VALUE` | Specifies the value of the environment variable to set. If this field is left blank, the environment variable will be set to `null`. | Optional |
:::info Output Variables
The **Set Environment Variable** step generates no output variables. Success or failure of this step depends on whether the environment variable is set correctly, allowing subsequent use within the workflow.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-setenvironment-component.git
---
## Snyk Scan Security
[Snyk Security Scan](https://snyk.io/learn/vulnerability-scanner/) is a powerful tool designed to identify and resolve vulnerabilities within your project's dependencies. Leveraging Snyk's extensive vulnerability database, this tool thoroughly analyzes libraries and frameworks used in your project, offering actionable insights to mitigate potential risks.
The **Snyk Security Scan** step integrates directly into Appcircle’s CI/CD workflows, allowing developers to automatically scan project dependencies for vulnerabilities with each build.
### Prerequisites
Before running the **Snyk Scan Security** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| -------------------------- | --------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/#git-clone) | Fetches the repository to be built from the specified branch, ensuring that the [Snyk CLI](https://docs.snyk.io/snyk-cli) can run on the repository path. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|-----------------------------------------------------------------------------------------------------------|-----------|
| `$AC_REPOSITORY_DIR` | Specifies the directory where the repository is cloned. | Required |
| `$AC_SNYK_ORGANIZATION` | The name of the [Snyk organization](https://docs.snyk.io/snyk-admin/groups-and-organizations/organizations) under which this project should be tested and monitored. | Required |
| `$AC_SNYK_AUTH_TOKEN` | Your [Snyk authentication token](https://docs.snyk.io/snyk-api/authentication-for-api). | Required |
| `$AC_SYK_CLI_COMMAND` | The [Snyk CLI command](https://docs.snyk.io/snyk-cli/cli-commands-and-options-summary) to execute. The default value is `test`. | Optional |
| `$AC_SNYK_SEVERITY_THRESHOLD` | Specifies the minimum [severity level of vulnerabilities](https://docs.snyk.io/manage-risk/prioritize-your-issues/severity-levels) to report. Options: `low`, `medium`, `high`. | Optional |
| `$AC_SNYK_FAIL_ON_ISSUES` | Specifies whether the build should fail based on the Snyk test results. Options: `yes`, `no`. | Optional |
| `$AC_SNYK_CREATE_REPORT` | Specifies whether to generate an [HTML report](https://docs.snyk.io/manage-risk/reporting/available-snyk-reports). Options: `yes`, `no`. | Optional |
| `$AC_SNYK_MONITOR` | If enabled, imports the snapshot of dependencies to [Snyk for continuous monitoring](https://docs.snyk.io/snyk-cli/commands/monitor). Options: `yes`, `no`. | Optional |
| `$AC_SNYK_ADD_ARG` | Additional arguments for the Snyk CLI command. | Optional | | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Output Variable | Description |
|--------------------------------|--------------------------------------------------------------------------------------------------------------------------|
| `AC_SNYK_REPORT` | The [Snyk report](https://docs.snyk.io/manage-risk/reporting/) file containing the results of executed tests. |
| `AC_SNYK_MONITOR_EXPLORE_LINK`| The [link to explore and monitor](https://docs.snyk.io/snyk-cli/commands/monitor) the project's security status on Snyk. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-snyk-scan-secure-component
---
## SonarQube
This step allows you to analyse your code quality with the [SonarQube CLI](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner). Whichever workflow you are doing your code analysis after, please run the **SonarQube** step after that step is completed.
### Prerequisites
Before running the **SonarQube** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | If you intend to retrieve the **SonarQube Scanner** parameters from the `sonar-project.properties` file in your repository, it's essential to employ the **Git Clone** step before the **SonarQube** step. After the **Git Clone** step is completed, it generates the `$AC_REPOSITORY_DIR` variable, which is used as input for the **SonarQube** step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::caution
Please note that **SonarQube** is a commercial code quality analysis tool. The parameters required for the scanner to work should be used as [**Enviroment Variables**](/environment-variables) as they may create security vulnerabilities. You can obtain these parameters by contacting your DevOps team.
:::
| Variable Name | Description |Status |
|-------------------------------|------------------------------------------------|--------------------|
| `$AC_SONAR_VERSION` | You can change the **SonarQube CLI** version as you wish with the version parameter. The default will be the **latest**. For more information about the **SonarQube CLI** version, please check out this [Github releases page](https://github.com/SonarSource/sonar-scanner-cli/releases). | Required |
| `$AC_SONAR_PARAMETERS` | [Scanner parameters](https://docs.sonarsource.com/sonarqube/9.9/analyzing-source-code/analysis-parameters/) are written in Java property format. You have extra parameters to be able to run [**Sonar Scanner**](https://docs.sonarsource.com/sonarqube/9.9/analyzing-source-code/scanners/sonarscanner/); you can specify them directly here. If there is a `sonar-project.properties` file in the main directory of your repository, its contents will be used instead of the properties entered here. If this input variable is not defined and the mentioned file does not exist in your repository, then the **SonarQube** step will not work. | Optional |
| `$AC_SONAR_EXTRA_PARAMETERS` | Extra command line parameters. Enter `-X` for debug mode. | Optional |
### Including Tests
You can also include your unit/UI test results in the **SonarQube** analysis.
:::caution
If you want to include your test results in the **SonarQube** analysis, always run the **SonarQube** step after the test step.
:::
#### iOS Tests
:::danger
SonarQube accepts `XML` format files to analyse test results. In order to analyse your test results, do not forget to convert the test results to `XML` format by running the [**Convert Xcresult to HTML/XML**](/workflows/ios-specific-workflow-steps/convert-xcresult-to-xml-html) step after the [**Xcodebuild for Unit and UI testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) step.
:::
#### Android Tests
If you intend to send the test result file obtained from the Android unit test output to **SonarQube**, it is necessary to execute the **Android Unit Tests** step before the **SonarQube** step.
:::caution
Ensure that the test result path provided to **SonarQube** as a property matches the test result path generated by the [**Android Unit Tests**](/workflows/android-specific-workflow-steps/android-unit-tests) step, and direct the output to that location.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-sonarqube-component
---
## Testinium Steps
## [Testinium Upload App](/workflows/common-workflow-steps/testinium-steps/testinium-upload-app)
The **Testinium Upload App** step uploads mobile apps from Appcircle to Testinium, supporting both cloud and enterprise environments.
## [Testinium Run Test Plan](/workflows/common-workflow-steps/testinium-steps/testinium-run-test-plan)
The **Testinium Run Test Plan** step allows you to run automated tests on your mobile applications directly from Appcircle, whether using Testinium cloud or enterprise setup.
## [Testinium](/workflows/common-workflow-steps/testinium-steps/testinium)
The **Testinium** step allows users to upload their mobile applications to **Testinium** and run a test plan for Testinium cloud users.
---
## Testinium Run Test Plan
The **Testinium Run Test Plan** step integrates the [Testinium](https://testinium.com/) testing platform into Appcircle's CI/CD workflow, allowing for automated testing of mobile applications directly within the Appcircle environment. This step enables developers to execute the test plan, analyze test outcomes, and verify the quality of their mobile apps before deployment.
### Prerequisites
Before running the **Testinium Run Test Plan** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Testinium Upload App**](/workflows/common-workflow-steps/testinium-steps/testinium-upload-app) | Required to upload your application to Testinium before executing test plans with the **Testinium Run Test Plan** step. |
:::tip
After using the [**Testinium Upload App**](/workflows/common-workflow-steps/testinium-steps/testinium-upload-app) step once, you can add multiple **Testinium Run Test Plan** steps to the workflow for each test plan.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_TESTINIUM_USERNAME` | Specifies the Testinium username used for logging in. | Required |
| `$AC_TESTINIUM_PASSWORD` | Specifies the Testinium password used for logging in. | Required |
| `$AC_TESTINIUM_PLAN_ID` | Specifies the Testinium plan ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_ENTERPRISE_BASE_URL` | The base URL for Testinium enterprise. This is required if you are using Testinium enterprise. Only for Testinium cloud users is this input not mandatory. | Optional |
| `$AC_TESTINIUM_COMPANY_ID` | Specifies the Testinium company ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_MAX_FAIL_PERCENTAGE` | Specifies the maximum failure percentage limit to interrupt the workflow. It must be in the range `0`-`100`. Selecting `0` means failures will not interrupt the workflow. | Optional |
| `$AC_TESTINIUM_TIMEOUT` | Specifies the Testinium plan timeout in minutes. | Required |
| `$AC_TESTINIUM_MAX_API_RETRY_COUNT` | Specifies the maximum retry in case of Testinium platform congestion or API errors. | Required |
| `$AC_TESTINIUM_UPLOADED_APP_ID` | The unique identifier for the application was uploaded to Testinium. This ID is generated after the **Testinium App Upload** step. | Required |
| `$AC_TESTINIUM_APP_OS` | The operating system of the uploaded application, either `iOS` or `Android`. This value is determined after the **Testinium App Upload** step. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------------------- | ------------------------------------------------------------------------------- |
| `AC_TESTINIUM_TEST_REPORT` | The file path of the test report generated by Testinium after running the plan. |
| `AC_TESTINIUM_RESULT_FAILURE_SUMMARY` | Total number of failures in the test results. |
| `AC_TESTINIUM_RESULT_ERROR_SUMMARY` | Total number of errors in the test results. |
| `AC_TESTINIUM_RESULT_SUCCESS_SUMMARY` | Total number of successes in the test results. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-testinium-run-test-plan-component
---
## Testinium Upload App
The **Testinium Upload App** step integrates the [Testinium](https://testinium.com/) testing platform into Appcircle's CI/CD workflow, allowing developers to upload mobile applications seamlessly to Testinium. This step serves as a prerequisite for executing test plans, enabling efficient and automated testing directly within the Appcircle environment.
### Prerequisites
Before running the **Testinium Upload App** step, you must complete certain prerequisites, as detailed in the table below:
:::info
After uploading the application, you should use the [**Testinium Run Test Plan**](/workflows/common-workflow-steps/testinium-steps/testinium-run-test-plan) step to run the test plan and view the test report. If you prefer to perform both operations within the same step, use the [**Testinium**](/workflows/common-workflow-steps/testinium-steps/testinium) step instead.
:::
#### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | Generates the app required for the **Testinium Upload App** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | This step is required for signing the app. It processes the output for signing but can be skipped if the app is already signed. |
#### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates a `IPA` file. |
#### For Android Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps#flutter-build-for-android) | Generates the app required for the **Testinium Upload App** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | This step is required for signing the app. It processes the output for signing but can be skipped if the app is already signed. |
#### For iOS Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in `ARM` architecture and generates an `IPA` file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps#flutter-build-for-ios) | Prepares the Flutter project for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter). |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_TESTINIUM_APP_PATH` | Specifies the full file path of the build output, such as `$AC_OUTPUT_DIR/MyApp.ipa` for iOS or `$AC_APK_PATH` for Android. | Required |
| `$AC_TESTINIUM_USERNAME` | Specifies the Testinium username used for logging in. | Required |
| `$AC_TESTINIUM_PASSWORD` | Specifies the Testinium password used for logging in. | Required |
| `$AC_TESTINIUM_ENTERPRISE_BASE_URL` | The base URL for Testinium enterprise. This is required if you are using Testinium enterprise. Only for Testinium cloud users is this input not mandatory. | Optional |
| `$AC_TESTINIUM_PROJECT_ID` | Specifies the Testinium project ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_COMPANY_ID` | Specifies the Testinium company ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_TIMEOUT` | Specifies the Testinium plan timeout in minutes. | Required |
| `$AC_TESTINIUM_MAX_API_RETRY_COUNT` | Specifies the maximum retry in case of Testinium platform congestion or API errors. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| --------------------------------- | ------------------------------------------------------------------------------- |
| `AC_TESTINIUM_UPLOADED_APP_ID` | The unique identifier for the application was uploaded to Testinium. This ID is used to select the uploaded application on the **Testinium Run Test Plan** step. |
| `AC_TESTINIUM_APP_OS` | The operating system of the uploaded application, either `iOS` or `Android`. This helps to run the test plan according to the platform OS in the **Testinium Run Test Plan** step. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-testinium-upload-app-component
---
## Testinium
The **Testinium** step integrates the [Testinium](https://testinium.com/) testing platform into Appcircle's CI/CD workflow, enabling users to upload mobile applications, execute test plans, and analyze results. This step helps developers run automated tests, assess test outcomes, and ensure app quality before deployment.
:::tip Multiple Test Plans
If you're using Testinium as an enterprise or need to run multiple test plans for the same app, use the [**Testinium Upload App**](/workflows/common-workflow-steps/testinium-steps/testinium-upload-app) step followed by multiple [**Testinium Run Test Plan**](/workflows/common-workflow-steps/testinium-steps/testinium-run-test-plan) steps instead of the **Testinium** step. This allows you to execute multiple test plans separately within the workflow.
:::
### Prerequisites
Before running the **Testinium** step, you must complete certain prerequisites, as detailed in the table below:
#### For Android (Java / Kotlin and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Android Build**](/workflows/android-specific-workflow-steps/android-build) | Generates the app required for the **Testinium** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | This step is required for signing the app. It processes the output for signing but can be skipped if the app is already signed. |
#### For iOS (Objective-C / Swift and React Native)
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
#### For Android Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps#flutter-build-for-android) | Generates the app required for the **Testinium** step. |
| [**Android Sign**](/workflows/android-specific-workflow-steps/android-sign) | This step is required for signing the app. It processes the output for signing but can be skipped if the app is already signed. |
#### For iOS Flutter
| Prerequisite Workflow Step | Description |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps#xcodebuild-for-devices-archive--export) | Builds the application in ARM architecture and generates an `IPA` file. |
| [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps#flutter-build-for-ios) | Prepares the Flutter project for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter). |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_TESTINIUM_APP_PATH` | Specifies the full file path of the build output, such as `$AC_EXPORT_DIR/Myapp.ipa` for iOS or `$AC_APK_PATH` for Android. | Required |
| `$AC_TESTINIUM_USERNAME` | Specifies the Testinium username used for logging in. | Required |
| `$AC_TESTINIUM_PASSWORD` | Specifies the Testinium password used for logging in. | Required |
| `$AC_TESTINIUM_PROJECT_ID` | Specifies the Testinium project ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_PLAN_ID` | Specifies the Testinium plan ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_COMPANY_ID` | Specifies the Testinium company ID. This ID must be obtained from the Testinium platform. | Required |
| `$AC_TESTINIUM_MAX_FAIL_PERCENTAGE` | Specifies the maximum failure percentage limit to interrupt the workflow. It must be in the range 1-100. | Optional |
| `$AC_TESTINIUM_TIMEOUT` | Specifies the Testinium plan timeout in minutes. | Required |
| `$AC_TESTINIUM_MAX_API_RETRY_COUNT` | Specifies the maximum repetition in case of Testinium platform congestion or API errors. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------------------- | ------------------------------------------------------- |
| `AC_TESTINIUM_RESULT_FAILURE_SUMMARY` | Total number of failures in the test. |
| `AC_TESTINIUM_RESULT_ERROR_SUMMARY` | Total number of errors in the test. |
| `AC_TESTINIUM_RESULT_SUCCESS_SUMMARY` | Total number of successes in the test results. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-testinium-component
---
## Upload Files to Amazon S3
[Amazon Simple Storage Service (S3)](https://aws.amazon.com/s3/) is an object storage service provided by AWS, utilized for storing build artifacts across diverse use cases.
The **Upload Files to Amazon S3** step in Appcircle enables direct uploading of any file or folder to the designated Amazon S3 bucket during the build process.
### Prerequisites
There are no prerequisites required before using the **Upload Files to Amazon S3** step.
:::info
To begin, add the **Upload Files to Amazon S3** step to the workflow from the [workflow marketplace](/build/build-process-management/build-workflows#workflow-marketplace). You can incorporate it at any point within the workflow and multiple times, as necessary, to upload specific files or folders. For example, you can place it after the build step to deploy the build outputs.
Once added, exit the workflow edit mode by saving your changes, and then click on the **Upload Files to Amazon S3** step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------|--------------------------------------------------|-----------|
| `$AC_INPUT_FILE_PATH` | Specifies the file or folder name to be uploaded to S3. You can provide the full path or the output of another step as an environment variable (e.g., `$AC_ARCHIVE_PATH` allows you to upload the output of the **Xcode Build for Devices** step). | Required |
| `$AWS_ACCESS_KEY_ID` | Specifies the AWS access key ID. [For more information, refer here](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys). | Required |
| `$AWS_SECRET_ACCESS_KEY`| Specifies the secret access key associated with the entered ID. [For more information, refer here](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys). | Required |
| `$AWS_BUCKET_NAME` | Specifies the S3 bucket name as the deployment target. | Required |
| `$AWS_BUCKET_REGION` | Specifies the AWS region where the specified bucket resides. You can find the [endpoint codes for the regions here](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). The default value is `us-east-1`. | Optional |
| `$AWS_TARGET_DIR` | Specifies the Amazon S3 folder path in the bucket. By default, it selects the date (`Y-m-d-H-M-S`) as the folder. | Optional |
:::info
It is highly recommended to add the keys as [secret environment variables](/build/build-environment-variables) instead of typing them here for security purposes.
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Output Variable | Description |
|-------------------------|----------------------------------------------------------------|
| `AC_AWS_UPLOAD_URL` | Specifies that the files and folders are deployed to a newly created directory as `s3://bucket-name/timestamp` to avoid any conflicts and potential overwrites. |
After saving your settings, the build can be run, and the step will be executed accordingly. Details of the upload operation can be viewed in the build logs:
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-file-upload-to-amazon-s3
---
## Firebase Deployment
[Firebase Deployment](https://firebase.google.com/docs/hosting) is production-grade web content hosting for developers. With a single command, you can quickly deploy web apps and serve both static and dynamic content to a global CDN (content delivery network).
Deploy web applications effortlessly using Appcircle's Firebase Deployment component.
### Prerequisites
Before running the **Firebase Deployment** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Flutter Build for Web**](/workflows/flutter-specific-workflow-steps/flutter-build-for-web) | The Flutter Build for Web step builds your web application using the [Flutter SDK](https://docs.flutter.dev/deployment/web#building-the-app-for-release) |
| [**Flutter Install**](/workflows/flutter-specific-workflow-steps/flutter-install) | This step installs the [Flutter SDK](https://docs.flutter.dev/deployment/web#building-the-app-for-release). If no version is specified, it installs the latest stable version. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|------------------------------------------|---------------------------------------------------------------------|------------------|
| `$AC_FIREBASE_VERSION` | Firebase version to be used. Enter v11.11.0 for a specific version. | Required |
| `$AC_FIREBASE_PROJECT_PATH` | The directory containing your `firebase.json` file. | Required |
| `$AC_FIREBASE_TOKEN` | A refresh token is generated when you authenticate using the `firebase login:ci` command. Choose either a **Either select Firebase token or Google Service account**. | Optional |
| `$GOOGLE_APPLICATION_CREDENTIALS` | Specify the path to your Google Service Account JSON file. Upload this file to your environment group under the name `GOOGLE_APPLICATION_CREDENTIALS`. Choose either a **Firebase token** or a **Google Service account**. | Optional |
| `$AC_FIREBASE_EXTRA_PARAMETERS` | Extra command line parameters. Enter --debug for debug mode. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-firebase-deploy-component
---
## Flutter Analyze
This component runs the `flutter analyze` command in your Flutter project. Please note that it requires the [**Flutter SDK**](https://docs.flutter.dev/get-started/install).
### Prerequisites
Before running the **Flutter Analyze** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step will clone your project through the connected Git provider and create the `$AC_REPOSITORY_DIR` variable. |
| [**Flutter Install**](/workflows/flutter-specific-workflow-steps/flutter-install) | This step will install the [Flutter SDK](https://flutter-ko.dev/development/tools/sdk/releases) release. If the version is not specified, it will install the latest **stable** version.|
:::danger
This step is particularly dependent on the Flutter Install step. If the Flutter SDK is not installed, the step will give an error that the required command was not found.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_FLUTTER_PROJECT_DIR` | This parameter is used as the repository path. This path is created immediately after the **Git Clone** step. If the **Git Clone** step is not used, this path cannot be found. | Required |
| `$AC_FLUTTER_ANALYZE_EXTRA_ARGS` | You can use this parameter if you want to add an extra parameter to the build command line. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-flutter-analyze-component
---
## Flutter Build for Android
The **Flutter Build for Android** step automates the generation of Android APK (Android Package) or AAB (Android App Bundle) files from [Flutter](https://flutter.dev) source code using the [Flutter SDK](https://docs.flutter.dev/tools/sdk). This simplifies the process of creating distributable packages for Flutter applications.
### Prerequisites
Before running the **Flutter Build for Android** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| -------------------------- | --------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step fetches the repository that needs to be built from the specified branch. It is essential for initiating the Flutter Android build process. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|-------------------------------------------------------------------------------------------------------|-----------|
| `$AC_FLUTTER_PROJECT_DIR` | Specifies the directory at the root of your Flutter project where the `pubspec.yaml` file is located. | Required |
| `$AC_OUTPUT_TYPE` | Defines the output type, such as `APK` or `AAB` (Android App Bundle). | Required |
| `$AC_FLUTTER_BUILD_MODE` | Specifies the Flutter build mode. The default value is `release`. | Optional |
| `$AC_FLUTTER_BUILD_EXTRA_ARGS`| Additional custom build arguments. For instance: `--split-per-abi`. | Optional |
:::info
If the required variables are already defined in the **Configuration** section, there is no need to redefine them in the Workflow. For more details, see the [Build Profile Configuration Overview](/build/build-process-management/configurations). The details you provide in the configuration will serve as input for the **Android Build** step. Kindly substitute the example information with your details:
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Output Variable | Description |
|---------------------------|---------------------------------|
| `AC_APK_PATH` | Path of the generated APK file. |
| `AC_AAB_PATH` | Path of the generated AAB file. |
:::info
The resulting files will be either APK or AAB, based on the `Output Type` selected in the project [Configuration](/build/build-process-management/configurations).
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-android-flutter-build-component
---
## FAQ
### How can I solve the `Out of memory error: Java heap memory` or set the heap memory during the build?
To resolve this issue, please refer to the following document for detailed instructions:
- [Android Build FAQ](/workflows/android-specific-workflow-steps/android-build#how-can-i-solve-the-out-of-memory-error-java-heap-memory-or-set-the-heap-memory-during-the-build)
---
## Flutter Build for iOS
This step makes your Flutter project suitable for the iOS environment and builds it using the [Flutter SDK](https://github.com/flutter/flutter).
### Prerequisites
Before running the **Flutter Build for iOS** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step will clone your project through the connected Git provider and create the `$AC_REPOSITORY_DIR` variable. |
| [**Flutter Install**](/workflows/flutter-specific-workflow-steps/flutter-install) | This step will install the Flutter SDK. If a version is not specified, it will install the latest **stable** version. The **Flutter SDK** package must be installed on the system. For this reason, make sure that **Flutter Build for iOS** is used after the **Flutter Install**. |
:::caution
Once you have compiled your app for Flutter iOS, the native environment will be built. For this reason, this step should be used before the [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) step.
:::
:::danger
**Keep in mind** that this step is dependent on the **Flutter Install** step. If Flutter is not installed on the system, it will give a Flutter SDK not found error.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_FLUTTER_PROJECT_PATH` | This parameter is used as the repository path. This path is created immediately after the **Git Clone** step. If the **Git Clone** step is not used, this path cannot be found. | Required |
| `$AC_FLUTTER_BUILD_MODE` | With this variable, you can add the mode you want to build in the build command. For example: `release`. | Required |
| `$AC_FLUTTER_BUILD_EXTRA_ARGS`| You can use this parameter if you want to add an extra parameter to the build command line. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-flutter-build-component
---
## Flutter Build for Web
The **Flutter Build for Web** step builds your web application using the [Flutter SDK](https://flutter.dev/docs/deployment/web#building-the-app-for-release).
### Prerequisites
Before running the **Flutter Build for Web** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step clones your project from the connected Git provider and creates the `$AC_REPOSITORY_DIR` variable, which defaults to `$AC_FLUTTER_PROJECT_DIR`. |
| [**Flutter Install**](/workflows/flutter-specific-workflow-steps/flutter-install) | This step installs the [Flutter SDK](https://flutter-ko.dev/development/tools/sdk/releases). If no version is specified, it installs the latest **stable** version. |
:::danger
This step relies heavily on the **Flutter Install** step. If the Flutter SDK is not installed, the step will report an error stating that the required command was not found.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|-------------------------------------|-----------------|
| `$AC_FLUTTER_PROJECT_DIR` | This parameter represents the repository path. The default value is `$AC_REPOSITORY_DIR`, which is created after the **Git Clone** step. | Required|
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|------------------------|-------------------------------------|
| `AC_FLUTTER_WEB_PATH` | This path is generated after the completion of the **Flutter Build for Web** step and stores the generated web application. |
### Deploying Applications to AWS Services
AWS Amplify offers a fully managed service for deploying and hosting static web applications, and Appcircle supports building Flutter web apps.
You can deploy Flutter web apps (or any other web app) that you build with Appcircle to AWS Amplify Console for an end-to-end app lifecycle from a single CI/CD platform for web and mobile.
To deploy apps to Amplify, you can use Git, manual uploads, or Amazon S3 buckets as the source.
Since Appcircle supports automated Amazon S3 uploads, you can automatically deploy your apps from Appcircle to Amazon S3 and then sync your S3 bucket with Amplify Console with the following steps:
- First, set up a [Flutter Web App build](/build/platform-build-guides/building-flutter-applications/building-flutter-web-applications).
- Then, add an [Upload to Amazon S3 step to your workflow](/workflows/common-workflow-steps/upload-files-to-amazon-s3) and configure it to receive the web app artifact as the input of the step.
- To set up Amplify Console and S3 sync, first go to Amplify and [set up a manual deployment](https://docs.aws.amazon.com/amplify/latest/userguide/manual-deploys.html).
- Then, follow the steps [in this AWS blog post](https://aws.amazon.com/blogs/mobile/deploy-files-s3-dropbox-amplify-console/) to automate deployments from an S3 bucket to Amplify.
You can build your Flutter web apps with Appcircle and deploy them to the Amplify Console with end-to-end automation.
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-flutter-web-build-component
---
## Flutter Install
This workflow step installs the specified [**Flutter SDK**](https://docs.flutter.dev/get-started/install) to run the [**Flutter CLI**](https://docs.flutter.dev/reference/flutter-cli) for subsequent analysis, build, and test operations. The Flutter version can be specified in [Configuration](/build/platform-build-guides/building-flutter-applications#build-configuration-for-flutter-ios-applications)
:::info
All Flutter versions and detailed information can be found in the [Flutter repository](https://github.com/flutter/flutter).
:::
### Prerequisites
There are no prerequisites required before using the **Flutter Install** step.
:::caution
These steps depend on Flutter installation and can only be used after the **Flutter Install** step:
- [**Flutter Build for iOS**](/workflows/flutter-specific-workflow-steps/flutter-build-for-ios)
- [**Flutter Build for Android**](/workflows/flutter-specific-workflow-steps/flutter-build-for-android)
- [**Flutter Analyze**](/workflows/flutter-specific-workflow-steps/flutter-analyze)
- [**Flutter Test**](/workflows/flutter-specific-workflow-steps/flutter-test)
- [**Flutter Build for Web**](/workflows/flutter-specific-workflow-steps/flutter-build-for-web)
:::
:::danger
The steps specified in the table are steps dependent on the **Flutter Install** step. **If Flutter Install is not used before these steps**, these steps will give a **Flutter SDK not found error**.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_SELECTED_FLUTTER_VERSION`| Specifies the Flutter version to install. Defaults to: `stable`. The version you set in the [Configuration](/build/platform-build-guides/building-flutter-applications#build-configuration-for-flutter-ios-applications) section will override this setting. | Optional |
:::caution
If no specific version is specified, this step will automatically install the latest [**stable**](https://docs.flutter.dev/release/archive?tab=macos) version released by Flutter.
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `PATH`| PATH variable that adds the Flutter tool to your workflow. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-flutter-install-component
---
## Flutter Test
This component allows you to run [**Flutter Unit Tests**](https://docs.flutter.dev/cookbook/testing/unit/introduction#run-tests-in-a-terminal). Please note that it requires the [**Flutter SDK**](https://flutter-ko.dev/development/tools/sdk/releases).
### Prerequisites
Before running the **Flutter Test** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step will clone your project through the connected Git provider and create the `$AC_REPOSITORY_DIR` variable. |
| [**Flutter Install**](/workflows/flutter-specific-workflow-steps/flutter-install) | This step will install the [Flutter SDK](https://flutter-ko.dev/development/tools/sdk/releases) release. If the version is not specified, it will install the latest **stable** version.|
:::danger
This step is particularly dependent on the Flutter Install step. If the Flutter SDK is not installed, the step will give an error that the required command was not found.
:::
### Input Variables
You can find all the parameters required for this step in the table below, with their descriptions in detail.
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_FLUTTER_PROJECT_DIR` | This parameter is used as the repository path. This path is created immediately after the Git Clone step. If the Git Clone step is not used, this path cannot be found. | Required|
| `$AC_FLUTTER_JUNIT_REPORTS` | If this is set to `YES`, [JUnit](https://junit.org/junit5/) test report will be created at the `AC_TEST_RESULT_PATH`. | Optional |
| `$AC_FLUTTER_TEST_EXTRA_ARGS` | You can use this parameter if you want to add an extra parameter to the build command line. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `AC_TEST_RESULT_PATH` | This path is created after the test results are reported. If you are using the [**Export Build Artifact**](/workflows/common-workflow-steps/export-build-artifacts) step, it can be accessed directly from [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts). |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-flutter-test-component
---
## Flutter Specific Workflow Steps
The steps listed below are specific to the Flutter build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [Firebase Deployment](/workflows/flutter-specific-workflow-steps/firebase-deployment)
Deploy your web applications to Firebase Hosting
## [Flutter Analyze](/workflows/flutter-specific-workflow-steps/flutter-analyze)
This component runs the `flutter analyze` command in your Flutter project.
## [Flutter Build for Android](/workflows/flutter-specific-workflow-steps/flutter-build-for-android)
This component builds your Flutter project for Android with the [Flutter SDK](https://github.com/flutter/flutter).
## [Flutter Build for iOS](/workflows/flutter-specific-workflow-steps/flutter-build-for-ios)
This component builds your Flutter project for iOS with the [Flutter SDK](https://github.com/flutter/flutter).
## [Flutter Build for Web](/workflows/flutter-specific-workflow-steps/flutter-build-for-web)
This component builds a web app with the [Flutter SDK](https://flutter.dev/docs/deployment/web#building-the-app-for-release).
## [Flutter Install](/workflows/flutter-specific-workflow-steps/flutter-install)
This workflow step installs the specified Flutter SDK to run the Flutter CLI for subsequent, Analyze, Build and Test operations.
## [Flutter Test](/workflows/flutter-specific-workflow-steps/flutter-test)
This component allows you to run [Flutter unit tests](https://flutter.dev/docs/cookbook/testing/unit/introduction#run-tests-in-a-terminal).
---
## How to Create an Integration
This guide outlines the process for creating a new Integration in Appcircle.
:::info
Before creating a new integration, please check the [Appcircle Integrations](https://appcircle.io/integrations) page to ensure the integration does not already exist.
:::
## 1. Repository Creation
The first phase is to create a dedicated repository where the step’s code will be managed.
### 1.1. Contact Appcircle Team
Before starting the development of a new integration, contributors must first get in touch with the Appcircle team. This ensures that the proposed step aligns with Appcircle’s roadmap and standards.
> **Contact the Appcircle Team:** 🔗 [Contact Appcircle Team](https://appcircle.io/contact)
### 1.2. Create Repository in Appcircle Organization
Once the proposal is approved, the contributor should request the creation of a new repository under the [appcircleio](https://github.com/appcircleio) GitHub organization. All official workflow steps are maintained under this organization to ensure consistency, security, and proper maintenance.
## 2. Core Implementation
This section describes the core implementation details of the workflow step, including the step structure, configuration, and scripting conventions.
:::danger MIT License
When the Appcircle team creates a repository, it will include an **MIT license** by default. Please do not remove or modify this file, as the license ensures openness, reusability, and legal protection for both contributors and users.
:::
### 2.1 Main Code File Standards
Each workflow step must include a main execution file. Currently, Appcircle supports two languages: **Ruby** and **Bash**.
Therefore, the main file must be named either `main.rb` or `main.sh`.
#### 2.1.1 Code Quality Requirements
All workflow steps in Appcircle are open source. Code should be easy to understand and maintain, as all users may contribute to it. Following **Clean Code** principles is mandatory.
#### 2.1.2 Code Consistency Requirements
All steps must follow the same conventions for naming, file structure, and environment handling.
**Exit Codes**
All steps must use the following exit conventions:
- `exit 0`: The step completes successfully, and execution continues to the next step.
- `exit 1`: The step fails and breaks the workflow execution.
**Error Logging**
To display an error message to the user, print it with the `@@[error]` tag:
```
@@[error] Your error message here
```
Any log printed in this format will be shown as an error message in the Appcircle interface.
**Running Terminal Commands**
All terminal commands must be executed through a function named `run_command`. This ensures consistent logging and error handling across all steps. The command must be printed with the `@@[command]` tag before execution.
Example `run_command` implementation in Ruby:
```ruby
def run_command(command)
puts "@@[command] #{command}"
status = nil
stdout_str = nil
stderr_str = nil
Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
stdout.each_line do |line|
puts line
end
stdout_str = stdout.read
stderr_str = stderr.read
status = wait_thr.value
end
unless status.success?
abort(stderr_str)
end
end
```
**Environment Variables**
- Save new environment variables to the [`AC_ENV_FILE_PATH`](https://docs.appcircle.io/environment-variables/appcircle-specific-environment-variables#ios--android-common-environment-variables).
#### 2.1.3 Logging and Output Standards
Logs must follow a color-coded system for consistency:
- Green: Success messages
- Yellow: Warnings and status updates
- Blue: Ongoing operations
- Red: Error messages
Logging patterns:
- Error messages must start with the `@@[error]` tag.
- Commands must start with the `@@[command]` tag.
For reference:
- Example workflow step code for **color usage**: [appcircle-android-post-process-component/main.rb](https://github.com/appcircleio/appcircle-android-post-process-component/blob/master/main.rb)
- Example workflow step code for **logging patterns**: [appcircle-cache-pull-component/main.rb](https://github.com/appcircleio/appcircle-cache-pull-component/blob/main/main.rb)
:::warning Avoid Using Environment Variables Directly in Code
Never access environment variables directly within your step's code. Instead, expose each required variable as a **named input** in your `component.yaml`, and set its `defaultValue` to the corresponding environment variable.
**Why?**
- Makes the step easier to test in isolation.
- Users can clearly see all required inputs without reading through the source code.
- Inputs can be overridden when needed, improving flexibility.
**Example:**
```yaml
inputs:
- key: AC_BUILD_NUMBER
defaultValue: "$BUILD_NUMBER"
title: "Build Number"
isRequired: true
```
Then in your main code, read `AC_BUILD_NUMBER` as a regular input — not `$BUILD_NUMBER` directly.
:::
### 2.2 `component.yaml` Configuration
Each step must include a `component.yaml` file that defines the step’s metadata, inputs, outputs, and execution details.
This file ensures the step integrates properly into the Appcircle platform.
:::tip
For example, you can review how the `component.yaml` of the following repository is structured as follows:
- [Appcircle Firebase App Distribution component](https://github.com/appcircleio/appcircle-firebase-distribution-component)
:::
#### Required YAML Structure
Specifies the essential fields and format of every `component.yaml` file must follow for proper step integration.
```yaml
platform: "The projects the step operates on. Options: 'Common', 'Android', or 'iOS. If empty, it supports all platform.'"
buildPlatform: "The platforms the step operates on. Options: 'ReactNative', 'JavaKotlin', 'Flutter', 'ObjectiveCSwift'. If empty, it supports all build platform."
displayName: "The step name displayed in the workflow step list."
description: "The step description displayed in the workflow step list."
inputs:
- key: "Defines the input key used in the main code by the step."
defaultValue: "Default value for the input. If `editorType` is 'select', one of the options should be specified here."
isRequired: "Options: true/false. If true selected, and value not defined, `main.rb` will fail to execute."
title: The title displayed for this input in the step details interface.
description: "Description displayed for this input in the step details interface."
editorType: "Defines the type of the value field. Options: 'select', 'textarea', 'text'. Defaults to 'text' if not specified."
options: "If `editorType` is 'select' options should be provided here. Example: 'true,false'."
helpText: "Help text if available. This is not displayed in the interface."
- key: ...
outputs: #if there are
- key: "Defines the output key used in the main code by the step."
defaultValue: "Specify the environment variable where the step output will be assigned."
title: The title displayed for this output in the step details interface.
description: "Description displayed for this output in the step details interface."
helpText: "Help text if available. This is not displayed in the interface."
- key: ...
processFilename: "ruby" # Programming language. Options: Ruby, Bash.
processArguments: "%AC_STEP_TEMP%/main.rb" # Main execution file (change to main.sh if main code is bash)
files:
- "main.rb" # Main execution file (change to main.sh if main code is bash)
- "additional_files.rb" # Add here any additional files from the same repository that are used within the main code, if any.
# For example additional files, see the,
# [Git Clone step](https://github.com/appcircleio/appcircle-git-clone-component/blob/e5c185fd9a2657744dd7fdcd2bf1c4a2e7a356c5/component.yaml#L66)
```
:::warning Input Validation Rules
There are two validation rules to be considered for the input:
- If `isRequired: true` and input is not provided, step execution will fail.
- For `editorType: select`, `defaultValue` must match one of the provided options.
:::
:::warning Type of Default Value
Always wrap the value with double quotes ("") to explicitly mark it as a string.
Even if you provide a value like `beeloan`, the `component.yaml` will send it as a string.
:::
### 2.3 `README.md` Rules
Each step must include a `README.md` file to provide clear usage instructions and input/output definitions.
Follow the template below:
```yaml
# Appcircle Step Title
Step description.
## Required Input Variables
- `AC_REQUIRED_INPUT_NAME`: Explanation for this required input.
- ...
## Optional Input Variables
- `AC_OPTIONAL_INPUT_NAME`: Explanation for this optional input.
- ...
## Output Variables
- `AC_OUTPUT_NAME`: Explanation for this output.
- ...
Add any additional relevant information after this section.
## Contributing
We welcome contributions to improve this workflow step. If you would like to add enhancements or fix issues, please refer to the [Appcircle Contribution Guidelines](Link to this documentation). Following these guidelines ensures consistency across all steps and helps us review and merge your contributions more efficiently.
Thank you for helping us make Appcircle better! 🙌
```
After completing these files, the workflow step will be ready for testing.
### 2.4 Unit Test Configuration
Each new integration should include unit tests to verify that the step behaves as expected before publishing.
#### 2.4.1 Test File Structure
Place test files in a `test/` directory at the root of the repository. Name your test file according to the main code language:
- `test/test_main.rb` for Ruby steps
- `test/test_main.sh` for Bash steps
#### 2.4.2 Testing Requirements
Tests must cover the following scenarios:
- **Happy path**: The step runs successfully with valid inputs.
- **Missing required inputs**: The step fails gracefully when a required input is not provided.
- **Invalid inputs**: The step handles unexpected or malformed values properly.
#### 2.4.3 Running Tests Locally
Before submitting a pull request, ensure all tests pass locally:
```bash
# For Ruby
ruby test/test_main.rb
# For Bash
bash test/test_main.sh
```
#### 2.4.4 Test Coverage
All critical functions in the main code file should be covered by tests. Aim for at least **80% coverage** to ensure reliability and maintainability.
---
Once unit tests are configured and passing, the workflow step is considered complete and ready for the **review and testing** process.
## 3. Testing the Step
After completing your source code, you need to follow these steps to test your custom step:
1. **Create your workflow** and add a [Custom Script](/workflows/common-workflow-steps/custom-script) to the designated location where your step should be placed.
2. **Rename the Custom Script** to reflect its purpose and functionality.
3. **Select the appropriate language** for the **Custom Script** to match your main code's programming language.
4. **Paste your main code** into the **Custom Script** editor.
5. **Click the Save** button.
6. **Configure input variables** (if required by component.yaml):
1. **Navigate** to the [Environment Variables](/environment-variables) page
2. **Create a new environment variable group** for the required inputs
3. **Define key-value pairs** for each required input parameter.
4. **Select the environment variable group** from the [Configuration](/build/build-process-management/configurations#environment-variables-configuration) that will be used to start the build.
7. **Start the build** and monitor the execution.
### 3.1 Post-Testing Requirements
Once your tests are complete successfully, you must finalize the documentation explaining how to use this step effectively.
:::info Different Test Cases
In certain scenarios, you may need to test the following additional cases:
- **Cross-platform testing**: If necessary, test across different pools such as React Native, Flutter, Java/Kotlin, or Swift.
- **Different Operating System Testing**: If necessary, test across different pools such as Linux or macOS.
- **Integration testing**: Test with other integrations that are likely to be used together.
:::
### 3.2 Testing Checklist
Use this checklist to ensure all testing requirements are met before submitting your custom step:
- [ ] Custom Script created and configured
- [ ] Code successfully pasted and language selected
- [ ] Environment variables properly defined and selected in the Configuration
- [ ] Test execution completed without errors
- [ ] Cross-platform compatibility verified (if applicable)
- [ ] Integration with existing components tested
✅ Once these steps are successfully completed, you can proceed to the documentation.
## 4. Documentation
Appcircle's [documentation repository](https://github.com/appcircleio/appcircle-docusaurus) is open source. You can create a pull request to this repository and request your documentation to be merged.
There are specific rules that must be followed for workflow documentation, outlined below:
### 4.1 Document Location
The location of your documentation depends on your step's platform compatibility:
- **Cross-platform steps** (all platforms) → [Common Workflow Steps](/workflows/common-workflow-steps)
- **iOS-specific steps** → [iOS Specific Workflow Steps](/workflows/ios-specific-workflow-steps)
- **Android-specific steps** → [Android Specific Workflow Steps](/workflows/android-specific-workflow-steps)
- **React Native-specific steps** → [React Native Specific Workflow Steps](/workflows/react-native-specific-workflow-steps)
- **Flutter-specific steps** → [Flutter Specific Workflow Steps](/workflows/flutter-specific-workflow-steps)
Your documentation must comply with the Document Guidelines in the README to follow the latest contribution standards.
**Important:** File names should follow the `lower-kebab-case` template format.
### 4.2 Adding Step to Index Page
After determining your document's location, add your workflow step to the corresponding `index.md` page. Steps must be listed in **alphabetical order** by step name; find the correct position before inserting your entry. Include your step as shown below:
```markdown
...
## [Step Name](Relative URL of component. e.g., /workflow/platform-name/component-name)
Brief description of what the step does.
...
```
### 4.3 Document template
For general template information, refer to the documentation [README](https://github.com/appcircleio/appcircle-docusaurus?tab=readme-ov-file#documentation-guidelines).
The step documentation template structure is as follows:
```markdown
---
title: Add the title used in the component.yaml on repo.
description: Add a concise purpose for the document/component.
💬 The new tag should be added to the docs/tags.yaml file in accordance with the Tag Strategy:
💬 https://github.com/appcircleio/appcircle-docusaurus?tab=readme-ov-file#tag-strategy.
tags: [add, terms, or, keywords, relevant, to, this topic]
---
💬 Add the following line for adding screenshots seamlessly.
# Step Name
The introduction below the title should include general information about the component's purpose.
Add detailed information about the document in the following paragraphs if needed.
## Prerequisites
💬 Option 1: With Prerequisites
Before running the **Step Name** step, you must complete certain prerequisites, as detailed in the table below:
💬 Add a table listing dependencies with the following columns
| Prerequisite Workflow Step | Description |
|---------------------------|-------------|
| [**Prerequisite Step Name**](Relative URL of component. e.g., /workflow/platform-name/component-name) | Description of why it is needed. |
| ... | ... |
💬 Option 2: No Prerequisites
There are no prerequisites required before using the **Step Name** step.
💬 If sequential execution is required with no dependency, add it as a caution like the following.
:::caution
If [**Pre Component Name**](Relative URL of component. e.g., /workflow/platform-name/component-name) component is in the workflow, the **Component Name** must come before it.
:::
💬 Or you can prefer following caution:
:::caution
The following steps can only be used after the **Component Name** step:
- [**Pre Component Name**](Relative URL of component. e.g., /workflow/platform-name/component-name)
- ...
:::
💬 Add additional necessary information, such as info or a caution box. If it is a repeating info box, etc., make it a component and reuse it.
## Input Variables
💬 If there are input variables, add the following introduction
This step contains some input variable(s). It needs these variable(s) to work. The table below gives an explanation for this variable(s).
💬 Add a screenshot link of the component input details page below the description.
💬 Include a table with these columns:
| Variable Name | Description | Status |
|----------------------------|----------------------------------------------------|-------------------|
| `$AC_INPUT_VAR_NAME` | Add an explanation. Include examples if necessary. | Required/Optional |
| ... | ... | ... |
## Output Variables
💬 If there are output variables, add the following introduction
The output(s) resulting from the operation of this component are as follows:
💬 Include a table with these columns:
| Variable Name | Description |
|-----------------------------|----------------------------------------------------|
| `$AC_OUTPUT_VAR_NAME` | Add an explanation. Include examples if necessary. |
| ... | ... |
💬 If there is no output variable, ignore this header. However, what the component provides as output can be added with a note box or info box.
---
💬 Include necessary information about the source code.
To access the source code of this component, use the following link:
https://github.com/appcircleio/appcircle-x-y-z-component.git
---
## FAQ
### How can I solve the `error message keywords`?
### **Problem Description**
Provide a brief and precise explanation of the error and the context in which it occurs.
### **Error Message Example (If there is)**
If the error message is specific, include it within code blocks for clarity.
### **Possible Causes**
List the possible root causes for the error if known.
### **Possible Solutions**
- Provide step-by-step solutions to resolve the issue.
- Include command-line examples or configuration file changes if needed.
### **Additional Tips (Optional)**
Mention helpful practices or additional checks.
```
Once you have filled out this template according to your workflow, you can submit your document for review.
:::warning Remove Comment Lines
Please do not forget to remove any comment lines starting with "💬".
:::
## 5. Create Content for the Integration Page
The newly added integration **must be listed on the Appcircle Integrations page** in the same format as existing integrations available at
[https://appcircle.io/integrations](https://appcircle.io/integrations)
To enable the relevant person on the **Appcircle** side to complete this addition, the integration content **must be included in the pull request**, either as
- A dedicated file, or
- A clearly formatted PR comment.
The content should strictly follow the structure below:
```md
# Integration Name
Short description of the integration and its purpose.
## Key Benefits
**Feature 1**: Description
**Feature 2**: Description
...
## Points to Consider
**Consideration 1**: Description
**Consideration 2**: Description
...
## FAQs
### Question 1
Answer
### Question 2
Answer
...
```
### Notes
* The **Integration Name** should be clear and consistent with the product or service name.
* Descriptions should be concise, technical, and user-focused.
* All sections are required to ensure consistency across the Integrations page.
## 6. Review & Deployment Process
After completing your step implementation and documentation, inform the Appcircle team. The team will review and test both the code and the documentation. During this process:
- **Code Review:** The team will evaluate your component's functionality, performance, and adherence to best practices.
- **Documentation Review:** All documentation will be checked for clarity, completeness, and consistency with existing standards.
- **Testing Phase:** Comprehensive testing will be conducted to ensure compatibility and reliability.
- **Communication:** You may be contacted for clarifications, additional information, or requested modifications.
### What to Expect
- **Response Time:** Initial review feedback is typically provided as soon as posible.
- **Collaboration:** Be prepared to iterate on feedback and make necessary adjustments.
- **Final Approval:** Once all requirements are met, your contribution will be approved for deployment.
---
**🎖️ Thank you for your contribution to the Appcircle community!**
We appreciate your effort in expanding our platform's capabilities and helping fellow developers succeed.
---
## What are Workflows and How to Use Workflows?
# What are Workflows and How to Use Them?
A workflow is a ladder of steps taken to build your applications.
Each step has a different purpose and the workflow can be customized by modifying step parameters and inputs, running custom scripts, or re-ordering steps.
Workflows allow you to have complete control on your build process and enhance it with third-party services and features.
:::caution
Please note that modifying workflow steps may cause your builds to fail, so utmost care is recommended when editing workflows.
:::
## [How to Create an Integration](/workflows/how-to-create-an-integration)
This guide explains the process of creating a new integration, including defining its purpose, configuring inputs and outputs, writing the necessary scripts or code, and integrating it into existing workflows for automation.
## [Common Integrations](/workflows/common-workflow-steps)
These steps are common across all build profiles regardless of the target OS and platform.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [iOS Specific Integrations](/workflows/ios-specific-workflow-steps)
These steps are specific to the iOS build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [Android Specific Integrations](/workflows/android-specific-workflow-steps)
These steps are specific to the Android build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [React Native Specific Integrations](/workflows/react-native-specific-workflow-steps)
These steps are specific to the React Native build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [Flutter Specific Integrations](/workflows/flutter-specific-workflow-steps)
These steps are specific to the Flutter build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
---
## App Center iOS Distribution
# App Center iOS Distrubiton
With this step, you can send your `IPA` and `dSYM` files to the [App Center](https://appcenter.ms/). For this, the step needs to be configured according to your App Center account.
### Prerequisites
Before running the **App Center iOS Distrubiton** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) | This step will build your application in ARM architecture and generate an `IPA` and `dSYM` file. |
:::caution
Note that if you do not use this step after the [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices), Appcircle will not find **IPA** and **dSYM** files to distribute to the **App Center**.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_APPCENTER_TOKEN` | You need to enter your **App Center Access Token** in this parameter. The CLI tool will be authenticated with this token. | Required |
| `$AC_APPCENTER_IPA_PATH` | Full path of the build. The path will be generated after the **Xcodebuild for Devices** step. You may enter the exact path of the `IPA` or the parent folder. | Required |
| `$AC_APPCENTER_OWNER` | Owner of the app. The app's owner can be identified in its URL, such as `https://appcenter.ms/users/JohnDoe/apps/myapp` for a user-owned app (where **JohnDoe** is the owner) and `https://appcenter.ms/orgs/Appcircle/apps/myapp` for an org-owned app (the owner is **Appcircle**). | Required |
| `$AC_APPCENTER_APPNAME` | The name of the app. The app's name can be identified in its URL, such as `https://appcenter.ms/users/JohnDoe/apps/myapp` for a user-owned app (where **myapp** is the app name) and `https://appcenter.ms/orgs/Appcircle/apps/myapp` for an org-owned app (the owner is **myapp**). | Required |
| `$AC_APPCENTER_GROUPS` | The group name parameter is the distribution of `Group Names` you opened in your App Center account. You can type in which group you want to send it to. | Optional |
| `$AC_APPCENTER_STORE` | Name of the store (App Store, Google Play, Intune). You can submit directly to this variable by giving one of the store names in your App Center account. | Optional |
| `$AC_APPCENTER_RELEASE_NOTES_PATH` | If you use the `Publish Release Notes` component before this step, release-notes.txt will be used as release notes. | Optional |
| `$AC_APPCENTER_UPLOAD_DSYM` | The user can decide whether to upload your `dSYM` file. This parameter uploads the `dSYM` file automatically. The default value is **true**. | Optional |
| `$AC_APPCENTER_MANDATORY` | This parameter specifies whether the update should be considered mandatory or not. The default value is **false**. | Optional |
| `$AC_APPCENTER_NOTIFY` | This parameter sends notifications to testers. The default value is **true**. | Optional |
| `$AC_APPCENTER_VERSION` | The latest version will be used if no version is set. | Optional |
| `$AC_APPCENTER_EXTRA` | Extra command line arguments for App Center. For example, add `--debug` for verbose logs. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-appcenter-distribute-component
---
## Appdome Build-2Secure for iOS
[Appdome Build-2Secure](https://apis.appdome.com/docs/integrate-in-cicd) automates the integration of advanced security features, adaptive protections, code-signing, and certification processes into mobile applications, enhancing security without the need for manual coding or code analysis.
For detailed information on the benefits that **Appdome Build-2Secure** adds to your mobile app, please refer to the following blog post:
https://appcircle.io/blog/elevate-your-mobile-app-security-with-appdome-integration
### Prerequisites
Before running the **Appdome Build-2Secure for iOS** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) | The app required for this step is generated by the **Xcodebuild for Devices** (or alternative build steps). |
:::danger
If a step other than the **Xcodebuild for Devices** step is used to build or sign the app, then the **Appdome Build-2Secure for iOS** step depends on this step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_APPDOME_IPA_PATH` | URL to app file (ipa) or an environment variable representing its path. For example: `$AC_EXPORT_DIR/.ipa`. | Required |
| `$AC_APPDOME_API_KEY` | This API key must be taken from the Appdome. Please follow the [Appdome documentations](https://apis.appdome.com/docs/getting-started#getting-and-resetting-your-appdomes-build2secure-api-token). | Required |
| `$AC_APPDOME_FUSION_SET_ID` | Fusion Set ID must be taken from the Appdome. | Required |
| `$AC_APPDOME_TEAM_ID` | Team ID must be taken from the Appdome. Please follow the [Appdome documantation](https://apis.appdome.com/docs/getting-started#getting-a-teams-id). | |
| `$AC_APPDOME_SIGN_METHOD` | Signing method for automatically sign applications using the Appdome service in accordance with Apple's guidelines. | Required |
| `$AC_APPDOME_IOS_ENTITLEMENTS` | Entitlements must be taken from the Xcode. You can separate entitlement files with commas. It must have `plist`, `txt` or `xml` file extension. | Required |
| `$AC_APPDOME_PROVISIONING_PROFILES` | Paths of the provisioning profiles. You can separate files with commas. It must have `mobileprovision` extension. | Required |
| `$AC_APPDOME_CERTIFICATES` | Paths of the certificate file. It must have `p12` extension. | |
| `$AC_APPDOME_CERTIFICATES_PASS` | iOS Certificate Password. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
:::caution
To view the output artifacts on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your workflow after this step.
:::
| Variable Name | Description | Status |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -------- |
| `AC_APPDOME_SECURED_IPA_PATH` | Local path of the secured `.ipa` file. Available when 'Signing Method' set to `On-Appdome` or `Private-Signing`. | Required |
| `AC_APPDOME_PRIVATE_SIGN_SCRIPT_PATH` | TLocal path of the `.sh` sign script file. Available when `Signing Method` set to `Auto-Dev-Signing`. | Required |
| `AC_APPDOME_CERTIFICATE_PATH` | Local path of the Certified Secure Certificate `.pdf` file. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-appdome-component
---
## Audit Permission Changes
This component captures and compares permission changes in your iOS projects.
The system conducts this check using a reference branch. First, run the pipeline containing this component on the branch you intend to use as a reference. Subsequently, when you run it on the branch you want to check, the system performs the control relative to this selected reference branch. When it detects a change in the project's permissions, Appcircle automatically stops the pipeline to ensure that no significant permission change goes unnoticed.
### Prerequisites
Before running the **Audit Permission Changes** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | You need to clone the repository to start the **Audit Permission Changes** step. After cloning, the system installs CocoaPods. After this step works, the variable `$AC_REPOSITORY_DIR` will be created. |
:::caution
The **Audit Permission Changes** component will automatically break the pipeline and halt operations if it detects a permission change. If you do not want this to occur, activate the **`'Continue with the next step even if this step fails'`** toggle within the step. This command will allow the pipeline to continue even if the step fails.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_REFERENCE_BRANCH` | Specifies the reference branch to check permissions. | Required |
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: `./appcircle.xcodeproj` | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-permission-check-component
---
## Azure Bot for Swiftlint
With the **Azure DevOps Bot for Swiftlint** integration, you can analyze your [**SwiftLint**](https://github.com/realm/SwiftLint/) and post the report details under the opened PR. You can also modify the PR status.
:::info
This component will work in builds that are automatically triggered by a configured trigger. To achieve this, you need to open a PR and set up the trigger. Further information for **Trigger Build**, please follow the [documantation](/build/build-process-management/build-manually-or-with-triggers/).
:::
:::caution
If there are warnings or errors in the SwiftLint report, this workflow step will fail and stop the build.
:::
:::danger
For this component to work, a PR must be opened, and a trigger must be set up based on this PR. If the build is triggered manually, the component will not function.
:::
### Prerequisites
Before running the **Azure Bot for Swiftlint** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Swiftlint**](/workflows/ios-specific-workflow-steps/swiftlint) | This component will check the source code for programmatic as well as stylistic errors. This is helpful in identifying some common and uncommon mistakes that are made during coding. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_LINT_PATH` | This is the Swiftlint report path, this path will being automatically generated, if Swiftlint step runs. | Required |
| `$AC_AZURE_ORG_NAME` | Specifies the name of the Azure DevOps organization. You can find it in the Azure DevOps URL: `https://dev.azure.com/{Your_Organization}`. Check out [this document](https://learn.microsoft.com/en-us/answers/questions/1080972/find-organization-name) to locate the organization name. | Required |
| `$AC_AZURE_PROJECT_NAME` | Specifies the name of the Azure DevOps project. You can find it in the Azure DevOps URL: `https://dev.azure.com/{Your_Organization}/{Your_Project}`. For more information about Azure DevOps projects, refer to [this document](https://learn.microsoft.com/en-us/azure/devops/user-guide/project-admin-tutorial?toc=%2Fazure%2Fdevops%2Forganizations%2Ftoc.json&view=azure-devops). | Required |
| `$AC_AZURE_REPO_NAME` | Specifies the name of the Azure DevOps repository. Check out [this document](https://learn.microsoft.com/en-us/azure/devops/repos/git/repository-settings) for more details about Azure DevOps repositories. | Required |
| `$AC_AZURE_BASE_URL` | Specifies the base URL of Azure DevOps. The default value is `https://dev.azure.com`. | Required |
| `$AC_AZURE_API_KEY` | Specifies the API key for Azure DevOps. Refer to [this document](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate) for details on how to obtain it. | Required |
| `$AC_DOMAIN_NAME` | Specifies the domain name of Appcircle. The default value is `my.appcircle.io`, which is the domain for Appcircle Cloud. | Required |
| `$AC_AZURE_API_VERSION` | Specifies the version of the Azure API, for example: `7.1`. Refer to the [REST API versioning](https://learn.microsoft.com/en-us/azure/devops/integrate/concepts/rest-api-versioning) document for more information. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-azure-bot-for-swiftlint-component
---
## BrowserStack App Automate
# BrowserStack App Automate (XCUI)
Run your [**XCUI**](https://developer.apple.com/documentation/xctest) tests on [**BrowserStack**](https://www.browserstack.com) App Automate. This step allows you to send test IPA's to the **BrowserStack** dashboard and run your test on it.
### Prerequisites
Before running the **BrowserStack App Automate (XCUI)** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) | After the [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) step runs, the test IPA paths (`$AC_TEST_IPA_PATH` and `$AC_UITESTS_RUNNER_PATH`) will be created automatically. So that the **BrowserStack** component depends on these paths. |
:::danger
In the build step, if there is no **Xcodebuild Build for Testing** step before **BrowserStack**, **BrowserStack** will throw an **error** and **break the pipeline** because it cannot find the paths that your step depends on.
:::
### Input Variables
The output(s) resulting from the operation of this component are as follows:
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_BROWSERSTACK_USERNAME` | Username of the **BrowserStack** account. It should come from the **BrowserStack** account. | Required |
| `$AC_BROWSERSTACK_ACCESS_KEY` | Access key for the **BrowserStack** account. It should come from the **BrowserStack** account. For more information, please follow [this document](https://www.browserstack.com/docs/iaam/security/manage-access-keys). | Required |
| `$AC_TEST_IPA_PATH` | Full path of the IPA file. This path will automatically generate in [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) step.| Required |
| `$AC_UITESTS_RUNNER_PATH` | Full path of the *-Runner.app. This path will automatically generate in [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) step. | Required |
| `$AC_BROWSERSTACK_PAYLOAD` | `$AC_BROWSERSTACK_APP_URL` and `$AC_BROWSERSTACK_TEST_URL` will be auto generated. Please check the [documentation](https://www.browserstack.com/docs/app-automate/api-reference/xcuitest/builds#execute-a-build) for more details about the payload. | Optional |
| `$AC_BROWSERSTACK_TIMEOUT` | **BrowserStack** plans a timeout in seconds. If there is any problem in BrowserStack, these variables will break the pipeline after a certain time. The default variable is **600 seconds**. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-browserstack-xcui-component
---
## Carthage
[Carthage](https://github.com/Carthage/Carthage) is a dependency manager for Swift and Objective-C applications. [Carthage](https://github.com/Carthage/Carthage) handles the installation of external libraries your application depends on during a build.
[Carthage](https://github.com/Carthage/Carthage) is widely used among iOS developers for dependency management, and it's very easy to include it in your iOS projects with Appcircle.
### Prerequisites
Before running the **Carthage** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step clones your git repo on the runner where the build process will take place so that the necessary workflow operations can be performed. |
:::caution
Appcircle will look for a [`Cartfile`](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md) file in your repository and use it to install the dependencies. For this reason, **it should be used after the Git Clone step**.
:::
### Input Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_CARTHAGE_COMMAND` | Specifies the Carthage command to run. Defaults to `bootstrap`. **Possible values:** `bootstrap`, `update`. | Required |
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after [**Git Clone**](/workflows/common-workflow-steps/git-clone).| Optional |
| `$AC_CARTFILE_PATH` | Specifies the path where the Cartfile resides. Defaults to the repository directory. **DO NOT** include Cartfile, this is only the path. **This value will be appended** to `$AC_REPOSITORY_DIR`. **Example:** `./` or `./subpath-to-cartfile/`. | Optional |
| `$AC_CARTHAGE_FLAGS` | Specifies additional flags after the Carthage command. The default value is empty. **For Xcode 12 and above, make sure to include** `--use-xcframeworks` **here**. To shorten the build time, make sure to specify the platform: `--platform iOS`. Example usage: `--platform iOS --use-xcframeworks`. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-carthage-component
---
## CocoaPods Deintegrate
The CocoaPods Deintegrate component removes all dependencies from your project using the `pod deintegrate` command, providing a clean environment for building.
You can easily integrate the Appcircle CocoaPods Deintegrate workflow step into your pipeline and utilize it in your projects.
### Prerequisites
Before running the **CocoaPods Deintegrate** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The repo needs to be cloned in order to start the CocoaPods Deintegrate process. After the clone, Fastlane will be installed. After this step works, the variable `$AC_REPOSITORY_DIR` will be created.|
:::caution
Please remember to use the [**CocoaPods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) step after this component, as it clears all dependencies in the project.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_XCODEPROJ_PATH` | Specifies the project path. For example: `./appcircle.xcodeproj`. Empty value will look for an `.xcodeproj` file. | Optional |
| `$AC_REPOSITORY_DIR` | Specifies the directory where the repository is cloned. This path is generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Optional |
| `$AC_COCOAPODS_VERSION` | Specifies the CocoaPods version. If you need a specific version, provide it here as hardcoded, and the system will automatically install that version. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-cocoapods-deintegrate-component
---
## Cocoapods Install
Runs the [CocoaPods](https://cocoapods.org) install command for dependency management. This step installs all pod dependencies. Appcircle uses the `pod install` command to install pods in the project. This command comes from the CocoaPods tool installed on the system. If a version is not specified for CocoaPods, this step will use the version of [**CocoaPods installed**](/infrastructure/ios-build-infrastructure#ios-build-environment) on the system.
### Prerequisites
Before running the **Cocoapods Install** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The repo needs to be cloned in order to start the CocoaPods installation process. After the clone, CocoaPods will be installed. After this step works, the variable `$AC_REPOSITORY_DIR` will be created. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ----------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: `./appcircle.xcodeproj`. If you filled in **`Configuration => Project or Workspace`**, this variable comes from [Configuration](/build/build-process-management/configurations). | Required |
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_COCOAPODS_VERSION` | Specifies the CocoaPods version. If there is a specific version you want to use, give it here as hardcoded, and the system will automatically install the given version. | Optional |
:::info
Please note that the **CocoaPods Install** step uses the default system [**CocoaPods version**](/infrastructure/ios-build-infrastructure#ios-build-environment). If you want to use a specific version, please enter it hardcoded in the CocoaPods Version parameter in the step.
:::
:::danger
Remember, if the project extension is not **.xcworkpace**, the pod install step will not work as expected. In the Configuration tab, make sure that the extension in the project path is **.xcworkspace**.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-cocoapods-component
---
## FAQ
### How do I manage iOS dependencies with artifactory repository manager?
Integrating an Artifactory repository manager into your iOS build process is a robust approach to centralizing dependency management, improving build reliability, and ensuring reproducibility. Below, we’ll demonstrate this process using **Sonatype Nexus Repository Manager** as an example in conjunction with the Appcircle **CocoaPods Install** workflow step. Please ensure your Sonatype Nexus Repository Manager is properly installed and configured. For more information, please visit the [official Sonatype Nexus documentation](https://help.sonatype.com/repomanager3).
:::info Supported Frameworks
Sonatype Sonatype Nexus only supports **CocoaPods** for iOS. There is no support for [**Carthage**](https://github.com/Carthage/Carthage) and [**SPM (Swfit Package Manager)**](https://www.swift.org/documentation/package-manager/).
For more information about supported frameworks, please visit [**Sonatype Sonatype Nexus Repository documentation**](https://help.sonatype.com/en/formats.html).
:::
:::tip Artifactory Management for SPM
Since Sonatype Nexus does not yet support **SPM**, it is **not** possible to manage SPM packages using Nexus.
For users with a Nexus infrastructure, an alternative approach to centralize and fetch SPM packages is to collect all SPM packages in a private Git repository. This way, all SPM packages are pulled only from a repository accessible to the user and included in the build process.
**Note**: With this method, the **SPM** packages collected in a single repository must be regularly checked and updated to ensure they remain up to date.
:::
:::caution Configure Sonatype Nexus Repository Authentication
If [anonymous access option](https://help.sonatype.com/en/anonymous-access.html) is turned off in Sonatype Nexus repository, you need to authenticate to the repository with the [**Authenticate with Netrc**](/workflows/common-workflow-steps/authenticate-with-netrc) step or by using a [**Custom Script**](/workflows/common-workflow-steps/custom-script). If Custom Script is used, you can use the bash script given below.
For more information, please visit the [**Sonatype Nexus Authentication documentations**](https://help.sonatype.com/en/cocoapods-repositories.html#configure-nexus-repository-authentication).
```bash
$cat ~/.netrc
machine https://Sonatype Nexus.example.com/repository/cocoapods-specs.git
login admin
password admin123
```
:::
For more information about Sonatype Nexus integration with CocoaPods, please visit the [Sonatype Nexus CocoaPods documentations](https://help.sonatype.com/en/cocoapods-repositories.html).
#### Example 1: How can I fetch the all dependencies from Sonatype Nexus with CocoaPods?
In the **CocoaPods Install** step, in order to pull dependencies from Sonatype Nexus or another artifactory, you need to make some changes in the `Pods` file. For this, the `source url` value of the `Pods` file in the project must be replaced with the relevant artifactory. A short example is shown in the following bash script.
For detailed server-side configuration steps, you can refer to [Appcircle’s Sonatype Nexus configuration guide](/self-hosted-appcircle/install-server/linux-package/configure-server/external-image-registry#sonatype-nexus-configuration).
:::info SSL Configuration
If you are using a self-signed SSL certificate, ensure that curl can work with it properly. Since the CocoaPods client uses the curl command to download Pod files from Nexus Repository, you can configure curl by adding the `--insecure` option to the .curlrc file in your home directory. If the file does not exist, simply create it. Example:
```bash
$cat ~/.curlrc
--insecure
```
For detailed information, please visit the [**Sonatype Nexus SSL Configuration documentations**](https://help.sonatype.com/en/cocoapods-repositories.html#configure-ssl).
:::
```bash
platform :ios, '13.0'
source 'https://Sonatype Nexus.example.com/repository/cocoapods-specs.git'
target 'MyApp' do
use_frameworks!
pod 'AFNetworking', '~> 4.0'
pod 'Alamofire', '~> 5.4'
end
.
.
. #Other Pod file codes
```
#### Example 2: How can I fetch some dependencies from different repositories?
If you want to fetch a dependency from a source other than this artifactory, you can set up your `Pod` file as shown below. This `Pod` file will pull any pods that are explicitly referenced from the specified URL, while all other dependencies will be retrieved directly from the default `source URL`.
```bash
platform :ios, '13.0'
source 'https://Sonatype Nexus.example.com/repository/cocoapods-specs.git'
target 'MyApp' do
use_frameworks!
pod 'AFNetworking', '~> 4.0'
pod 'Alamofire', '~> 5.4'
pod 'MyPrivatePod', :git => 'https://git.mycompany.com/MyPrivatePod.git', :branch => 'main'
end
.
.
. #Other Pod file codes
```
After these changes;
- Trigger your build through Appcircle. The workflow will fetch dependencies from the Sonatype Nexus repository as configured and compile the project with them.
- Logs will show dependency resolution status to confirm successful integration with Sonatype Nexus.
### How do I troubleshoot CocoaPods Install step errors, such as builds getting stuck, failing with exit code ***37, or working intermittently?
#### Option 1: Using Cache Push and Pull in Build Pipelines (Recommended)
CocoaPods caches are compatible with Appcircle's [Cache Push](/workflows/common-workflow-steps/build-cache/cache-push) and [Cache Pull](/workflows/common-workflow-steps/build-cache/cache-pull) steps.
When you add the **Cache Push** step to the pipeline, it stores CocoaPods dependencies so they can be restored in future builds with **Cache Pull**, avoiding potential network access issues.
This also reduces the duration of the **CocoaPods Install** step, since dependencies no longer need to be fetched from the internet.
#### Option 2: Using Appcircle's Nexus Server for Specific Dependencies
For dependencies that cause issues (for example, `Mapbox-iOS-SDK`), you can [configure your Podfile](/workflows/ios-specific-workflow-steps/cocoapods-install#example-2-how-can-i-fetch-some-dependencies-from-different-repositories) to fetch them from the Appcircle Nexus server instead of the default source.
---
## Convert Xcresult to HTML/XML
After the [**Xcodebuild for Unit and UI Tests**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) step runs, it generates a `test_result.xcresult` file. In specific cases, this test file must be converted to another format. The **Convert Xcresult to HTML/XML** step is used for converting this test file to `HTML` and `XML` formats.
### Prerequisites
Before running the **Convert Xcresult to HTML/XML** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Unit and UI Tests**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) | This step allows you to run unit and UI tests on your project. After this step runs, the related path, `$AC_TEST_RESULT_PATH` will be generated automatically. |
:::caution
Please note that if you do not run **Xcodebuild for Unit and UI Tests** before this step, the step will produce an error because there will be no test result file to convert.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|-------------------------------------|------------------|
| `$AC_OUTPUT_DIR` | Specifies the path for outputs for generated artifacts. This path will be automatically defined. Do not change if it is not necessary. | Required |
| `$AC_TEST_RESULT_PATH` | This directory will be used for converting from `Xcresult` to `HTML` or `XML`. | Required |
| `$AC_CONVERT_FILE_NAME` | The name of the converted test result file. This will be the new filename for the result file. | Required |
| `$AC_CONVERT_TYPE` | Specify the convert-type option. Which type should it be converted to? The options are `XML` and `HTML`. The default value is `XML`. | Required |
| `$AC_INCLUDE_COVERAGE` | If set to `Yes`, it will include the coverage result in the converted file. The default value is `No`. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|-------------------------------------|
| `AC_CONVERTED_TEST_RESULT_PATH` | Specifies the path where the converted result is stored. Users can access this path via this variable. Additionally, it will be available for download in the [**Download Artifact**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) section. |
:::caution
To view the converted test reports on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your workflow after this step.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-xcresult-convert-html-xml-component
---
## Firebase Upload dSYM
This step allows to upload your debug symbols to [**Firebase Crashlytics**](https://firebase.google.com/docs/crashlytics/get-deobfuscated-reports?hl=tr&platform=ios).
### Prerequisites
Before running the **Firebase Upload dSYM** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) | This step will build your application, create an Archive file, and generate `.ipa`. The Archive file contains the `.dSYM` file. Please use **Firebase Upload dSYM** step after this step. |
:::danger
If this step is not used after **Xcodebuild for Devices**, the pipeline will give error. Because the dSYM file is generated after the project is archived.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_FIREBASE_PLIST_PATH` | The path of the **GoogleService-InfoPlist** file must be defined. In the project, wherever your GoogleService-InfoPlist file is, type that path directly without any characters at the beginning. Appcircle will automatically fill the beginning of the path with the repository path. For example, **`GoogleService-InfoPlist`** or **`services/GoogleService-InfoPlist`**. | Required |
| `$AC_FIREBASE_CRASHLYTICS_PATH` | This path parameter specifies the path of the generated dSYM file. | Required |
:::info
Crashlytics paths change depending on the platform. According to the mobile application platform you are working on, you need to provide one of the following paths here.
| Project Type | Crashlytics Paths for Platforms |
|----------------------|-------------------------------------------------------------------------------------------------------------------|
| Native iOS CocoaPods | $AC_REPOSITORY_DIR/Pods/FirebaseCrashlytics/upload-symbols |
| Native iOS SPM | $HOME/Library/Developer/Xcode/DerivedData/**/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols |
| React Native iOS | $AC_REPOSITORY_DIR/ios/Pods/FirebaseCrashlytics/upload-symbols |
| Flutter iOS | $AC_REPOSITORY_DIR/ios/Pods/FirebaseCrashlytics/upload-symbols |
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-firebase-dsym-upload-component
---
## iOS Specific Workflow Steps
The steps listed below are specific to the iOS build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [App Center iOS Distribution](/workflows/ios-specific-workflow-steps/appcenter-ios-distribution)
Distribute IPA and dSYM files to [App Center](https://appcenter.ms/). You need enter your token, owner, app and group names to distribute your binaries.
## [Appdome Build-2Secure for iOS](/workflows/ios-specific-workflow-steps/appdome-build-to-secure-for-ios)
Appdome Build-2Secure is a comprehensive automated solution that seamlessly integrates advanced security features, adaptive protections, code-signing, and certification processes into mobile applications, enhancing security without the need for manual coding or code analysis.
For detailed information on the benefits Appdome Build-2Secure adds to your mobile app, refer to the blog post:
[https://appcircle.io/blog/elevate-your-mobile-app-security-with-appdome-integration](https://appcircle.io/blog/elevate-your-mobile-app-security-with-appdome-integration)
## [Audit Permission Changes](/workflows/ios-specific-workflow-steps/audit-permission-change)
This component captures and compares permission changes in your iOS projects.
## [Azure Bot for SwiftLint](/workflows/ios-specific-workflow-steps/azure-bot-for-swiftlint)
This step integrates Azure Bot with SwiftLint to provide feedback on code quality.
## [BrowserStack App Automate - XCUI](/workflows/ios-specific-workflow-steps/browserstack-app-automation)
Run your XCUI tests on BrowserStack App Automate. You need to add **Xcodebuild Build for Testing** before this step to create the required `$AC_TEST_IPA_PATH` and `$AC_UITESTS_RUNNER_PATH` files.
## [Carthage](/workflows/ios-specific-workflow-steps/carthage)
Runs the Carthage bootstrap/update command for dependency management.
## [CocoaPods Deintegrate](/workflows/ios-specific-workflow-steps/cocoapods-deintegrate)
This step runs the `pod deintegrate` command to remove CocoaPods from the project.
## [Cocoapods Install](/workflows/ios-specific-workflow-steps/cocoapods-install)
Runs the Cocoapods install command for dependency management.
## [Convert Xcresult to HTML/XML](/workflows/ios-specific-workflow-steps/convert-xcresult-to-xml-html)
This step converts Xcresult files to HTML or XML format.
## [Firebase Upload dSYM](/workflows/ios-specific-workflow-steps/firebase-upload-dsym)
Upload your debug symbols to Firebase Crashlytics
## [Install Certificates and Profiles](/workflows/ios-specific-workflow-steps/install-certificates-provisions)
This step installs the selected certificates and the provisioning profile for the build.
## [iOS Increment Build and Version](/workflows/ios-specific-workflow-steps/ios-increment-build-and-version-number)
This step increments the build number and version number of the iOS project.
## [Slather](/workflows/ios-specific-workflow-steps/slather)
This step converts Xcode's test results to different formats by using [Slather](https://github.com/SlatherOrg/slather/). This workflow must be run **after** [Xcodebuild for Unit and UI Tests](#xcodebuild-for-unit-and-ui-tests) step.
## [SwiftLint](/workflows/ios-specific-workflow-steps/swiftlint)
This step installs [SwiftLint](https://github.com/realm/SwiftLint/) and runs swiftlint with given options.
## [Test Reports for iOS](/workflows/ios-specific-workflow-steps/test-reports-for-ios)
This component provides detailed reports and insights on the results of iOS app tests conducted.
For detailed information on the usage of **Test Reports for iOS**, please refer to the documentation:
- [Generating Test Report](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests#generating-test-report)
## [Tuist Commands](/workflows/ios-specific-workflow-steps/tuist-commands)
This step runs specific [Tuist Commands](https://docs.tuist.io/en/cli/auth) such as `tuist build` or `tuist test`.
## [Tuist Install](/workflows/ios-specific-workflow-steps/tuist-install)
This step installs [Tuist](https://tuist.io/) and runs `tuist generate` with given options.
## [Xcode Select (Version)](/workflows/ios-specific-workflow-steps/xcode-select)
This step is used to specify the Xcode version to be used during the build process.
:::info
### Pool-Based Xcode Version Selection
A version other than the Xcode versions on the configuration page should not be entered manually as the Xcode select workflow argument.
Because the Xcode versions on the configuration page are the versions installed on runners.
Entering an unavailable Xcode version may cause the build to fail.
You can review the documentation for detailed information about the Xcode version selection [here](/self-hosted-appcircle/self-hosted-runner/configure-runner/manage-pools/#pool-based-xcode-version-selection).
:::
## [Xcodebuild for Devices (Archive & Export)](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices)
This step builds your application for iOS devices in ARM architecture, which is required for the [**Share With Testers**](/testing-distribution/create-or-select-a-distribution-profile) feature or any other means of iOS distribution.
## [Xcodebuild for iOS Simulator](/workflows/ios-specific-workflow-steps/xcodebuild-for-ios-simulator)
This step builds your application for the iOS Simulator in x86_64 or arm64 architecture. This step creates an unsigned `xarchive` file. You may also optionally install the application for given simulator.
## [Xcodebuild for Testing](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing)
This step builds your application for testing.
## [Xcodebuild for Unit and UI Tests](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test)
This step performs unit and UI tests for your iOS applications. This does not "build" your app, but uses the "xcodebuild" command to run tests. To build your app for testing, please refer to the previous workflow step.
---
## Install Certificates and Provisioning Profiles
This step installs the specified [certificate](https://developer.apple.com/support/certificates/) and [provisioning profile](https://developer.apple.com/help/account/manage-profiles/create-a-development-provisioning-profile/) files to sign the project.
For more detailed information on **iOS Certificates and Provisioning Profiles**, please refer to [this document](/signing-identities).
### Prerequisites
Before running the **Install Certificates and Provisioning Profiles** step, you must complete certain prerequisites, as detailed in the table below:
:::info
If you are using an automatic code sign, you can remove this step. Since automatic code signing is managed by Xcode, this step will not be needed.
:::
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | Clone your repository to the runner machine. Use the Install Certificates and Provisiong Profiles step after this step. This step will clone your repository to be able to use provisioning profiles and certificates. |
:::danger
Please remember. If you are using **manual sign**, you should definitely use this step and run it after the **Git Clone** step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|-------------|
| `$AC_CERTIFICATES` | Concatenated strings of `cert_pass`\|`cert_path` combined with a pipe ('\|') character that have the paths of the certificates and their passwords if they exist. For instance, when we have two certificates A and B that require passwords, then it should be like '`a_cert_pass`\|`a_cert_path`\|`b_cert_pass`\|`b_cert_path`'. If there is no password, its field will be empty, like '\|`a_cert_path`'. | Required |
| `$AC_PROVISIONING_PROFILES` | Paths of the provisioning profiles. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `AC_KEYCHAIN_PATH` | A path is created after the certificate is added to the current runner's keychain. |
| `AC_KEYCHAIN_PASSWORD` | After this certificate is added to the keychain, the password assigned to the keychain. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-install-certificates-and-profiles-component
---
## iOS Increment Build and Version Number
The **iOS Increment Build and Version Number** step is controlled by **iOS Versioning**. For detailed information about this step, including [**Prerequisites**](/versioning/ios-version#enabling-version-management), [**Input Variables**](/versioning/ios-version#input-variables), and [**Output Variables**](/versioning/ios-version#output-values), please refer to the documentation below:
- [**Understanding iOS Versioning**](/versioning/ios-version)
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-build-version-increment
---
## Slather
This step converts Xcode's test results to different formats by using [**Slather**](https://github.com/SlatherOrg/slather/). You can convert your test coverage results, such as `cobertura`, `JSON`, etc.
### Prerequisites
Before running the **Slather** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step will clone your repository. After this step works, the variable `$AC_REPOSITORY_DIR` will be created. This variable is the required input variable for **Slather**. |
| [**Xcodebuild for Unit and UI Tests**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) | This step executes your unit and UI tests, generating a `.xcresult` file. This file serves as the mandatory test result input for **Slather**. |
:::danger
**Slather** component needs test results in `.xcresult` format to work. Therefore, make sure that the tests of the project are run. Otherwise, **Slather** will throw an error for not finding the file and the pipeline will break.
:::
## Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------|--------------------------------------|----------------------------------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. It's generated after the **Git Clone** step. | Required |
| `$AC_TEST_RESULT_PATH` | This is the path of **`.xcresult`** file. It will be generated after the [**Xcodebuild for Unit and UI Test**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) step. | Required |
| `$AC_SCHEME` | Specifies the project scheme for build. If you filled in `Config => Build Schema` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: **`./appcircle.xcodeproj`**. If you filled in `Config => Xcode Project or Workspace Path` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). But if you have a different location, specify this parameter. | Required |
| `$AC_WORKSPACE_PATH` | Specifies the workspace path. For example : **`./appcircle.xcworkspace`**. If you filled in `Config => Xcode Project or Workspace Path` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). But if you have a different location, specify this parameter. | Optional |
| `$AC_COVERAGE_FORMAT` | Exported coverage format. You can change the output format of the coverage test results for Slather with the **Coverage Type** variable. The default value is **cobertura**. | Optional |
| `$AC_CONFIGURATION_NAME`| If you have a configuration that you want to specify while **Slather** is running, you can add it to the command line with the **Configuration** parameter. | Optional |
| `$AC_SLATHER_OPTIONS` | If you want to add an extra command to the command line, you can do it with the **Extra Option** variable. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-slather-component
---
## SwiftLint
SwiftLint checks the source code for programmatic as well as stylistic errors. This is helpful in identifying some common and uncommon mistakes that are made during coding. This step installs [SwiftLint](https://github.com/realm/SwiftLint/) and runs SwiftLint with the given options.
### Prerequisites
Before running the **SwiftLint** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | This step will clone your repository. After this step works, the variable `$AC_REPOSITORY_DIR` will be created. This variable is the required input variable for **SwiftLint**. |
| [**Cocoapods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install)| This step will install the dependencies in the project before **SwiftLint** can run. |
:::danger
If you are using **CocoaPods**, note that this step is dependent on the [**CocoaPods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) step. Otherwise, the **SwiftLint** component will **fail**, and the **pipeline will break.**
:::
:::caution
If you are using **Swift Package Manager (SPM)**, do not use this step. SPM packages will be compiled in other steps that work with **Xcode**, such as [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices).
If you have SPM in your project and you are using the **SwiftLint** component in your workflow, the Linter component will give an error because it cannot find the required dependencies.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. | Required |
| `$AC_LINT_PATH` | This is the path of SwiftLint dependency. It comes from the Xcode Build Phase section. | Optional |
| `$AC_LINT_RANGE` | With the Range option, you can run SwiftLint on your entire project or only on changes in PR. Default is **all**. | Optional |
| `$AC_LINT_CONFIG` | Specifies the linting configuration file. For example: `/.swiftlint.yml` | Optional |
| `$AC_LINT_REPORTER` | You can change the report type with the `Reporter Format` option. This option supports extensions such as **`html`**, **`json`**, **`junit`**, etc. The default is **Xcode**. | Optional |
| `$AC_LINT_STRICT` | If there is a failure in the running lint, you can break the pipeline with the **Strict** option. The default value is `NO`. | Optional |
| `$AC_LINT_QUIET` | If you want the logs to be simpler, you can make the report file simpler with the **Quiet Mode** feature. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `AC_LINT_OUTPUT_PATH` | The path of the SwiftLint results output file. After **SwiftLint** runs, all results will be written in a `.txt` file. It can be found in the download artifacts. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-swiftlint-component
---
## Test Reports for iOS
The Appcircle **Test Report** step displays your test results and code coverage in an aesthetically pleasing user interface.
This component supports the following test and coverage formats:
- [Xcode 13+ XCTest](https://developer.apple.com/documentation/xctest) - For Apple's native test framework.
- [JUnit](https://junit.org) - For Java-based test reporting.
- [Cobertura](https://cobertura.github.io/cobertura) - For coverage reporting.
- [lcov.info](https://lcov-viewer.netlify.app) - For GCC coverage data.
For additional details, please refer to the document: [**Generating Test Report**](/continuous-testing/ios-testing/running-ios-unit-and-ui-tests#generating-test-report)
### Prerequisites
Before running the **Test Reports for iOS** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------- |
| [**Xcodebuild for Unit and UI Test**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) | Run unit and UI tests in your project to generate an `.xcresult` file containing the test outcomes. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ------------------------ | ---------------------------------------------------------------- | --------- |
| `$AC_TEST_RESULT_PATH` | Define the directory and its subdirectories for searching compatible test files. | Required |
| `$AC_COVERAGE_RESULT_PATH`| For native iOS projects, tests automatically set this variable. For other projects, you must specify the coverage path manually. | Optional |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------- | ---------------------------------------------------- |
| `AC_TEST_REPORT_JSON_PATH` | Specifies the path of the JSON report. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-test-report-component
---
## Tuist Commands
[**Tuist Commands**](https://docs.tuist.io/cli/auth) component is a component where you can run Tuist specific commands using the [**Tuist CLI**](https://docs.tuist.io/).
You can seamlessly integrate Tuist Commands into your workflow with Appcircle, making setup and utilization within your existing development processes easy.
### Prerequisites
Before running the **Tuist Commands** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | You need to clone the repository to start the Tuist Commands process. After cloning, it creates the `$AC_REPOSITORY_DIR` variable, and the system is able to run the **Tuist Commands**. |
| [**Tuist Install**](/workflows/ios-specific-workflow-steps/tuist-install) | You need to install the Tuist to start the **Tuist Commands** step. |
:::caution Tuist Commands
Tuist must be installed in order to use the **Tuist Commands** component. Tuist is a tool that can execute many **Xcode commands** on its own. For this reason, when certain commands are used, Appcircle's other iOS specific components will not be needed. For example, Workflow will no longer need the [**Xcodebuild for devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices) step when using the `tuist build` command.
The same applies to the `tuist test` command. For example, if you run your tests with `tuist test` command, you will not need [**Xcodebuild for Unit and UI Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test) and [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing) steps in the workflow.
For more information about Tuist CLI Commands, please visit the [**Tuist CLI**](https://docs.tuist.io/cli/auth) documentation.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_TUIST_PATH` | Specifies the path to the directory containing the project definition. This path is automatically generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_TUIST_COMMANDS` | Specifies the Tuist commands to be able to run specific Tuist commands. For example; `tuist test` or `tuist build`. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-tuist-commands-component
---
## Tuist Install
[**Tuist**](https://docs.tuist.io/) is a command-line tool that abstracts the intricacies of Xcode projects through project generation. It serves as a foundation to help teams maintain and optimize their large modular projects.
You can seamlessly integrate Tuist Install into your workflow with Appcircle, making setup and utilization within your existing development processes easy.
:::info
Tuist CLI tool is a tool that enables different actions to be performed in the project with different commands. The **Tuist Install** step only installs Tuist and runs the `tuist generate` command to generate the project. On the other hand, if you want to run other commands that Tuist has, please visit the [**Tuist Commands**](/workflows/ios-specific-workflow-steps/tuist-commands) step document.
:::
### Prerequisites
Before running the **Tuist Install** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | You need to clone the repository to start the Tuist process. After cloning, the system installs Tuist and creates the `$AC_REPOSITORY_DIR` variable. |
:::caution Tuist Usage
Appcircle's Tuist Install component generates your project using only the `tuist generate` command. This means that it will automatically generate the `.xcworkspace` and `.xcodeproj` files in the project after the tuist generate command runs. Note that if you use **Tuist Install** in the Appcircle pipeline and want to generate an **IPA** file, you need the other build steps, such as
- [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices)
- [**Xcodebuild for iOS Simulator**](/workflows/ios-specific-workflow-steps/xcodebuild-for-ios-simulator)
- [**Xcodebuild for Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-testing)
- [**Xcodebuild for Unit and UI Testing**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test)
- [**Cocoapods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install)
For more iOS specific workflow steps, please visit the [**iOS Integration**](/workflows/ios-specific-workflow-steps) documentation.
:::
:::danger
In Tuist integrated projects, there will be cases where `.xcworkspace` and `.xcodeproj` files will be created after the `tuist generate` command. For this reason, the **auto fill** feature in the **build configuration** may not work as expected. For more information about build configurations, please visit the [**Build Configurations**](/build/build-process-management/configurations) documentation.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::tip Tuist Version
In some projects, the version of Tuist that needs to be installed and used can be integrated **into the project** with the `.tuist-version` file. If you have a project with **Tuist** version integrated in this way, Appcircle will **not detect** the Tuist version in the project, so if there is a **specific** Tuist version you want to install, you **must** enter this version in the **Tuist Version** input field in the step.
:::
:::caution Tuist Install
Appcircle uses homebrew as [installation method](https://docs.tuist.io/en/guides/quick-start/install-tuist) in **Tuist Install** step, therefore only compatible versions are supported. For more information, please check this [list](https://github.com/tuist/homebrew-tuist/tree/main/Formula) for compatible versions of Tuist.
For this reason, iOS apps using Tuist versions `1.x` or `2.x` are not supported with Appcircle's Tuist Components.
:::
| Variable Name | Description | Status |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_TUIST_PATH` | Specifies the path to the directory containing the project definition. This path is automatically generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_TUIST_VERSION` | Specifies the Tuist version. If not specified, the latest version of Tuist will be installed. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-tuist-component
---
## Xcode Select
# Xcode Select (Version)
This step is used to specify the Xcode version to be used during the build process. All available versions of Xcode can be seen in the [Configuration](/build/build-process-management/configurations) tab.
### Prerequisites
There are no prerequisites required before using the **Xcode Select** step.
:::danger
Always use this step **before** [**CocoaPods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) and [**Xcodebuild for Devices**](/workflows/ios-specific-workflow-steps/xcodebuild-for-devices). If you have other **Xcode related** steps, such as [**Xcodebuild for iOS Simulators**](/workflows/ios-specific-workflow-steps/xcodebuild-for-ios-simulator) and [**Xcodebuild for Unit and UI Tests**](/workflows/ios-specific-workflow-steps/xcodebuild-for-unit-and-ui-test), **don't forget** to use before them.
:::
:::caution
Please **don't forget** to select the **Xcode version** from [Configuration](/build/build-process-management/configurations) first.
:::
### Version Change
- To select an Xcode version, open [Configuration](/build/build-process-management/configurations) in the build profile.
- After opening the configuration, you will see the **Xcode Version** section. Now you can select a version for Xcode.
:::info
Appcircle provides new versions of Xcode (including beta versions) within 24 hours after they are released.
:::
:::info Manually Xcode Version Change (Not Recommended)
In addition to the version change method described above, you can also change the Xcode version **manually**. For this, you can **hard-code** the desired Xcode version into the `$AC_XCODE_VERSION` parameter, which serves as the input for the **Xcode Select** step. For example: `15.1`.
Please note that, if the version you hard-coded is not available on the runner where the build will run, the build **will not** start. The [**Build Configuration**](/build/platform-build-guides/building-ios-applications#build-configuration) always lists the **available** Xcode versions.
For more information, please visit our [**iOS Build Stacks**](/infrastructure/ios-build-infrastructure#available-xcode-versions) documentation.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_XCODE_LIST_DIR` | Specifies the directory with the Xcode versions. Xcode versions are located under the `/Volumes` directory and selected according to the given version. | Required |
| `$AC_XCODE_VERSION` | Specifies the xcode version. This variable comes from Configuration. | Required |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-xcode-select-component
---
## Xcodebuild for Devices (Archive & Export)
This step builds your application for iOS devices in ARM architecture, which is required for the [**Sharing With Testers**](/testing-distribution/create-or-select-a-distribution-profile) feature or any other means of iOS distribution.
:::info
This step is the archive and export step. When the step is completed, the `.ipa` file of the application is generated.
:::
### Prerequisites
Before running the **Xcodebuild for Devices** step, you must complete certain prerequisites, as detailed in the table below:
| Require Workflow Step | Description |
| ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The repository that needs to be built must be fetched from the Git provider. **Xcodebuild for Devices** should be used after this step. |
| [**Xcode Select**](/workflows/ios-specific-workflow-steps/xcode-select) | In this step, select the Xcode version to build. **Xcodebuild for Devices** should be used after this step. |
| [**Cocoapods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) | This step installs all pod dependencies for project. **Xcodebuild for Devices** should be used after this step. If you use SPM (Swift Package Manager), it is not necessary to use. |
:::danger
This step should always follow steps that may affect Archive and Export, such as **Xcode Select** and **Cocoapods Install**.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_OUTPUT_DIR_PATH` | This variable specifies the path of the artifacts that will be generated after the build is complete. | Required |
| `$AC_SCHEME` | Specifies the project scheme for build. If you filled in **`Configuration => Build Scheme`**, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_CLEAN_BUILD` | Adds the clean parameter to xcodebuild command. When false, performs incremental build without cleaning. Default value is `true`. | Optional |
| `$AC_ARCHIVE_FLAGS` | Specifies the extra xcodebuild flag. For example: `-quiet`. | Optional |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: `./appcircle.xcodeproj`. If you filled in **`Configuration => Project or Workspace`**, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_CERTIFICATES` | This variable specifies the path of the certificates to be signed. | Required |
| `$AC_BUNDLE_IDENTIFIERS` | This variable holds the Bundle Identifier of the application to be built. | Required |
| `$AC_PROVISIONING_PROFILES` | This variable specifies the path of provisioning profiles to be signed. | Required |
| `$AC_CONFIGURATION_NAME` | You can build your project with any configuration you want. Specify the configuration as hard coded. Appcircle will add automatically this configuration to the xcodebuild command. For example; **`Debug`**. | Optional |
| `$AC_COMPILER_INDEX_STORE_ENABLE` | You can disable indexing during the build for faster build. Default value is `No`. | Optional |
| `$AC_METHOD_FOR_EXPORT` | Describes how Xcode should export the archive. Available options are `auto-detect`, `app-store`, `ad-hoc`, `enterprise`, `development`. The default is `auto-detect`. | Optional |
| `$AC_TEAMID_FOR_EXPORT` | The Developer Portal team to be use for this export. Defaults to the team used to build the archive. | Optional |
| `$AC_COMPILE_BITCODE_FOR_EXPORT` | For non-App Store exports, should Xcode re-compile the app from bitcode? Available options `YES`, `NO`. | Optional |
| `$AC_UPLOAD_BITCODE_FOR_EXPORT` | For App Store exports, should the package include a bitcode? Available options `YES`, `NO`. | Optional |
| `$AC_UPLOAD_SYMBOLS_FOR_EXPORT` | For App Store exports, should the package include symbols? Available options `YES`, `NO`. | Optional |
| `$AC_ICLOUD_CONTAINER_ENVIRONMENT_FOR_EXPORT` | For non-App Store exports, if the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. Available options `Development` and `Production`. | Optional |
| `$AC_DELETE_ARCHIVE` | Delete `build.xcarchive` file after creating ipa file. | Optional |
:::info Local SPM (Swift Package Manager)
If SPM dependencies are kept locally in your project and are already installed, the Xcodebuild for Devices step may fail during the build while resolving the dependencies. For this reason, you can use the `-skipPackagePluginValidation` parameter in the `$AC_ARCHIVE_FLAGS` input to prevent reloading dependencies that are already installed in the project.
**Note**: This may be a security risk if they are not from trusted sources.
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
| --------------------------- | --------------------------------------------------------- |
| `AC_ARCHIVE_PATH` | This is the path created after retrieving the archive. |
| `AC_ARCHIVE_METADATA_PATH` | This is the path created after the metadata is generated. |
| `AC_EXPORT_DIR` | This is the path created when exporting. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-build-sign-component
---
## FAQ
### Adding Additional Command to Xcodebuild for Devices Step
To address the need to add a new command after completing the `xcodebuild` command in the **Xcodebuild for Devices** step, you can follow the following approach:
- Disable **Xcodebuild for Devices** step in your workflow.
- Add a new "Custom Script" component instead of **Xcodebuild for Devices** step.
- Go to Appcircle github profile and navigate to the [repository](https://github.com/appcircleio/appcircle-ios-build-sign-component).
- Copy all code lines from the `main.rb` file and paste them into the new **Custom Script** that you just added in your workflow.
- Change the name as **Custom Xcodebuild for Devices** for this custom script.
- Change "Execute With" picker as **Ruby**.
- In the Ruby code, you can add the required codes to the end of the `xcodebuild` command.
:::caution
Before running the script, some variables must be changed, and new variables must be added to the **Custom Script**.
:::
First, the `output_path` global variable should be changed like below in global variables.
```ruby
...
## Other global variables
...
$output_path = env_has_key("AC_OUTPUT_DIR")
```
After this, you need to add some parameters to your custom script. The parameters below should be added right after global variables.
```ruby
AC_COMPILER_INDEX_STORE_ENABLE = "NO"
AC_METHOD_FOR_EXPORT = "auto-detect"
AC_DELETE_ARCHIVE = "false"
AC_ARCHIVE_PATH = "AC_ARCHIVE_PATH"
AC_ARCHIVE_METADATA_PATH = "AC_ARCHIVE_METADATA_PATH"
AC_EXPORT_DIR = "AC_EXPORT_DIR"
```
In the next step for completing custom script settings, the `AC_COMPILER_INDEX_STORE_ENABLE` parameter should be equaled with the following parameter:
```ruby
$compiler_index_store_enable = AC_COMPILER_INDEX_STORE_ENABLE
```
:::caution
You should find the line with `compiler_index_store_enable` and replace it with the above statement.
:::
After these variables were set. There is an `archive()` function in the Ruby code. First, find the function in the code.
```ruby
## Archive Functions
def archive()
extname = File.extname($project_path)
command = "xcodebuild -scheme \"#{$scheme}\" clean archive -archivePath \"#{$archive_path}\" -derivedDataPath \"#{$temporary_path}/DerivedData\" -destination \"generic/platform=iOS\""
...
## Other code lines of archive() function
...
```
At the end of this function, before running the `run_command_simple()` function, you can add these lines to be able to add additional commands.
```ruby
...
## Other code lines of archive() function
...
command.concat(" ")
command.concat("Write your command that you want to add here")
command.concat(" ")
run_command_simple(command)
end
```
#### For Example
When you need to reduce the verbosity of the `xcodebuild` logs, you can achieve this by appending the `| grep -A 5 error:` command to the `xcodebuild` command to decrease the clutter in the log file.
```ruby
...
## Other code lines of archive() function
...
command.concat(" ")
command.concat(" | grep -A 5 error:")
command.concat(" ")
run_command_simple(command)
end
```
Now, the `run_command_simple()` function will execute your customized `xcodebuild` command.
### How can I resolve the `Outputting Keys and Certificates` signing error?
Since Appcircle does not have direct access to self-hosted environments, the default versions installed on runners may also have user-generated updates. This error is caused by using **OpenSSL** by default instead of **LibreSSL**. If **OpenSSL** is used instead of **LibreSSL** for any reason in your self-hosted environments, you will get an **error** like the one below.
```
`parse_certificate': Error outputting keys and certificates (RuntimeError)
C05EDAE401000000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:355:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()
Could not find certificate from
Error: Error outputting keys and certificates
C05EDAE401000000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:355:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()
```
:::info Cloud Customers
All packages running in Appcircle cloud environments are controlled by the Appcircle development teams on runners and updated when necessary. One of the packages used on runners is **LibreSSL**. In Appcircle Cloud environments, the **LibreSSL** 3.3.6 version on macOS Sonoma and the **LibreSSL** 2.8.3 version on macOS Monterey are used. For more information, please visit our [**Build Infrastructure**](/infrastructure/ios-build-infrastructure#ios-build-environment) documentation.
However, issues may still occur depending on how the environment is used. If you are working in the cloud environment and the [**Custom Scripts**](/workflows/common-workflow-steps/custom-script) you use can **change** or **update** the packages in our environments. If cloud users encounter such **signing errors**, it is recommended to check the **Custom Scripts** used. You can use the example `bash` script below.
```bash
export PATH="/usr/bin:$PATH"
```
Appcircle's macOS environments use `LibreSSL` by default. If this default value is changed in any way, the global path must be updated with the script above and `LibreSSL` must be set as default again. Otherwise, the system will try to find and sign `OpenSSL` first while the system is running, so if there is a depricated method, it may cause an error during signing.
**Note:** Please note, the example script given above should be run before the **Xcodebuild for Devices** step. Otherwise you may keep getting errors during signing.
:::
Although **LibreSSL** and **OpenSSL** are alternatives to each other, there are differences between them. **LibreSSL** comes by default with macOS machines and is managed by **Apple**. For this reason, since Appcircle does not have direct access to self-hosted environments, some user-side work on runners can replace **LibreSSL** with **OpenSSL** or update their versions.
The reason for this **error** is that the **encryption algorithm** in the new versions of **OpenSSL** has been changed. In **OpenSSL** versions **3 and above**, the algorithm named **RC2** is marked as **legacy**. When you encounter this error, you need to change the **OpenSSL** package on the runners receiving the error to **LibreSSL**.
The **RC2 algorithm** is just one example. There are other algorithms and ciphers that **OpenSSL** has deprecated. Users may encounter other errors with certificates containing other algorithms, such as **SHA1**. This depends on the encryption algorithm of the certificate the user is using.
For more information about **legacy algorithms**, please visit the [**OpenSSL**](https://docs.openssl.org/3.0/man7/OSSL_PROVIDER-legacy/) documentation.
---
## Xcodebuild for iOS Simulator
This step builds your application for the iOS Simulator in x86_64 or arm64 architecture. This step creates an unsigned `xarchive` file. You may also optionally install the application for the given simulator.
### Prerequisites
Before running the **Xcodebuild for iOS Simulator** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcode Select**](/workflows/ios-specific-workflow-steps/xcode-select) | This step selects the Xcode version that is specified. |
| [**Cocoapods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) | This step installs all the dependencies of the pod file. |
:::caution
If you use SPM (Swift Package Manager), Xcode will manage itself when a project is built. The **CocoaPods Install** step is not necessary.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_OUTPUT_DIR_PATH` | Specifies the path for outputs for generated artifacts. | Required |
| `$AC_SCHEME` | Specifies the project scheme for build. If you filled in `Config => Build Schema` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_SIMULATOR_ARCH` | Specifies the CPU architecture for the simulator build. The default variable is **`arm64`**. | Optional |
| `$AC_SIMULATOR_NAME` | Destination name of the simulator. Ex. `iPhone 14`. If you set a simulator name, the build will be installed into the given simulator. Please be aware that setting the simulator name invalidates the `$AC_SIMULATOR_ARCH` option. | Required |
| `$AC_ARCHIVE_FLAGS` | Specifies the extra xcodebuild flag. For example: `-quiet`. | Optional |
| `$AC_PROJECT_PATH` | Specifies the project path. If you filled in `Config => Xcode Project or Workspace Path` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). For example: `./appcircle.xcodeproj`. | Required |
| `$AC_CONFIGURATION_NAME` | You can build your project with any configuration you want. Specify the configuration as hard coded. Appcircle will automatically add this configuration to the xcodebuild command. For example; **`Debug`**. | Optional |
| `$AC_COMPILER_INDEX_STORE_ENABLE` | You can disable indexing during the build for a faster build. The default value is **`No`**. | Required |
:::caution
Be aware of which OS version you used; the simulator type should match that OS version. For example, if you use the [**latest OS version**](https://developer.apple.com/documentation/ios-ipados-release-notes), you can not use the **iPhone 14** simulator.
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `AC_SIMULATOR_APP_PATH` | Simulator app path. You can reach the simulator app from this path, and it will be exported, it can be downloaded from the **Download Artifacts**. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-build-simulator
---
## Xcodebuild for Testing
This step builds your application and generates an IPA for testing so that it can be used in test automation frameworks like [**BrowserStack**](/workflows/ios-specific-workflow-steps/browserstack-app-automation) or [**Testinium**](/workflows/common-workflow-steps/testinium-steps/testinium).
### Prerequisites
Before running the **Xcodebuild for Testing** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Xcode Select**](/workflows/ios-specific-workflow-steps/xcode-select) | This step selects the Xcode version that is specified. |
| [**CocoaPods Install**](/workflows/ios-specific-workflow-steps/cocoapods-install) | This step installs all the dependencies of the pod file. |
:::caution
If you use SPM (Swift Package Manager), Xcode will manage itself when a project build. The **CocoaPods Install** step is not necessary.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|----------------------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps#git-clone) step. | Required |
| `$AC_SCHEME` | Specifies the project scheme for build. If you filled in `Config => Build Schema` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_ARCHIVE_FLAGS` | Specifies the extra xcodebuild flag. For example: **`-quiet`** | Optional |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: **`./appcircle.xcodeproj`**. This variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_CONFIGURATION_NAME` | You can build your project with any configuration you want. Specify the configuration as hard-coded. Appcircle will automatically add this configuration to the xcodebuild command. For example; **`Debug`** | Optional |
| `$AC_COMPILER_INDEX_STORE_ENABLE` | You can disable indexing during the build for a faster build. The default value is **`No`**. | Optional |
| `$AC_DESTINATION` | This parameter determines for which destination the application will be built and IPA will be generated. The default value is **`generic/platform=iOS`**, which means that it will be built for all iOS devices. | Required |
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|------------------------------------------------|
| `AC_TEST_APP_PATH` | This parameter is the path of the application after the build is complete. If you are using a test automation tool, you can use this path as the app path. |
| `AC_UITESTS_RUNNER_PATH` | This path is the UI Runner Path for running UI tests after the build is complete. This variable is sent to test automation tools to run the tests. |
| `AC_XCTEST_PATH` | This variable is the path containing the tests. |
| `AC_UITESTS_RUNNER_IPA_PATH` | This variable is the path that the IPA generated for the test creates for the UI tests to run. This can be sent directly to test automation tools. |
| `AC_XCTEST_ZIP_PATH` | Path to the IPA version of the Xctests. You can access it directly via this path. |
| `AC_TEST_IPA_PATH` | This path holds the IPA file created for running tests and sending the IPA file to test automation tools. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-build-for-testing
---
## Xcodebuild for Unit and UI Testing
This step allows you to run unit and UI tests in your project. When this step runs, all your tests are run, and an `.xcresult` file is created as a result. This step does not `build` your app, but uses the `xcodebuild` command to run tests.
:::caution
This step does not generate **IPA**, it only runs tests within the project.
:::
### Prerequisites
Before running the **Xcodebuild for Unit and UI Testing** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | The repository must be cloned to initiate the unit and UI testing process. Following the clone, this step will run the tests and create the `$AC_REPOSITORY_DIR` variable. |
| [**Xcode Select**](/workflows/ios-specific-workflow-steps/xcode-select) | This step selects the specified Xcode version. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|------------------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_OUTPUT_DIR_PATH` | Specifies the path for outputs for generated artifacts. | Required |
| `$AC_SCHEME` | Specifies the project scheme for build. If you filled in `Config => Build Schema` in the Configuration, this variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Required |
| `$AC_ARCHIVE_FLAGS` | Specifies the extra xcodebuild flag. For example: **`-quiet`** | Optional |
| `$AC_PROJECT_PATH` | Specifies the project path. For example: **`./appcircle.xcodeproj`**. This variable comes from [Configuration](/build/platform-build-guides/building-ios-applications#build-configuration). | Optional |
| `$AC_CONFIGURATION_NAME` | You can build your project with any configuration you want. Specify the configuration as hard-coded. Appcircle will automatically add this configuration to the xcodebuild command. For example; **`Debug`** | Optional |
| `$AC_COMPILER_INDEX_STORE_ENABLE`| You can disable indexing during the build for a faster build. The default value is **`No`**. | Required |
| `$AC_TEST_OS_VERSION` | Specify the test OS version. The default value is `latest`. User can use different OS version. For example: `16.3`. | Required |
| `$AC_TEST_DEVICE` | Destination name of the test simulator device. Ex. `iPhone 14`. If you set a simulator name, the build will be installed into the given simulator. The default value is `iPhone 8 Plus`. | Required |
| `$AC_TEST_PLATFORM` | Specify the test platform. The default value is `iOS Simulator`. | Required |
:::caution
Ensure the simulator type matches the OS version used. For example, if you use the [**latest OS version**](https://developer.apple.com/documentation/ios-ipados-release-notes), the iPhone 14 simulator cannot be used.
:::
:::caution
To view the output artifacts on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts#download-exported-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your workflow after this step.
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|-------------------------------|----------------------------------------------------------------------------------------------------------|
| `AC_TEST_RESULT_PATH` | The output path for the `.xcresult` file. This environment variable can be utilized in subsequent steps. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-ios-test-component
---
## App Center CodePush
:::danger
As [Microsoft announced](https://learn.microsoft.com/en-gb/appcenter/retirement),
> "Visual Studio App Center is scheduled for retirement on March 31, 2025. After that date, it will not be possible to sign in with your user account nor make API calls."
Therefore, the AppCenter CodePush step in Appcircle will also be deprecated after this date.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcenter-codepush-component
---
## Appcircle CodePush Workflow
# Appcircle CodePush
The **Appcircle CodePush** step allows you to automate the process of releasing over-the-air (OTA) updates for your React Native apps as part of your CI/CD workflow.
For more information about Appcircle CodePush feature, please visit the [**CodePush**](/code-push) documentations.
### Prerequisites
Before running the **Appcircle CodePush** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Git Clone** | Clone the selected repository to the build machine. Please use the **Appcircle CodePush** step after this step. |
| **Node Install** | This step will install Node modules for your application. Please note that the **Appcircle CodePush** step should be used after this step. |
| **NPM/Yarn Commands** | This step installs the [NPM](https://www.npmjs.com/) or [Yarn](https://www.npmjs.com/package/yarn) package manager to install specific dependencies for your React Native applications. Please note that the **Appcircle CodePush** step should be used after this step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
:::danger Sensitive Variables
Please do not use sensitive variables such as **Username**, **Password**, **API Key**, or **Personal Access Key** directly within the step.
We recommend using [**Environment Variables**](/build/build-environment-variables) groups for such sensitive variables.
:::
| Variable Name | Description | Status |
|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_REPOSITORY_DIR` | Relative path of the React Native project. | Required |
| `$AC_CODE_PUSH_TOKEN` | Appcircle personal access token. You can create a new Personal Access Key in the Appcircle dashboard under `Settings > Security > Personal Access Key`. For details, see [Generating and Managing Personal Access Keys](/account/my-organization/security/personal-access-key). | Required |
| `$AC_CODE_PUSH_SERVER_URL` | This parameter specifies the server URL used by self-hosted Appcircle instances to authenticate CLI access (e.g. `https://api-appcircle.spacetech.com/codepush`). Ignore this if you are not a self-hosted Appcircle user. | Optional |
| `$AC_CODE_PUSH_AUTH_URL` | This parameter specifies the authentication URL used by self-hosted Appcircle instances to authenticate CLI access (e.g. `https://auth-appcircle.spacetech.com`). Ignore this if you are not a self-hosted Appcircle user. | Optional |
| `AC_CODE_PUSH_APP_NAME` | This parameter specifies the name of the app in Appcircle. The App Name parameter is the Appcircle CodePush profile name. For example `MyApp-Android` or `MyApp-iOS`. | Required |
| `$AC_CODE_PUSH_DEPLOYMENT_NAME` | This parameter specifies the deployment channel name in Appcircle. The Deployment Channel parameter is the Appcircle CodePush deployment name. For example `Staging` or `Production`. | Required |
| `$AC_CODE_PUSH_TARGET_BINARY_VERSION` | This parameter specifies the target binary version of the app that this update is intended for. It should be in the format `1.0.0`. | Required |
| `$AC_CODE_PUSH_DESCRIPTION` | This parameter provides an optional changelog for the deployment. | Optional |
| `$AC_CODE_PUSH_ROLLOUT_PERCENTAGE` | This parameter specifies the percentage of users (as an integer between 1 and 100) that should be eligible to receive this update. | Optional |
| `$AC_CODE_PUSH_EXTRA_ARGUMENTS` | Extra command line arguments for Appcircle CodePush CLI command. For example, add `--debug` for verbose logs. | Optional |
:::tip Package Diff
You can add `--diffEnabled` flag to `$AC_CODE_PUSH_EXTRA_ARGUMENTS` to enable package diff feature to make users download only the changed files instead of the full package.
:::
### CodePush Code Signing
With the **Appcircle CodePush** step, you can also publish a **signed CodePush release**. The required actions are outlined below, step by step.
- First, create a group in the **Environment Variables** sub‑section under the **Build** module, and upload your `.pem` file into that group. For more information, please visit the Environment Variable [documentation](/environment-variables).
:::caution Environment Variables
In order to use the **Environment Variable** group you created in the relevant profile, you need to select this group from the build configuration. For more detailed information, please refer to the Build Configuration [documentation](/build/build-process-management/configurations#environment-variables-configuration).
:::
- Next, in the **Appcircle CodePush** step, use the **Extra Arguments** input to pass the `--privateKeyPath ` parameter and reference the environment variable you created.
Once these steps are completed, running the **Appcircle CodePush** step will automatically sign the generated CodePush release with your provided `.pem` file and publish it.
### Package Diff
With the **Package Diff** feature, users download only the changed files instead of the full package. When **Package Diff** is enabled, updates from any older version to a new one include only the modified files, reducing update size and speeding up delivery.
- In the **Appcircle CodePush** step, use the **Extra Arguments** input to pass the `--diffEnabled` parameter.
---
## React Native Specific Workflow Steps
The steps listed below are specific to the React Native build profiles.
You can find the full list of available workflow steps in our [workflow marketplace](https://github.com/appcircleio/appcircle-workflow-components) and under each workflow step in this document, you can find the related repository URL, which also includes the documentation for the related step.
## [Appcircle CodePush](/workflows/react-native-specific-workflow-steps/appcircle-codepush)
Release a React Native update to [Appcircle CodePush](/code-push). You need enter your token, app name and deployment channel to distribute your updates.
## [Install Node](/workflows/react-native-specific-workflow-steps/node-install)
React Native applications commonly depend on certain Node modules. This workflow step makes sure that you have the required Node version installed in the build agent to build your React Native application.
## [NPM/Yarn Commands](/workflows/react-native-specific-workflow-steps/npm-yarn-commands)
You may want to use npm or Yarn package manager to install specific dependencies for your React Native applications. The package manager commands you enter are executed in this workflow step.
## [React Native UI Test](/workflows/react-native-specific-workflow-steps/react-native-ui-test)
Run all the UI tests in your project written with [Detox](https://wix.github.io/Detox/docs/introduction/getting-started/) integration.
## [React Native Unit Test](/workflows/react-native-specific-workflow-steps/react-native-unit-test)
Run all the unit tests in your project written with [Jest](https://jestjs.io/docs/tutorial-react-native) integration.
## [Test Reports for React Native](/workflows/react-native-specific-workflow-steps/test-reports-react-native)
This component provides detailed reports and insights on the results of React Native app tests conducted.
For detailed information on the usage of **Test Reports for React Native**, please refer to the documentation:
[Appcircle React Native Testing](/continuous-testing/react-native-testing)
---
## Install Node
React Native applications commonly depend on certain Node modules. This workflow step makes sure that you have the required Node version installed in the build agent to build your React Native application.
### Prerequisites
Before running the **Install Node** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps/git-clone) | Clone the selected repository to the build machine. Please use the **Install Node** step after this step. |
:::caution
Please note that this step should be used before steps that need the **npm/yarn Commands** step. To avoid any problems, you can run this step after the **Git Clone** step.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_SELECTED_NODE_VERSION` | This step takes only the **Node version** variable. You can specify the version directly in the step if you wish. Or you can get it from build [**Configurations**](/build/platform-build-guides/building-react-native-applications#build-configuration-for-react-native-ios-applications). | Optional |
:::caution
If you do not specify any specific version for the **Install Node** step. The latest version will be installed automatically.
:::
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-node-install-component
---
## NPM/Yarn Commands
You may want to use the [NPM](https://www.npmjs.com/) or [Yarn](https://www.npmjs.com/package/yarn) package manager to install specific dependencies for your [React Native](https://reactnative.dev/) applications. The package manager commands you enter are executed in this workflow step.
### Prerequisites
Before running the **NPM/Yarn Commands** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|-------------------------------------------------|-------------------------------------------------|
| [**Install Node**](/workflows/react-native-specific-workflow-steps/node-install) | This step will install Node modules for your application. Please note that the **NPM/Yarn Commands** step should be used after this step. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|-------------------------------|------------------------------------------------|--------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps/git-clone) step. | Required |
| `$AC_NPM_COMMAND_ARGS` | The NPM command to run. You can add different command parameters directly. The default is: `npm/yarn install`. | Optional |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-npm-yarn-component
---
## React Native UI Test
This component runs all the UI tests in your project written with [Detox](https://wix.github.io/Detox/docs/introduction/getting-started) integration. When this step is completed, it generates a test report file in `e2e-report.xml` format. You can view these test results in detail using Appcircle's [**Test Report**](/workflows/react-native-specific-workflow-steps/test-reports-react-native) component.
For detailed information for continuous testing, please visit our [React Native Continuous Testing documentation](/continuous-testing/react-native-testing/react-native-ui-test-with-detox).
To generate detailed Test Reports. Please visit our [Test Reports Component documentation](/workflows/react-native-specific-workflow-steps/test-reports-react-native).
:::info Java Version
The default Java version in Appcircle's build stacks is **Java 17**. If your project requires a **higher** or **lower** Java version, please use the [**Select Java Version**](/workflows/common-workflow-steps/select-java-version) component. On the other hand, you can see all details for build stacks both iOS and Android with this [documentation](/infrastructure).
:::
### Prerequisites
Before running the **React Native UI Test** step, you must complete certain prerequisites, as detailed in the table below:
#### For iOS
| Prerequisite Workflow Step | Description |
|--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps#git-clone) | Clone the selected repository to the build machine. |
| [**Install Node**](/workflows/react-native-specific-workflow-steps#install-node) | This step will install Node modules for your application. |
| [**NPM/Yarn Commands**](/workflows/react-native-specific-workflow-steps/npm-yarn-commands) | This step installs the [NPM](https://www.npmjs.com/) or [Yarn](https://www.npmjs.com/package/yarn) package manager to install specific dependencies for your React Native applications. |
| [**Cocoapods Install**](/workflows/ios-specific-workflow-steps#cocoapods-install) | This step installs all the dependencies of the pod file. |
:::info
If your **CocoaPods** dependencies are **embedded** in the project, you do not need to use the **CocoaPods Install** step to run UI tests.
:::
#### For Android
| Prerequisite Workflow Step | Description |
|-------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps#git-clone) | Clone the selected repository to the build machine. |
| [**Install Node**](/workflows/react-native-specific-workflow-steps#install-node) | This step will install Node modules for your application. |
| [**NPM/Yarn Commands**](/workflows/react-native-specific-workflow-steps/npm-yarn-commands) | This step installs the [NPM](https://www.npmjs.com/) or [Yarn](https://www.npmjs.com/package/yarn) package manager to install specific dependencies for your React Native applications. |
| [**Wait for Android Emulator**](/workflows/android-specific-workflow-steps/wait-for-android-emulator) | This step waits for the Android Emulator to boot. You must use this step before running any UI tests. |
:::danger React Native UI Test for Android
For Appcircle **Cloud**, you need to use **Appcircle Linux Pool (x86_64)** to run your UI tests on the Android platform. Since **Appcircle Standard macOS Pool (arm64)** is based on **Apple Silicon's virtualization** technology, it does not support running Android emulators. If your organization has **self-hosted pools**, you can choose and use any pool that has bare-metal machines or VMs that support nested virtualization. For more information, please follow the [**Build Configuration**](/build/build-process-management/configurations) and [**Android Build Infrastructure**](/infrastructure/android-build-infrastructure) documentations.
:::
:::caution Android Emulator
React Native UI Test component works according to the device given in the project configurations. To change the emulator device or install a new device, please follow the [**Emulator**](/infrastructure/android-build-infrastructure#emulator) documentation.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps#git-clone) step. | Required |
| `$AC_OUTPUT_DIR` | This variable specifies the path of the artifacts that will be generated after the build is complete. | Required |
| `$AC_RN_DETOX_CONFIGURATION` | Specify the detox configuration name to used when building and running the tests. | Required |
| `$AC_RN_DETOX_TEST_ARGS` | Specify the Detox extra arguments to add the test command. The arguments will be executed by appending `detox test --configuration` to the end of the command. The default value is `--take-screenshots all` For more information, see the Detox test [CLI options](https://wix.github.io/Detox/docs/19.x/api/detox-cli/#test). | Optional |
:::danger Detox Configuration
To able to run your test successfully, you must specify the **Detox Configuration** in the `$AC_RN_DETOX_CONFIGURATION`. If you do not specify a specific configuration, UI tests will throw an error because of the configuration not found.
**Example Configuration**
```
configurations: {
'ios.sim.debug': {
device: 'simulator',
app: 'ios.debug',
},
'ios.sim.release': {
device: 'simulator',
app: 'ios.release',
},
'android.emu.debug': {
device: 'emulator',
app: 'android.debug',
},
'android.emu.release': {
device: 'emulator',
app: 'android.release',
},
},
```
For more information, please visit [**Continuous Testing**](/continuous-testing/react-native-testing/react-native-ui-test-with-detox) documentation.
:::
:::info How to Download Screen Shots
The Appcircle interface does **not** support displaying screenshots generated from UI tests in React Native projects. All screenshots created as a result of these tests are exported to [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) as `test_attachments.zip`. You can access the relevant screenshots in **Download Artifact** and download them directly.
:::
:::caution
To view the output artifacts on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your Workflow after this step.
:::
### Output Variables
The outputs resulting from the operation of this component are as follows:
| Variable Name | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------ |
| `AC_TEST_RESULT_PATH` | The output path for the `e2e-report.xml` file. This environment variable can be utilized in subsequent steps. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-react-native-ui-test-component
---
## React Native Unit Test
This component runs all the unit tests in your project written with [Jest](https://jestjs.io/docs/tutorial-react-native) integration. When this step is completed, it generates a test report file in `junit-report.xml` format. You can view these test results in detail using Appcircle's **Test Report** component. To generate detailed Test Reports. Please visit our [Test Reports Component documentation](/workflows/react-native-specific-workflow-steps/test-reports-react-native).
For detailed information for continuous testing, please visit our [React Native Continuous Testing documentation](/continuous-testing/react-native-testing/react-native-unit-test-with-jest).
### Prerequisites
Before running the **React Native Unit Test** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
|--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Git Clone**](/workflows/common-workflow-steps#git-clone) | Clone the selected repository to the build machine. |
| [**Install Node**](/workflows/react-native-specific-workflow-steps#install-node) | This step will install Node modules for your application. |
| [**NPM/Yarn Commands**](/workflows/react-native-specific-workflow-steps/npm-yarn-commands) | This step installs the [NPM](https://www.npmjs.com/) or [Yarn](https://www.npmjs.com/package/yarn) package manager to install specific dependencies for your React Native applications. |
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| `$AC_REPOSITORY_DIR` | Specifies the cloned repository directory. This path will be generated after the [**Git Clone**](/workflows/common-workflow-steps#git-clone) step. | Required |
| `$AC_OUTPUT_DIR` | This variable specifies the path of the artifacts that will be generated after the build is complete. | Required |
| `$AC_RN_TEST_COMMAND_ARGS` | Specify additional arguments for running the Jest command. These arguments will be added to the end of the command `jest --coverage --coverageDirectory=coverage --coverageReporters=lcov` which will be used by default. You can add extra arguments, such as `--debug --colors`, without affecting the default ones. For more information, see the Jest [CLI options](https://jestjs.io/docs/cli#options). | Optional |
:::caution
To view the output artifacts on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your workflow after this step.
:::
### Output Variables
The output(s) resulting from the operation of this component are as follows:
| Variable Name | Description |
|---------------------------|-----------------------------------------------------------------------------------------------------------------------|
| `AC_TEST_RESULT_PATH` | The output path for the `junit-report.xml` file. This environment variable can be utilized in subsequent steps. |
| `AC_COVERAGE_RESULT_PATH` | The output path for the `lcov.info` file for coverage. This environment variable can be utilized in subsequent steps. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-react-native-unit-test-component
---
## Test Reports for React Native
The Appcircle **Test Report** step displays your test results and code coverage in an aesthetically pleasing user interface.
This component supports the following test and coverage formats:
- [JUnit](https://junit.org) - For Java-based test reporting.
For additional details, please refer to the document: [**Generating Test Report**](/continuous-testing/react-native-testing/react-native-ui-test-with-detox#generating-test-report)
### Prerequisites
Before running the **Test Reports for React Native** step, you must complete certain prerequisites, as detailed in the table below:
| Prerequisite Workflow Step | Description |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| [**React Native Unit Test**](/workflows/react-native-specific-workflow-steps/react-native-unit-test) | Run unit tests in your project to generate an `junit-report.xml` file containing the test outcomes. |
| [**React Native UI Test**](/workflows/react-native-specific-workflow-steps/react-native-ui-test) | Run UI tests in your project to generate an `e2e-report.xml` file containing the test outcomes. |
:::caution Prerequisites
To able to use the **Test Report** component, not necessary to use both test step **React Native UI Test** and **React Native Unit Test** at the same time. But if these test steps are included in the flow, they must be used before the **Test Report** component.
:::
### Input Variables
This step contains some input variable(s). It needs these variable(s) to work. The table below gives explanation for this variable(s).
| Variable Name | Description | Status |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$AC_TEST_RESULT_PATH` | Define the directory and its subdirectories for searching compatible test files. | Required |
| `$AC_COVERAGE_RESULT_PATH` | For native iOS projects, tests automatically set this variable. For other projects, you must specify the coverage path manually. | Optional |
:::caution
To view the output artifacts on the [**Download Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) page, please ensure that the [**Export Build Artifacts**](/workflows/common-workflow-steps/export-build-artifacts) step is included in your Workflow after this step.
:::
### Output Variables
The outputs resulting from the operation of this component are as follows:
| Variable Name | Description |
| -------------------------- | -------------------------------------- |
| `AC_TEST_REPORT_JSON_PATH` | Specifies the path of the JSON report. |
---
To access the source code of this component, please use the following link:
https://github.com/appcircleio/appcircle-test-report-component