HarmonyOS Next Private Repository Construction in Practice
This article builds its own private repository based on the tools provided by the official.
Background
In Android and iOS development, dependencies and collaborations are often carried out in the form of binary products. Android uses Maven as the repository, and iOS has Pod as the repository. We can use open libraries provided by others on the officially provided platforms, which greatly improves everyone's development efficiency. However, some libraries related to a company's business do not want to be used by external personnel. Uploading them to external common repositories is not very safe. Many companies have built private repositories internally. On the one hand, it is more secure, and on the other hand, pushing and pulling products is usually faster.
HarmonyOS has the same issue. We can conveniently use open products from third parties on the official repository platform, but for a company's internal business, it still needs to rely on private repositories. This article builds its own private repository based on the tools provided by the official.
Introduction to HarmonyOS Shared Packages
HarmonyOS shared packages are divided into static shared packages and dynamic shared packages:
HAR (Harmony Archive) is a static shared package that can contain code, C++ libraries, resources, and configuration files. Through HAR, multiple modules or multiple projects can share relevant codes such as ArkUI components and resources. HAR is different from HAP and cannot be independently installed and run on devices. It can only be referenced as a dependency of application modules.
HSP (Harmony Shared Package) is a dynamic shared package. Static shared packages will be packaged into each dependent HAP, resulting in a large package size and repeated packaging of multiple copies of public resources and codes into the application. Dynamic shared packages allow multiple HAPs to share the same public resource code. HSP only supports sharing within an application and does not support cross-application sharing.
Building a Private Repository with the ohpm-repo Private Repository Tool
The official provides the ohpm-repo tool to help developers quickly build lightweight ohpm private repositories. It is compatible with the ohpm package manager and caches all dependencies on demand to accelerate installation in a private network.
ohpm-repo supports single-point deployment and multi-instance deployment:
Single-point deployment: ohpm-repo is only deployed and used on one machine.
Multi-instance deployment: ohpm-repo will be deployed on multiple machines with the same configuration content and shared data storage space.
Installation of the Dependent Environment
ohpm-repo depends on node to run and supports node.js 16.x and above versions. Nodejs needs to be installed first, and the environment needs to be configured. NodeJs can be downloaded from the official website (https://nodejs.org/download/release/latest/).
Downloading the ohpm-repo Tool
Download the ohpm-repo tool. The download address is: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-software-download-0000001507075446
Unzip the ohpm-repo tool.
Configuring the ohpm-repo Environment Variables
Configure the path of the bin directory in the unzipped directory of the ohpm-repo tool package to the system environment variable path:
export PATH=$OHPM-REPO-PATH/bin:$PATH
Execute the command
ohpm-repo -v
to view the version number and verify that the unzipped package is intact.
Configuration of the ohpm-repo Service Configuration File
Enter the conf directory in the unzipped directory, open the config.yaml file. The default configuration is as follows:
##### server configuration section #####
listen: 0.0.0.0:8088
# listen:
# - localhost:8088 # Listen to the local loopback address
# - http://localhost:8088 # Listen to the local loopback address
# - 0.0.0.0:8088 # Listen to all local addresses (INADDR_ANY)
# Protocol Configurable http or https,default http
# port: 1-65535(Windowssystems)/ 1024-65535(LinuxmaybeMacsystems)
# selectable (listen because of https You must configure the)
https_key: '' # https service-usable key pathways (No configuration defaults to'')
https_cert: '' # https service-usable crt pathways (No configuration defaults to'')
##### server deploy root section #####
deploy_root: '' # Installation root directory (No configuration defaults to `<existing userhomedirectory (on computer hard drive)>/ohpm-repo`),Only absolute paths are supported,and the path directory must exist
##### server numeric limit section #####
max_package_size: 100 # Upload packet size limit inMB (0, 100],不配置默认为 100
max_extract_size: 500 # Unpacked zip size limit,The unit isMB [max_package_size, 500],No configuration defaults to 500
max_extract_file_num: 10240 # Limit the number of files in a zip archive after decompression (0, 102400],No configuration defaults to 10240
user_rate_limit: 100 # User access frequency control in times/s (0, 10000],No configuration defaults to 100
fetch_timeout: 60 # Request/response timeout in seconds (0, 3600],No configuration defaults to 60
keep_alive_timeout: 60 # TCP Hold connection timeout,In seconds. (0, 3600],不配置默认为 60
api_timeout: 60 # apitimeout,In seconds.(0, 3600],No configuration defaults to 60
upload_lock_hour: 24 # After taking down all versions of a package, a time-limited ban on uploads of packages with the same name will be imposed.,单Bit is the hour. (0, 168],non-configuration,default 24
upload_max_times: 100 # Limit on the number of uploads in a 24-hour period for a single user (0, 10000],No configuration defaults to 100
##### metadata storage section #####
## Data storage type filedb respond in singing mysql Either/or, not both
db: # must yaml Writing in array form
type: filedb
config: # If you want to change the storage path and keep the old data, you need to change the number under the old path to the new path. Migration of documents to new paths
path:./db # Local data storage path, not configured defaults to <deploy_root>/db;
#db: # Must be written in yaml array form
# type: mysql
# config:
# host: "localhost" # Database host address
# port: 3306 # database port (0,65535]
# username: root # User name of the database
# password: "password" # User password for the database (please configure it in plaintext, it will eventually be converted to ciphertext in the deployment directory)
# database: "repo" # database name
##### storage section #####
## File storage typefs,sftp 和 custom Three choices, not more.
store: # Must be written in yaml array form
type: fs
config: # If you want to change the storage path after uploading a resource, you need to migrate the data under the old path to the new path.
path:./storage # The path to the triple repository store that has been shelved, without configuration the default is <deploy_root>/storage;
#server: http://localhost:8088 # Tripartite library download link, no default value configured
# The file storage type is sftp 时,Configure up to three sftp services
#store: # Must be written in yaml array form
# type: sftp # if and only if db The type of the mysql hour,store It is only when the type of the sftp
# config:
# location:
# -
# name: test_one_sftp # Host name, name cannot be duplicated with other sftp configurations
# host: "localhost" # host address
# port: 22 # host port (0,65535]
# read_username: "read" # Name of the user with read access to the host
# read_password: "password" # Passwords for users with read access to the host (please configure plaintext, it will be converted to ciphertext in the deployment directory)
# write_username: "write" # Name of the user with write access to the host
# write_password: "password" # Passwords for users with write access to the host (please configure plaintext, it will be converted to ciphertext in the deployment directory)
# path: /source22 # Path to a file relative to the sftp root directory, starts with / only, and the path folder must exist.
# -
# name: test_two_sftp
# host: "localhost"
# port: 24
# read_username: "read"
# read_password: "password"
# write_username: "write"
# write_password: "password"
# path: /source24
# #server: http://localhost:8088 # The address of the local repository download link, without configuring the default value of listen,
#store:
# type: custom # is a custom storage plugin type, the custom storage plugin development process is described in the guidance document
# config:
# export_name: CustomStorage # Class name of the plugin export
# plugin_path:../plugins/CustomStorage.js # The absolute path of the plugin or the path relative to the ohpm-repo package, it is recommended to place the plugin in the plugins directory of the package
# custom_field: "test" # Custom fields, get the value of a custom field by introducing the getStorageConfigInfo method of libs/common/getStorageConfigInfo.js
# #server: http://localhost:8088 # Local repository download link address, not configured to take the default value of listen
##### uplink section #####
uplink_cache_path:./uplink # Cache path, no configuration defaults to <deploy_root>/uplink
uplink_cache_time: 168 # Remote packet metadata cache time, in hours, default 168 hours, range (0, 8760]
##### log section #####
logs_path:./logs # log path, no configuration defaults to <deploy_root>/logs
##### log level section #####
# Log Levels: In descending order, the levels are all、trace、debug、info、warn、error、fatal、mark、off
# run,operate respond in singing access Not configured or misconfigured, defaults to info
loglevel_run: info
loglevel_operate: info
loglevel_access: info
It includes listening ports, https configuration, the private repository deployment directory deploy_root, service-related configurations, storage configurations, logs, etc. Just configure it according to the actual situation.
Regarding the storage module:
The db is the configuration item for metadata storage. The db supports local storage of fileDB and storage in the mysql database.
The store is the configuration item for file storage. The store supports local storage, sftp storage, and custom plugin storage.
Methods for Modifying the Configuration File After the Private Repository is Successfully Started:
When starting the private repository for the first time, execute the install command to specify the configuration file: Find the specified configuration file to modify its content, then re-execute install to specify the modified configuration file, and then execute start to start the private repository.
When starting the private repository for the first time, execute the install command without specifying the configuration file: The configuration file in the conf directory under the unzipped path of the private repository compression package is used by default. Modify the content of this file, and then re-execute the install and start operations.
Installation and Startup
Execute ohpm-repo install
to install. After the installation is completed, set the environment variables according to the configuration. After the setting is completed, execute ohpm-repo start
to start the service.
Using Private Repository Shared Packages
By default, the client ohpm tool only pulls dependency packages from the official public repository. To pull from a private repository, additional configuration is required. There are two configuration methods:
Configure this private repository for all projects:
ohpm config set registry <Configured Private Warehouse Service Address>/repos/ohpm
Configure for a certain dependency installation:
ohpm install @ohos/lottie --registry <Configured Private Warehouse Service Address>/repos/ohpm
The configured private repository service address above refers to the address information of store.config.server in the configuration file. For example, if store.config.server is
http://127.0.0.1:8088
, then the registry is: http://127.0.0.1:8088/repos/ohpm
. If store.config.server is not configured, the default value will be taken.
Publishing Shared Packages
Locally developed shared packages, whether static shared packages or dynamic shared packages, can be published through the ohpm command tool or using the Web page. For convenience and efficiency in general development work, we usually use the command line to publish.
Generate an ssh key locally:
ssh-keygen -m PEM -t RSA -b 4096 -f <your_key_path>
Log in to the ohpm-repo private repository management address, click on the personal center in the upper right corner of the home page, and add a new public key. Paste the content of the public key file (
<your_key_path>.pub
) into the public key input box.Set the private key path:
ohpm config set key_path <your_key_path>
Log in to the ohpm-repo private repository management address, click on the personal center in the upper right corner of the home page, and copy the publishing code.
Configure the publishing code to the.ohpmrc file:
ohpm config set publish_id <your_publish_id>
Publish the static shared library:
ohpm publish demo.har
Publish the dynamic shared package:
ohpm publish demo.tgz
The HSP package of the dynamic shared package cannot be directly published in the private repository and needs to be converted into a.tgz package first.
Switching the compilation mode to the release mode will package out a.taz package.
Module Configuration
In the library module (at the same level as the src folder), add the following files:
Newly create a README.md file: In the README.md file, it must include the introduction and reference method of the package, and more detailed introductions can also be added according to the content of the package.
Newly create a CHANGELOG.md file: Fill in the version update record of HAR.
Add a LICENSE file: The LICENSE license file.
The README.md file will eventually be displayed on the private repository web platform, and the dependent users can use it directly according to the description in README.md, so it is best to describe it clearly.
Explanation of the oh_package.json5 configuration file:
{
"parameterFile": "../dependencies.json5",
"keywords": [
"asr"
],
"name": "@xx/base-asr",
"version": "1.0.0-rc.9",
"repository": "http://gerrit.google.com/mobile_harmony/base_asr",
"description": "asr sdk",
"main": "Index.ets",
"author": "qingkouwei",
"license": "Apache-2.0",
"dependencies": {
}
}
The module name, version number, and description must meet the requirements. Otherwise, the upload to the private repository will fail. The version number can only increase sequentially and cannot be overwritten infinitely like a SNAPSHOT in Android.
Best Practices
In the actual development process, an engineering project may have multiple SDKs. After the SDKs are developed, they need to be integrated into other engineering projects. Sometimes, when locating problems and debugging, they may need to be frequently uploaded to the private repository, and other engineering projects rely on the packaged ones for debugging. In this way, it is particularly cumbersome and inefficient to compile the SDK each time and then execute commands to upload it, especially when an engineering project has multiple SDKs and these SDKs also have dependencies.
The best way is to be able to compile and upload to the private repository with one click through scripts, and upload them one by one according to the dependency relationship. It is also possible to package and upload a certain module separately.
First, create a version.json5 to store the SDK version:
{
"project": {
"sdk_version": "1.1.0-rc.1",
}
}
Automatic packaging:
def run_commands(modulename, productname):
hvigor_home = '/Applications/DevEco-Studio.app/Contents/tools/hvigor'
# Packing Command
command1 = 'node %s/bin/hvigorw.js --mode module -p product=default -p module=%s@default -p buildMode=debug assembleHar --analyze --parallel --incremental --daemon' %(hvigor_home,modulename)
# Wait for the first command to complete
process1.wait()
# Upload command
ohpm publish productname
process2.wait()
Automatically modify the version number:
python
def changeVersionAModule():
with open('version.json5', 'r') as f:
data = json5.load(f)
versionName = data['project']['sdk_version']
with open('AModule/oh-package.json5', 'r') as f:
aData = json5.load(f)
aData['version'] = versionName
with open('AModule/oh-package.json5', 'w') as f:
json.dump(aData, f, indent=4)
with open('dependencies.json5', 'r') as depf:
depData = json5.load(depf)
depData
Original source: HarmonyOS Next Private Repository Construction in Practice - DEV Community