<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://aznot.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kenneth</id>
	<title>Omnia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://aznot.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kenneth"/>
	<link rel="alternate" type="text/html" href="https://aznot.com/Special:Contributions/Kenneth"/>
	<updated>2026-08-01T22:11:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://aznot.com/index.php?title=USA_Territories&amp;diff=10127</id>
		<title>USA Territories</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=USA_Territories&amp;diff=10127"/>
		<updated>2026-08-01T08:57:35Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Insular Areas of the United States and Freely Associated States &amp;lt;ref&amp;gt;https://www.doi.gov/library/internet/insular&amp;lt;/ref&amp;gt;&lt;br /&gt;
* American Samoa&lt;br /&gt;
* Guam&lt;br /&gt;
* Republic of the Marshall Islands&lt;br /&gt;
* Federated States of Micronesia&lt;br /&gt;
* Commonwealth of the Northern Mariana Islands&lt;br /&gt;
* Republic of Palau&lt;br /&gt;
* Puerto Rico&lt;br /&gt;
* U.S. Virgin Islands&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/Wly2bTf.png&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref&amp;gt;https://www.reddit.com/r/MapPorn/comments/18yvs3s/us_territories/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- https://preview.redd.it/us-territories-v0-v88k4cx1bjac1.jpeg?width=1080&amp;amp;crop=smart&amp;amp;auto=webp&amp;amp;s=ece646133d25f7ca502c0a8766dc48e8b7964d11 --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=USA_Territories&amp;diff=10126</id>
		<title>USA Territories</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=USA_Territories&amp;diff=10126"/>
		<updated>2026-08-01T08:52:08Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;Insular Areas of the United States and Freely Associated States &amp;lt;ref&amp;gt;https://www.doi.gov/library/internet/insular&amp;lt;/ref&amp;gt; * American Samoa * Guam * Republic of the Marshall Islands * Federated States of Micronesia * Commonwealth of the Northern Mariana Islands * Republic of Palau * Puerto Rico * U.S. Virgin Islands&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Insular Areas of the United States and Freely Associated States &amp;lt;ref&amp;gt;https://www.doi.gov/library/internet/insular&amp;lt;/ref&amp;gt;&lt;br /&gt;
* American Samoa&lt;br /&gt;
* Guam&lt;br /&gt;
* Republic of the Marshall Islands&lt;br /&gt;
* Federated States of Micronesia&lt;br /&gt;
* Commonwealth of the Northern Mariana Islands&lt;br /&gt;
* Republic of Palau&lt;br /&gt;
* Puerto Rico&lt;br /&gt;
* U.S. Virgin Islands&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10125</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10125"/>
		<updated>2026-08-01T03:28:48Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
LDFLAGS=&amp;quot;-Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fix:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
CPPFLAGS=&amp;quot;-I/opt/openssl-3/include&amp;quot; \&lt;br /&gt;
LDFLAGS=&amp;quot;-L/opt/openssl-3/lib64 -Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
PKG_CONFIG_PATH=&amp;quot;/opt/openssl-3/lib64/pkgconfig&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --with-openssl-rpath=auto \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Local links&lt;br /&gt;
```bash&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/local/bin/python&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/local/bin/pip&lt;br /&gt;
&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/bin/python3.14&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/bin/pip3.14&lt;br /&gt;
&lt;br /&gt;
sudo alternatives --install \&lt;br /&gt;
    /usr/bin/unversioned-python \&lt;br /&gt;
    python \&lt;br /&gt;
    /opt/python3.14/bin/python3.14 \&lt;br /&gt;
    314&lt;br /&gt;
&lt;br /&gt;
# sudo alternatives --set python /usr/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
sudo alternatives --set python /opt/python3.14/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
sudo alternatives --install \&lt;br /&gt;
    /usr/bin/python3 \&lt;br /&gt;
    python3 \&lt;br /&gt;
    /opt/python3.14/bin/python3.14 \&lt;br /&gt;
    314&lt;br /&gt;
&lt;br /&gt;
sudo alternatives --set python3 /opt/python3.14/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
sudo ln -s /usr/bin/unversioned-python /usr/bin/python&lt;br /&gt;
&lt;br /&gt;
python --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10124</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10124"/>
		<updated>2026-08-01T01:19:55Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
LDFLAGS=&amp;quot;-Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fix:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
CPPFLAGS=&amp;quot;-I/opt/openssl-3/include&amp;quot; \&lt;br /&gt;
LDFLAGS=&amp;quot;-L/opt/openssl-3/lib64 -Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
PKG_CONFIG_PATH=&amp;quot;/opt/openssl-3/lib64/pkgconfig&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --with-openssl-rpath=auto \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Local links&lt;br /&gt;
```bash&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/local/bin/python&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/local/bin/pip&lt;br /&gt;
&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/bin/python3.14&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/bin/pip3.14&lt;br /&gt;
&lt;br /&gt;
sudo alternatives --install \&lt;br /&gt;
    /usr/bin/unversioned-python \&lt;br /&gt;
    python \&lt;br /&gt;
    /opt/python3.14/bin/python3.14 \&lt;br /&gt;
    314&lt;br /&gt;
&lt;br /&gt;
# sudo alternatives --set python /usr/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
sudo alternatives --set python /opt/python3.14/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
sudo ln -s /usr/bin/unversioned-python /usr/bin/python&lt;br /&gt;
&lt;br /&gt;
python --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.8&amp;diff=10123</id>
		<title>CentOS/8/Python 3.8</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.8&amp;diff=10123"/>
		<updated>2026-08-01T00:25:36Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.8 with or without OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.8 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.8 in `/opt/python3.8`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.8&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.8.20/Python-3.8.20.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.8.20.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.8.20&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure with openssl-3:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
CPPFLAGS=&amp;quot;-I/opt/openssl-3/include&amp;quot; \&lt;br /&gt;
LDFLAGS=&amp;quot;-L/opt/openssl-3/lib64 -Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
PKG_CONFIG_PATH=&amp;quot;/opt/openssl-3/lib64/pkgconfig&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.8 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --with-openssl-rpath=auto \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
&lt;br /&gt;
#    --enable-optimizations \&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Or Configure without openssl-3:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.8 \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
&lt;br /&gt;
#    --enable-optimizations \&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Note: On RHEL7/CentOS7 ran into GPO problems with the optimizations, but your milage may vary&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Local links&lt;br /&gt;
```bash&lt;br /&gt;
ln -sfn /opt/python3.8/bin/python3.8 /usr/local/bin/python3.8&lt;br /&gt;
ln -sfn /opt/python3.8/bin/pip3.8 /usr/local/bin/pip3.8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/python3.8 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.8.20&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration (if with openssl)&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/python3.8 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/python3.8 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/pip3.8 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/pip3.8 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.8/bin/python3.8 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.8/bin/python3.8 /usr/local/bin/python3.8&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.8/bin/pip3.8 /usr/local/bin/pip3.8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.8 --version&lt;br /&gt;
pip3.8 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.8 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.8&amp;diff=10122</id>
		<title>CentOS/8/Python 3.8</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.8&amp;diff=10122"/>
		<updated>2026-08-01T00:15:16Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== Python 3.8 with or without OpenSSL 3 ==  &amp;lt;markdown&amp;gt; # Python 3.8 + OpenSSL 3.x on CentOS 8  This guide installs:  - OpenSSL 3.x in `/opt/openssl-3` - Python 3.8 in `/opt/python3.8` - Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp` - Isolation from the OS Python and OpenSSL versions  This approach is recommended for environments that use:  - Corporate TLS inspection appliances - Internal Artifactory servers - Self-signed enterprise CAs - Modern...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.8 with or without OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.8 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.8 in `/opt/python3.8`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.8&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.8.20/Python-3.8.20.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.8.20.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.8.20&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure with openssl-3:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
CPPFLAGS=&amp;quot;-I/opt/openssl-3/include&amp;quot; \&lt;br /&gt;
LDFLAGS=&amp;quot;-L/opt/openssl-3/lib64 -Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
PKG_CONFIG_PATH=&amp;quot;/opt/openssl-3/lib64/pkgconfig&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.8 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --with-openssl-rpath=auto \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
&lt;br /&gt;
#    --enable-optimizations \&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Or Configure without openssl-3:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.8 \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Local links&lt;br /&gt;
```bash&lt;br /&gt;
ln -sfn /opt/python3.8/bin/python3.8 /usr/local/bin/python3.8&lt;br /&gt;
ln -sfn /opt/python3.8/bin/pip3.8 /usr/local/bin/pip3.8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/python3.8 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.8.20&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration (if with openssl)&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/python3.8 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/python3.8 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/pip3.8 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.8/bin/pip3.8 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.8/bin/python3.8 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.8/bin/python3.8 /usr/local/bin/python3.8&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.8/bin/pip3.8 /usr/local/bin/pip3.8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.8 --version&lt;br /&gt;
pip3.8 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.8 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10121</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10121"/>
		<updated>2026-07-31T10:41:35Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
LDFLAGS=&amp;quot;-Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fix:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make distclean&lt;br /&gt;
&lt;br /&gt;
CPPFLAGS=&amp;quot;-I/opt/openssl-3/include&amp;quot; \&lt;br /&gt;
LDFLAGS=&amp;quot;-L/opt/openssl-3/lib64 -Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
PKG_CONFIG_PATH=&amp;quot;/opt/openssl-3/lib64/pkgconfig&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --with-openssl-rpath=auto \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Local links&lt;br /&gt;
```bash&lt;br /&gt;
ln -sfn /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
ln -sfn /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10120</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10120"/>
		<updated>2026-07-31T09:24:34Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
LDFLAGS=&amp;quot;-Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10119</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10119"/>
		<updated>2026-07-31T09:19:54Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Actually Needs:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
LD_LIBRARY_PATH=/opt/openssl-3/lib64 /opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
 &lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
&lt;br /&gt;
OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Yum&amp;diff=10118</id>
		<title>CentOS/8/Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Yum&amp;diff=10118"/>
		<updated>2026-07-31T08:59:41Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* /etc/yum.repos.d/centos8.repo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== /etc/yum.repos.d/centos8.repo ===&lt;br /&gt;
&lt;br /&gt;
 ls -l /etc/pki/rpm-gpg&lt;br /&gt;
 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-8&lt;br /&gt;
&lt;br /&gt;
 rpm -qa gpg-pubkey* | grep -i f4a80eb5&lt;br /&gt;
&lt;br /&gt;
 https://www.centos.org/keys/&lt;br /&gt;
 https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official-SHA256&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 curl https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official-SHA256 -o /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&lt;br /&gt;
 curl --fail -s https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official-SHA256 -o /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
 if [ $? -ne 0 ] ; then echo &amp;quot;FAIL&amp;quot; ; fi&lt;br /&gt;
&lt;br /&gt;
 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&lt;br /&gt;
 rpm -qa gpg-pubkey* | grep -i 8483c65d&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 cat &amp;gt; /etc/yum.repos.d/centos8.repo &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[BaseOS]&lt;br /&gt;
name=CentOS-8.5.2111 - BaseOS&lt;br /&gt;
baseurl=http://vault.centos.org/8.5.2111/BaseOS/$basearch/os/&lt;br /&gt;
enabled=1&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&lt;br /&gt;
[AppStream]&lt;br /&gt;
name=CentOS-8.5.2111 - AppStream&lt;br /&gt;
baseurl=http://vault.centos.org/8.5.2111/AppStream/$basearch/os/&lt;br /&gt;
enabled=1&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&lt;br /&gt;
[PowerTools]&lt;br /&gt;
name=CentOS-8.5.2111 - PowerTools&lt;br /&gt;
baseurl=http://vault.centos.org/8.5.2111/PowerTools/$basearch/os/&lt;br /&gt;
enabled=0&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 EOF&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10117</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10117"/>
		<updated>2026-07-31T08:50:47Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
&lt;br /&gt;
mkdir ~/.src ; cd ~/.src&lt;br /&gt;
&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Yum&amp;diff=10116</id>
		<title>CentOS/8/Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Yum&amp;diff=10116"/>
		<updated>2026-07-31T08:50:17Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;=== /etc/yum.repos.d/centos8.repo ===   ls -l /etc/pki/rpm-gpg  rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-8   rpm -qa gpg-pubkey* | grep -i f4a80eb5   curl https://vault.centos.org/RPM-GPG-KEY-CentOS-7 -o /tmp/RPM-GPG-KEY-CentOS-8   curl --fail -s https://vault.centos.org/RPM-GPG-KEY-CentOS-7 -o /tmp/RPM-GPG-KEY-CentOS-8  if [ $? -ne 0 ] ; then echo &amp;quot;FAIL&amp;quot; ; fi   rpm --import /tmp/RPM-GPG-KEY-CentOS-8   rpm -qa gpg-pubkey* | grep -i f4a80eb5    cat &amp;gt; /etc/yum.repo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== /etc/yum.repos.d/centos8.repo ===&lt;br /&gt;
&lt;br /&gt;
 ls -l /etc/pki/rpm-gpg&lt;br /&gt;
 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-8&lt;br /&gt;
&lt;br /&gt;
 rpm -qa gpg-pubkey* | grep -i f4a80eb5&lt;br /&gt;
&lt;br /&gt;
 curl https://vault.centos.org/RPM-GPG-KEY-CentOS-7 -o /tmp/RPM-GPG-KEY-CentOS-8&lt;br /&gt;
&lt;br /&gt;
 curl --fail -s https://vault.centos.org/RPM-GPG-KEY-CentOS-7 -o /tmp/RPM-GPG-KEY-CentOS-8&lt;br /&gt;
 if [ $? -ne 0 ] ; then echo &amp;quot;FAIL&amp;quot; ; fi&lt;br /&gt;
&lt;br /&gt;
 rpm --import /tmp/RPM-GPG-KEY-CentOS-8&lt;br /&gt;
&lt;br /&gt;
 rpm -qa gpg-pubkey* | grep -i f4a80eb5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 cat &amp;gt; /etc/yum.repos.d/centos8.repo &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[BaseOS]&lt;br /&gt;
name=CentOS-8.5.2111 - BaseOS&lt;br /&gt;
baseurl=http://vault.centos.org/8.5.2111/BaseOS/$basearch/os/&lt;br /&gt;
enabled=1&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&lt;br /&gt;
[AppStream]&lt;br /&gt;
name=CentOS-8.5.2111 - AppStream&lt;br /&gt;
baseurl=http://vault.centos.org/8.5.2111/AppStream/$basearch/os/&lt;br /&gt;
enabled=1&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&lt;br /&gt;
[PowerTools]&lt;br /&gt;
name=CentOS-8.5.2111 - PowerTools&lt;br /&gt;
baseurl=http://vault.centos.org/8.5.2111/PowerTools/$basearch/os/&lt;br /&gt;
enabled=0&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 EOF&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/7/Yum&amp;diff=10115</id>
		<title>CentOS/7/Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/7/Yum&amp;diff=10115"/>
		<updated>2026-07-31T08:38:56Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== /etc/yum.repos.d/centos7.repo ==   ls -l /etc/pki/rpm-gpg  rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7  rpm -qa gpg-pubkey* | grep -i f4a80eb5   curl --fail -s -o /tmp/RPM-GPG-KEY-CentOS-7 \     https://vault.centos.org/RPM-GPG-KEY-CentOS-7   rpm --import /tmp/RPM-GPG-KEY-CentOS-7  &amp;lt;pre&amp;gt; [base] name=CentOS-$releasever - Base baseurl=http://vault.centos.org/7.9.2009/os/$basearch/ gpgcheck=1 enabled=1  [updates] name=CentOS-$releasever - Updates baseurl=http://va...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== /etc/yum.repos.d/centos7.repo ==&lt;br /&gt;
&lt;br /&gt;
 ls -l /etc/pki/rpm-gpg&lt;br /&gt;
 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7&lt;br /&gt;
 rpm -qa gpg-pubkey* | grep -i f4a80eb5&lt;br /&gt;
&lt;br /&gt;
 curl --fail -s -o /tmp/RPM-GPG-KEY-CentOS-7 \&lt;br /&gt;
    https://vault.centos.org/RPM-GPG-KEY-CentOS-7&lt;br /&gt;
&lt;br /&gt;
 rpm --import /tmp/RPM-GPG-KEY-CentOS-7&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[base]&lt;br /&gt;
name=CentOS-$releasever - Base&lt;br /&gt;
baseurl=http://vault.centos.org/7.9.2009/os/$basearch/&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
enabled=1&lt;br /&gt;
&lt;br /&gt;
[updates]&lt;br /&gt;
name=CentOS-$releasever - Updates&lt;br /&gt;
baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
enabled=1&lt;br /&gt;
&lt;br /&gt;
[extras]&lt;br /&gt;
name=CentOS-$releasever - Extras&lt;br /&gt;
baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/&lt;br /&gt;
gpgcheck=1&lt;br /&gt;
enabled=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10114</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10114"/>
		<updated>2026-07-29T10:09:38Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Workflow Run */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
NOTE: To sneak a run in that is not in the default branch, just temporarily add a:&lt;br /&gt;
 on:&lt;br /&gt;
   push&lt;br /&gt;
&lt;br /&gt;
Trigger workflow run:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: the INPUTS names do appear to be case sensitive!!&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
=== Workflow Run List ===&lt;br /&gt;
&lt;br /&gt;
To see runs for this workflow, try:&lt;br /&gt;
 gh run list --workflow=test.yaml&lt;br /&gt;
&lt;br /&gt;
In JSON Format:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId&lt;br /&gt;
&lt;br /&gt;
Limit to last run:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId -L 1&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId --limit 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSON Fields:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Available fields:&lt;br /&gt;
  conclusion&lt;br /&gt;
  createdAt&lt;br /&gt;
  databaseId&lt;br /&gt;
  displayTitle&lt;br /&gt;
  event&lt;br /&gt;
  headBranch&lt;br /&gt;
  headSha&lt;br /&gt;
  name&lt;br /&gt;
  number&lt;br /&gt;
  startedAt&lt;br /&gt;
  status&lt;br /&gt;
  updatedAt&lt;br /&gt;
  url&lt;br /&gt;
  workflowDatabaseId&lt;br /&gt;
  workflowName&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;databaseId&amp;quot;: 304415075xx,&lt;br /&gt;
    &amp;quot;displayTitle&amp;quot;: &amp;quot;Test test&amp;quot;,&lt;br /&gt;
    &amp;quot;url&amp;quot;: &amp;quot;https://github.com/myorg/myrepo/actions/runs/304415075xx&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10113</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10113"/>
		<updated>2026-07-29T10:09:26Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Workflow Run */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
NOTE: To sneak a run in that is not in the default branch, just temporarily add a:&lt;br /&gt;
 on:&lt;br /&gt;
   push&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: the INPUTS names do appear to be case sensitive!!&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
=== Workflow Run List ===&lt;br /&gt;
&lt;br /&gt;
To see runs for this workflow, try:&lt;br /&gt;
 gh run list --workflow=test.yaml&lt;br /&gt;
&lt;br /&gt;
In JSON Format:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId&lt;br /&gt;
&lt;br /&gt;
Limit to last run:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId -L 1&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId --limit 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSON Fields:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Available fields:&lt;br /&gt;
  conclusion&lt;br /&gt;
  createdAt&lt;br /&gt;
  databaseId&lt;br /&gt;
  displayTitle&lt;br /&gt;
  event&lt;br /&gt;
  headBranch&lt;br /&gt;
  headSha&lt;br /&gt;
  name&lt;br /&gt;
  number&lt;br /&gt;
  startedAt&lt;br /&gt;
  status&lt;br /&gt;
  updatedAt&lt;br /&gt;
  url&lt;br /&gt;
  workflowDatabaseId&lt;br /&gt;
  workflowName&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;databaseId&amp;quot;: 304415075xx,&lt;br /&gt;
    &amp;quot;displayTitle&amp;quot;: &amp;quot;Test test&amp;quot;,&lt;br /&gt;
    &amp;quot;url&amp;quot;: &amp;quot;https://github.com/myorg/myrepo/actions/runs/304415075xx&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10112</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10112"/>
		<updated>2026-07-29T10:08:31Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Workflow Run List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: the INPUTS names do appear to be case sensitive!!&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
=== Workflow Run List ===&lt;br /&gt;
&lt;br /&gt;
To see runs for this workflow, try:&lt;br /&gt;
 gh run list --workflow=test.yaml&lt;br /&gt;
&lt;br /&gt;
In JSON Format:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId&lt;br /&gt;
&lt;br /&gt;
Limit to last run:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId -L 1&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId --limit 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSON Fields:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Available fields:&lt;br /&gt;
  conclusion&lt;br /&gt;
  createdAt&lt;br /&gt;
  databaseId&lt;br /&gt;
  displayTitle&lt;br /&gt;
  event&lt;br /&gt;
  headBranch&lt;br /&gt;
  headSha&lt;br /&gt;
  name&lt;br /&gt;
  number&lt;br /&gt;
  startedAt&lt;br /&gt;
  status&lt;br /&gt;
  updatedAt&lt;br /&gt;
  url&lt;br /&gt;
  workflowDatabaseId&lt;br /&gt;
  workflowName&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;databaseId&amp;quot;: 304415075xx,&lt;br /&gt;
    &amp;quot;displayTitle&amp;quot;: &amp;quot;Test test&amp;quot;,&lt;br /&gt;
    &amp;quot;url&amp;quot;: &amp;quot;https://github.com/myorg/myrepo/actions/runs/304415075xx&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10111</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10111"/>
		<updated>2026-07-29T10:07:48Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Workflow Run List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: the INPUTS names do appear to be case sensitive!!&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
=== Workflow Run List ===&lt;br /&gt;
&lt;br /&gt;
To see runs for this workflow, try:&lt;br /&gt;
 gh run list --workflow=test.yaml&lt;br /&gt;
&lt;br /&gt;
In JSON Format:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId&lt;br /&gt;
&lt;br /&gt;
Limit to last run:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId -L 1&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId --limit 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSON Fields:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Available fields:&lt;br /&gt;
  conclusion&lt;br /&gt;
  createdAt&lt;br /&gt;
  databaseId&lt;br /&gt;
  displayTitle&lt;br /&gt;
  event&lt;br /&gt;
  headBranch&lt;br /&gt;
  headSha&lt;br /&gt;
  name&lt;br /&gt;
  number&lt;br /&gt;
  startedAt&lt;br /&gt;
  status&lt;br /&gt;
  updatedAt&lt;br /&gt;
  url&lt;br /&gt;
  workflowDatabaseId&lt;br /&gt;
  workflowName&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10110</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10110"/>
		<updated>2026-07-29T10:06:19Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Workflow Run List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: the INPUTS names do appear to be case sensitive!!&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
=== Workflow Run List ===&lt;br /&gt;
&lt;br /&gt;
To see runs for this workflow, try:&lt;br /&gt;
 gh run list --workflow=test.yaml&lt;br /&gt;
&lt;br /&gt;
In JSON Format:&lt;br /&gt;
 gh run list --workflow=test.yaml --json=displayTitle,url,databaseId&lt;br /&gt;
&lt;br /&gt;
JSON Fields:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Available fields:&lt;br /&gt;
  conclusion&lt;br /&gt;
  createdAt&lt;br /&gt;
  databaseId&lt;br /&gt;
  displayTitle&lt;br /&gt;
  event&lt;br /&gt;
  headBranch&lt;br /&gt;
  headSha&lt;br /&gt;
  name&lt;br /&gt;
  number&lt;br /&gt;
  startedAt&lt;br /&gt;
  status&lt;br /&gt;
  updatedAt&lt;br /&gt;
  url&lt;br /&gt;
  workflowDatabaseId&lt;br /&gt;
  workflowName&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10109</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10109"/>
		<updated>2026-07-29T09:54:47Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Workflow Run */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: the INPUTS names do appear to be case sensitive!!&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
=== Workflow Run List ===&lt;br /&gt;
&lt;br /&gt;
To see runs for this workflow, try:&lt;br /&gt;
 gh run list --workflow=test.yaml&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10108</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10108"/>
		<updated>2026-07-29T09:32:14Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* COMMAND LIST */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Workflow Run ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gh workflow run [&amp;lt;workflow-id&amp;gt; | &amp;lt;workflow-name&amp;gt;] [flags]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Have gh prompt you for what workflow you&#039;d like to run and interactively collect inputs&lt;br /&gt;
$ gh workflow run&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at the remote&#039;s default branch&lt;br /&gt;
$ gh workflow run triage.yml&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; at a specified ref&lt;br /&gt;
$ gh workflow run triage.yml --ref my-branch&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with command line inputs&lt;br /&gt;
$ gh workflow run triage.yml -f name=scully -f greeting=hello&lt;br /&gt;
&lt;br /&gt;
# Run the workflow file &#039;triage.yml&#039; with JSON via standard input&lt;br /&gt;
$ echo &#039;{&amp;quot;name&amp;quot;:&amp;quot;scully&amp;quot;, &amp;quot;greeting&amp;quot;:&amp;quot;hello&amp;quot;}&#039; | gh workflow run triage.yml --json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
reference: https://cli.github.com/manual/gh_workflow_run&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10107</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10107"/>
		<updated>2026-07-29T09:30:42Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* GH_TOKEN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10106</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10106"/>
		<updated>2026-07-29T09:29:45Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* keywords */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== COMMAND LIST ==&lt;br /&gt;
&lt;br /&gt;
Manual:&lt;br /&gt;
 https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh --help&lt;br /&gt;
Work seamlessly with GitHub from the command line.&lt;br /&gt;
&lt;br /&gt;
USAGE&lt;br /&gt;
  gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; [flags]&lt;br /&gt;
&lt;br /&gt;
CORE COMMANDS&lt;br /&gt;
  auth:        Authenticate gh and git with GitHub&lt;br /&gt;
  browse:      Open the repository in the browser&lt;br /&gt;
  codespace:   Connect to and manage codespaces&lt;br /&gt;
  gist:        Manage gists&lt;br /&gt;
  issue:       Manage issues&lt;br /&gt;
  org:         Manage organizations&lt;br /&gt;
  pr:          Manage pull requests&lt;br /&gt;
  release:     Manage releases&lt;br /&gt;
  repo:        Manage repositories&lt;br /&gt;
&lt;br /&gt;
GITHUB ACTIONS COMMANDS&lt;br /&gt;
  run:         View details about workflow runs&lt;br /&gt;
  workflow:    View details about GitHub Actions workflows&lt;br /&gt;
&lt;br /&gt;
ALIAS COMMANDS&lt;br /&gt;
  co:          Alias for &amp;quot;pr checkout&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ADDITIONAL COMMANDS&lt;br /&gt;
  alias:       Create command shortcuts&lt;br /&gt;
  api:         Make an authenticated GitHub API request&lt;br /&gt;
  completion:  Generate shell completion scripts&lt;br /&gt;
  config:      Manage configuration for gh&lt;br /&gt;
  extension:   Manage gh extensions&lt;br /&gt;
  gpg-key:     Manage GPG keys&lt;br /&gt;
  label:       Manage labels&lt;br /&gt;
  search:      Search for repositories, issues, and pull requests&lt;br /&gt;
  secret:      Manage GitHub secrets&lt;br /&gt;
  ssh-key:     Manage SSH keys&lt;br /&gt;
  status:      Print information about relevant issues, pull requests, and notifications across repositories&lt;br /&gt;
  variable:    Manage GitHub Actions variables&lt;br /&gt;
&lt;br /&gt;
HELP TOPICS&lt;br /&gt;
  actions:     Learn about working with GitHub Actions&lt;br /&gt;
  environment: Environment variables that can be used with gh&lt;br /&gt;
  exit-codes:  Exit codes used by gh&lt;br /&gt;
  formatting:  Formatting options for JSON data exported from gh&lt;br /&gt;
  mintty:      Information about using gh with MinTTY&lt;br /&gt;
  reference:   A comprehensive reference of all gh commands&lt;br /&gt;
&lt;br /&gt;
FLAGS&lt;br /&gt;
  --help      Show help for command&lt;br /&gt;
  --version   Show gh version&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  $ gh issue create&lt;br /&gt;
  $ gh repo clone cli/cli&lt;br /&gt;
  $ gh pr checkout 321&lt;br /&gt;
&lt;br /&gt;
LEARN MORE&lt;br /&gt;
  Use &#039;gh &amp;lt;command&amp;gt; &amp;lt;subcommand&amp;gt; --help&#039; for more information about a command.&lt;br /&gt;
  Read the manual at https://cli.github.com/manual&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/Workflow&amp;diff=10105</id>
		<title>GitHub/Workflow</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/Workflow&amp;diff=10105"/>
		<updated>2026-07-29T09:23:42Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* keywords */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GitHub Actions Workflow ==&lt;br /&gt;
&lt;br /&gt;
== Starter Workflows ==&lt;br /&gt;
&lt;br /&gt;
 Quickstart for GitHub Actions - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/quickstart&lt;br /&gt;
&lt;br /&gt;
 actions/starter-workflows: Accelerating new GitHub Actions workflows&lt;br /&gt;
 https://github.com/actions/starter-workflows&lt;br /&gt;
&lt;br /&gt;
 GitHub Marketplace - Actions&lt;br /&gt;
 https://github.com/marketplace?category=&amp;amp;query=&amp;amp;type=actions&amp;amp;verification=&lt;br /&gt;
&lt;br /&gt;
== Manual Run ==&lt;br /&gt;
&lt;br /&gt;
manual.yaml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Manual Run&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      LABEL:&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
        description: label&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    runs-on: ${{ inputs.LABEL }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== workflow dispatch limits ==&lt;br /&gt;
&lt;br /&gt;
https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_dispatch&lt;br /&gt;
&lt;br /&gt;
Limits:&lt;br /&gt;
* The maximum number of top-level properties for inputs is 10.&lt;br /&gt;
* The maximum payload for inputs is 65,535 characters.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Immediately Fail on Non Zero Return Code ==&lt;br /&gt;
&lt;br /&gt;
 # exit on error temporarily&lt;br /&gt;
 set -e&lt;br /&gt;
&lt;br /&gt;
 # disable exitting on error temporarily&lt;br /&gt;
 set +e&lt;br /&gt;
&lt;br /&gt;
== Multiline GITHUB_OUTPUT ==&lt;br /&gt;
&lt;br /&gt;
=== Bash ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Set multiline output&lt;br /&gt;
  id: example_step&lt;br /&gt;
  run: |&lt;br /&gt;
    # 1. Define your multiline content&lt;br /&gt;
    CONTENT=$(printf &amp;quot;Line 1\nLine 2\nLine 3&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    # 2. Append to GITHUB_OUTPUT using a delimiter&lt;br /&gt;
    echo &amp;quot;MY_OUTPUT&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
    echo &amp;quot;$CONTENT&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
    echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- name: Use the output&lt;br /&gt;
  run: echo &amp;quot;${{ steps.example_step.outputs.MY_OUTPUT }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
# The multiline content you want to save&lt;br /&gt;
multiline_string = &amp;quot;&amp;quot;&amp;quot;Line 1: Hello&lt;br /&gt;
Line 2: World&lt;br /&gt;
Line 3: From Python&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Define a unique delimiter&lt;br /&gt;
delimiter = &amp;quot;EOF&amp;quot;&lt;br /&gt;
output_file = os.getenv(&#039;GITHUB_OUTPUT&#039;)&lt;br /&gt;
&lt;br /&gt;
with open(output_file, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
    f.write(f&amp;quot;my_output&amp;lt;&amp;lt;{delimiter}\n&amp;quot;)&lt;br /&gt;
    f.write(f&amp;quot;{multiline_string}\n&amp;quot;)&lt;br /&gt;
    f.write(f&amp;quot;{delimiter}\n&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      - name: Some Automation&lt;br /&gt;
        id: some-automation&lt;br /&gt;
        run: |&lt;br /&gt;
            ...&lt;br /&gt;
        shell: python&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change Run Name with Input ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Nodecheck&lt;br /&gt;
run-name: Nodecheck for ${{ inputs.RUNNER_LABEL }}&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      RUNNER_LABEL:&lt;br /&gt;
        description: Name of runner to target&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    inputs:&lt;br /&gt;
      RUNNER_LABEL:&lt;br /&gt;
        required: true&lt;br /&gt;
        type: string&lt;br /&gt;
        description: Name of runner to target&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    uses: some-org/some-repo/.github/workflows/nodecheck.yaml@latest&lt;br /&gt;
    with:&lt;br /&gt;
      RUNNER_LABEL: ${{ inputs.RUNNER_LABEL }}&lt;br /&gt;
    secrets: inherit&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== On Pull Request ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: On Pull Request&lt;br /&gt;
on:&lt;br /&gt;
  pull_request:&lt;br /&gt;
    types: [opened, reopened]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  test:&lt;br /&gt;
    runs-on: [ubuntu-latest]&lt;br /&gt;
    steps:&lt;br /&gt;
      - name: do something&lt;br /&gt;
        shell: bash&lt;br /&gt;
        run: |&lt;br /&gt;
          echo &amp;quot;hi&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== On Label Change ==&lt;br /&gt;
&lt;br /&gt;
Note: Must have event in &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: On Label&lt;br /&gt;
on:&lt;br /&gt;
  pull_request:&lt;br /&gt;
    types:&lt;br /&gt;
      - labeled&lt;br /&gt;
jobs:&lt;br /&gt;
  label-job:&lt;br /&gt;
    if: &amp;quot;github.event.label.name == &#039;run-mylabel&#039;&amp;quot;&lt;br /&gt;
    uses: myorg/myrepo/.github/workflows/dolabel.yaml@v2&lt;br /&gt;
    with:&lt;br /&gt;
      VAR1: VAR1&lt;br /&gt;
    secrets: inherit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic Workflow ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: GitHub Actions Demo&lt;br /&gt;
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀&lt;br /&gt;
on: [push]&lt;br /&gt;
jobs:&lt;br /&gt;
  Explore-GitHub-Actions:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;🎉 The job was automatically triggered by a ${{ github.event_name }} event.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}.&amp;quot;&lt;br /&gt;
      - name: Check out repository code&lt;br /&gt;
        uses: actions/checkout@v3&lt;br /&gt;
      - run: echo &amp;quot;💡 The ${{ github.repository }} repository has been cloned to the runner.&amp;quot;&lt;br /&gt;
      - run: echo &amp;quot;🖥️ The workflow is now ready to test your code on the runner.&amp;quot;&lt;br /&gt;
      - name: List files in the repository&lt;br /&gt;
        run: |&lt;br /&gt;
          ls ${{ github.workspace }}&lt;br /&gt;
      - run: echo &amp;quot;🍏 This job&#039;s status is ${{ job.status }}.&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://docs.github.com/en/actions/quickstart&lt;br /&gt;
&lt;br /&gt;
== Using Job Output ==&lt;br /&gt;
&lt;br /&gt;
if you want to export the job output from the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: CI Precommit Automation Pipeline - Get Builds&lt;br /&gt;
on:&lt;br /&gt;
  workflow_call:&lt;br /&gt;
    inputs:&lt;br /&gt;
      ...&lt;br /&gt;
    outputs:&lt;br /&gt;
      output1: ${{ jobs.job1.outputs.output1 }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job outputs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    # Map a step output to a job output&lt;br /&gt;
    outputs:&lt;br /&gt;
      output1: ${{ steps.step1.outputs.test }}&lt;br /&gt;
      output2: ${{ steps.step2.outputs.test }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - id: step1&lt;br /&gt;
        run: echo &amp;quot;test=hello&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
      - id: step2&lt;br /&gt;
        run: echo &amp;quot;test=world&amp;quot; &amp;gt;&amp;gt; &amp;quot;$GITHUB_OUTPUT&amp;quot;&lt;br /&gt;
      - id: step3&lt;br /&gt;
        run: echo &amp;quot;I see step1: ${{ steps.step1.outputs.test }}&lt;br /&gt;
  job2:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    needs: job1&lt;br /&gt;
    steps:&lt;br /&gt;
      - env:&lt;br /&gt;
          OUTPUT1: ${{needs.job1.outputs.output1}}&lt;br /&gt;
          OUTPUT2: ${{needs.job1.outputs.output2}}&lt;br /&gt;
        run: echo &amp;quot;$OUTPUT1 $OUTPUT2&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: Defining outputs for jobs - GitHub Enterprise Cloud Docs - https://docs.github.com/en/enterprise-cloud@latest/actions/using-jobs/defining-outputs-for-jobs&lt;br /&gt;
&lt;br /&gt;
Multi-line output: &amp;lt;ref&amp;gt;https://github.com/github/docs/issues/21529&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    run: |&lt;br /&gt;
      echo &#039;JSON_RESPONSE&amp;lt;&amp;lt;EOF&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
      curl https://example.lab &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
      echo &#039;EOF&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python version job output ===&lt;br /&gt;
&lt;br /&gt;
Python version: &amp;lt;ref&amp;gt;https://github.com/orgs/community/discussions/28146&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
  print(f&#039;{SOME}={THING}&#039;, file=fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def set_output(name, value):&lt;br /&gt;
    with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
        print(f&#039;{name}={value}&#039;, file=fh)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Multi lined version:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import uuid&lt;br /&gt;
&lt;br /&gt;
def set_multiline_output(name, value):&lt;br /&gt;
    with open(os.environ[&#039;GITHUB_OUTPUT&#039;], &#039;a&#039;) as fh:&lt;br /&gt;
        delimiter = uuid.uuid1()&lt;br /&gt;
        print(f&#039;{name}&amp;lt;&amp;lt;{delimiter}&#039;, file=fh)&lt;br /&gt;
        print(value, file=fh)&lt;br /&gt;
        print(delimiter, file=fh)&lt;br /&gt;
&lt;br /&gt;
# call example:&lt;br /&gt;
set_multiline_output(&amp;quot;value&amp;quot;, my_multiline_string)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Runs-on ==&lt;br /&gt;
&lt;br /&gt;
Dynamic from Input:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Labels&lt;br /&gt;
run-name: Dynamic Labels&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      LABELS:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
        default: &amp;quot;[ \&amp;quot;CI\&amp;quot; ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run:&lt;br /&gt;
    # runs-on: ${{ fromJSON( &#039;[&amp;quot;CI&amp;quot;]&#039; ) }}  # This works&lt;br /&gt;
    # runs-on: ${{ fromJSON( &#039;[&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;]&#039; ) }}  # This works&lt;br /&gt;
    runs-on: ${{ fromJSON( inputs.LABELS ) }}  # This works if formatted like: [&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;]&lt;br /&gt;
    # runs-on: ${{ inputs.LABELS }}  # this works for single label&lt;br /&gt;
    # runs-on: [ CI, MORE ]  # this works&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic from script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Script&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      RUNS: ${{ steps.set-RUNS.outputs.RUNS }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-RUNS&lt;br /&gt;
      run: echo &amp;quot;RUNS=[\&amp;quot;CI\&amp;quot;,\&amp;quot;MORE\&amp;quot;]&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  job2:&lt;br /&gt;
    needs: job1&lt;br /&gt;
    runs-on: ${{fromJSON(needs.job1.outputs.RUNS)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* How to Dynamically assign the runs-on value in the github actions - Stack Overflow - https://stackoverflow.com/questions/73241812/how-to-dynamically-assign-the-runs-on-value-in-the-github-actions&lt;br /&gt;
* Github Actions: How use strategy/matrix with script - Stack Overflow - https://stackoverflow.com/questions/59977364/github-actions-how-use-strategy-matrix-with-script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- todo ---&lt;br /&gt;
&lt;br /&gt;
ideas:&lt;br /&gt;
 runs-on: ${{ fromJson(format(&#039;[{0}]&#039;, github.event.inputs.LABELS)) }}&lt;br /&gt;
&lt;br /&gt;
this will work if labels is a string of quoted labels: &amp;quot;a&amp;quot;,&amp;quot;b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Sadness - if the actions expressions supported a &amp;quot;replace()&amp;quot; function, could have the comma replace with a &amp;quot;,&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #1 ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ &amp;quot;include&amp;quot;: [&lt;br /&gt;
    {&amp;quot;runson&amp;quot;: [&amp;quot;CI&amp;quot;, &amp;quot;MORE&amp;quot;],&lt;br /&gt;
     &amp;quot;task&amp;quot;: &amp;quot;joe&amp;quot;},&lt;br /&gt;
    {&amp;quot;runson&amp;quot;: [&amp;quot;CI&amp;quot;, &amp;quot;LESS&amp;quot;],&lt;br /&gt;
     &amp;quot;task&amp;quot;: &amp;quot;bob&amp;quot;}&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  generate:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      MATRIX: ${{ steps.set-MATRIX.outputs.MATRIX }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-MATRIX&lt;br /&gt;
      run: echo &amp;quot;MATRIX={\&amp;quot;include\&amp;quot;:[{\&amp;quot;runson\&amp;quot;:[\&amp;quot;CI\&amp;quot;,\&amp;quot;MORE\&amp;quot;],\&amp;quot;task\&amp;quot;:\&amp;quot;joe\&amp;quot;},{\&amp;quot;runson\&amp;quot;:[\&amp;quot;CI\&amp;quot;,\&amp;quot;LESS\&amp;quot;],\&amp;quot;task\&amp;quot;:\&amp;quot;bob\&amp;quot;}]}&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  jober:&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runson }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix: ${{fromJson(needs.generate.outputs.matrix)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: hostname&lt;br /&gt;
    - run: echo ${{ matrix.runson }}&lt;br /&gt;
    - run: echo ${{ matrix.task }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will generate 2 sub jobs:&lt;br /&gt;
* jober (CI, MORE, joe)&lt;br /&gt;
** Requested labels: CI, MORE&lt;br /&gt;
* jober (CI, LESS, bob)&lt;br /&gt;
** Requested labels: CI, LESS&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #2 ==&lt;br /&gt;
&lt;br /&gt;
Matrix Multiplier --- THIS WILL TRY EVERY EVERY EVERY COMBINATION!!!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
color  = [ &amp;quot;red&amp;quot;,   &amp;quot;blue&amp;quot;,  &amp;quot;yellow&amp;quot; ]&lt;br /&gt;
fruit  = [ &amp;quot;apple&amp;quot;, &amp;quot;berry&amp;quot;,  &amp;quot;banana&amp;quot; ]&lt;br /&gt;
runner = [ &amp;quot;CI&amp;quot;,    &amp;quot;CI&amp;quot;,      [&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jobs will be generated in a matrix multipler like so:&lt;br /&gt;
* ci_red_apple_CI&lt;br /&gt;
** Requested labels: CI&lt;br /&gt;
* ci_red_app_CD&lt;br /&gt;
** Requested labels: CD&lt;br /&gt;
* ci_red_apple_Array&lt;br /&gt;
** Requested labels: Linux, Automation   (note: [&amp;quot;Linux, Automation&amp;quot;] output to the name as &amp;quot;Array&amp;quot;)&lt;br /&gt;
* ci_blue_apple_CI&lt;br /&gt;
* ci_blue_apple_CD&lt;br /&gt;
* ci_blue_apple_Array&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
* etc...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  generate:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      color: ${{ steps.set-matrix.outputs.color }}&lt;br /&gt;
      fruit: ${{ steps.set-matrix.outputs.fruit }}&lt;br /&gt;
      runner: ${{ steps.set-matrix.outputs.runner }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: &amp;gt;&lt;br /&gt;
        echo &#039;color=[&amp;quot;red&amp;quot;, &amp;quot;berry&amp;quot;, &amp;quot;yellow&amp;quot;]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;fruit=[&amp;quot;apple&amp;quot;, &amp;quot;blue&amp;quot;, &amp;quot;banana&amp;quot;]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;runner=[&amp;quot;CI&amp;quot;, &amp;quot;CD&amp;quot;, [&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;] ]&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&lt;br /&gt;
  jober:&lt;br /&gt;
    name: ci_${{ matrix.color }}_${{ matrix.fruit }}_${{ matrix.runner }}&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runner }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        color: ${{fromJson(needs.generate.outputs.color)}}&lt;br /&gt;
        fruit: ${{fromJson(needs.generate.outputs.fruit)}}&lt;br /&gt;
        runner: ${{fromJson(needs.generate.outputs.runner)}}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: &amp;gt;&lt;br /&gt;
        echo &amp;quot;FRUIT: ${{ matrix.fruit }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;COLOR: ${{ matrix.color }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;RUNNER: ${{ matrix.runner }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dynamic Jobs #3 ==&lt;br /&gt;
&lt;br /&gt;
Seems like the perfect option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include:&lt;br /&gt;
[&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,    &amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,  &amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;                    },&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,   &amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,  &amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;                    },&lt;br /&gt;
 { &amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;, &amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;, &amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;] }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jobs will be generated in a matrix multipler like so:&lt;br /&gt;
* ci_red_apple_CI&lt;br /&gt;
** Requested labels: CI&lt;br /&gt;
* ci_blue_berry_CD&lt;br /&gt;
** Requested labels: CD&lt;br /&gt;
* ci_yellow_banana_Array&lt;br /&gt;
** Requested labels: Linux, Automation   (note: [&amp;quot;Linux, Automation&amp;quot;] output to the name as &amp;quot;Array&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: Dynamic Jobs&lt;br /&gt;
run-name: Test&lt;br /&gt;
on:&lt;br /&gt;
  workflow_dispatch:&lt;br /&gt;
    inputs:&lt;br /&gt;
      Go:&lt;br /&gt;
        required: false&lt;br /&gt;
        type: string&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  # automation-matrix:&lt;br /&gt;
  generate:&lt;br /&gt;
    # name: automation-matrix&lt;br /&gt;
    # needs: [ some-requirements ]&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      matrixgen: ${{ steps.set-matrix.outputs.matrixgen }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: |&lt;br /&gt;
        tmp=$(mktemp)&lt;br /&gt;
        echo &amp;quot;[&amp;quot; &amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;},&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;},&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;,&amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]}&#039; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
        echo &amp;quot;]&amp;quot; &amp;gt;&amp;gt; $tmp&lt;br /&gt;
&lt;br /&gt;
        cat $tmp&lt;br /&gt;
        echo &amp;quot;matrixgen&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        cat $tmp &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        rm -f $tmp&lt;br /&gt;
&lt;br /&gt;
  automation:&lt;br /&gt;
    # name: ${{ matrix.name }}&lt;br /&gt;
    name: ci_${{ matrix.color }}_${{ matrix.fruit }}_${{ matrix.runner }}&lt;br /&gt;
    needs: generate&lt;br /&gt;
    runs-on: ${{ matrix.runner }}&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        include: ${{ fromJson(needs.generate.outputs.matrixgen) }}&lt;br /&gt;
    steps:&lt;br /&gt;
    - run: |&lt;br /&gt;
        echo &amp;quot;FRUIT: ${{ matrix.fruit }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;COLOR: ${{ matrix.color }}&amp;quot;&lt;br /&gt;
        echo &amp;quot;RUNNER: ${{ matrix.runner }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The file processor could also be done in-line, but generally it makes more sense to process a file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    - id: set-matrix&lt;br /&gt;
      run: |&lt;br /&gt;
        echo &amp;quot;matrixgen&amp;lt;&amp;lt;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;[&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;apple&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CI&amp;quot;},&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;berry&amp;quot;,&amp;quot;runner&amp;quot;:&amp;quot;CD&amp;quot;},&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &#039;{&amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;fruit&amp;quot;:&amp;quot;banana&amp;quot;,&amp;quot;runner&amp;quot;:[&amp;quot;Linux&amp;quot;, &amp;quot;Automation&amp;quot;]}&#039; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;]&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
        echo &amp;quot;EOF&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Official Dynamic Job Examples ==&lt;br /&gt;
&lt;br /&gt;
Reference: https://docs.github.com/en/actions/learn-github-actions/expressions#example-returning-a-json-object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name: build&lt;br /&gt;
on: push&lt;br /&gt;
jobs:&lt;br /&gt;
  job1:&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    outputs:&lt;br /&gt;
      matrix: ${{ steps.set-matrix.outputs.matrix }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - id: set-matrix&lt;br /&gt;
        run: echo &amp;quot;matrix={\&amp;quot;include\&amp;quot;:[{\&amp;quot;project\&amp;quot;:\&amp;quot;foo\&amp;quot;,\&amp;quot;config\&amp;quot;:\&amp;quot;Debug\&amp;quot;},{\&amp;quot;project\&amp;quot;:\&amp;quot;bar\&amp;quot;,\&amp;quot;config\&amp;quot;:\&amp;quot;Release\&amp;quot;}]}&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;br /&gt;
  job2:&lt;br /&gt;
    needs: job1&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - run: echo &amp;quot;Matrix - Project ${{ matrix.project }}, Config ${{ matrix.config }}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jobs:&lt;br /&gt;
  example_matrix:&lt;br /&gt;
    strategy:&lt;br /&gt;
      matrix:&lt;br /&gt;
        os: [ubuntu-22.04, ubuntu-20.04]&lt;br /&gt;
        version: [10, 12, 14]&lt;br /&gt;
    runs-on: ${{ matrix.os }}&lt;br /&gt;
    steps:&lt;br /&gt;
      - uses: actions/setup-node@v4&lt;br /&gt;
        with:&lt;br /&gt;
          node-version: ${{ matrix.version }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Remotely Trigger Workflow - repository_dispatch ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
    types: [some_event_type]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 curl -X POST https://api.github.com/repos/OWNER/REPO/dispatches -H &amp;quot;Authorization: Bearer ${GH_TOKEN}&amp;quot; -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;some_event_type&amp;quot;}&#039;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 curl -X POST https://api.github.com/repos/ORG/REPO/dispatches -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;some_event_type&amp;quot;}&#039;&lt;br /&gt;
  #  -d or --data, -X or --request&lt;br /&gt;
  #  -H &amp;quot;Accept: application/vnd.github.v3+json&amp;quot;&lt;br /&gt;
  #  -H &amp;quot;Accept: application/vnd.github+json&amp;quot;&lt;br /&gt;
  # You will most likely need to also pass along auth: (unless you are silly and on a publicly executable workflow?)&lt;br /&gt;
  # -H &amp;quot;Authorization: Bearer $GITHUB_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 curl -L \&lt;br /&gt;
  -X POST \&lt;br /&gt;
  -H &amp;quot;Accept: application/vnd.github+json&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer &amp;lt;YOUR-TOKEN&amp;gt;&amp;quot; \&lt;br /&gt;
  -H &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; \&lt;br /&gt;
  https://api.github.com/repos/OWNER/REPO/dispatches \&lt;br /&gt;
  -d &#039;{&amp;quot;event_type&amp;quot;:&amp;quot;on-demand-test&amp;quot;,&amp;quot;client_payload&amp;quot;:{&amp;quot;unit&amp;quot;:false,&amp;quot;integration&amp;quot;:true}}&#039;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 if you want to trigger from some other branch:&lt;br /&gt;
  {...,&#039;ref&#039;:&#039;other_branch_or_ref&#039;},...}&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 repository_dispatch - Events that trigger workflows - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#repository_dispatch&lt;br /&gt;
&lt;br /&gt;
 repository_dispatch - Repositories - GitHub Docs&lt;br /&gt;
 https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
If you pass this payload through, you can limit the workflow, and access it in the workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;event_type&amp;quot;: &amp;quot;test_result&amp;quot;,&lt;br /&gt;
  &amp;quot;client_payload&amp;quot;: {&lt;br /&gt;
    &amp;quot;passed&amp;quot;: false,&lt;br /&gt;
    &amp;quot;message&amp;quot;: &amp;quot;Error: timeout&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
workflow:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on:&lt;br /&gt;
  repository_dispatch:&lt;br /&gt;
    types: [test_result]&lt;br /&gt;
&lt;br /&gt;
jobs:&lt;br /&gt;
  run_if_failure:&lt;br /&gt;
    if: ${{ !github.event.client_payload.passed }}&lt;br /&gt;
    runs-on: ubuntu-latest&lt;br /&gt;
    steps:&lt;br /&gt;
      - env:&lt;br /&gt;
          MESSAGE: ${{ github.event.client_payload.message }}&lt;br /&gt;
        run: echo $MESSAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Timeout ==&lt;br /&gt;
&lt;br /&gt;
Workflow syntax - jobs - timeout-minutes https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my-job:&lt;br /&gt;
 runs-on:         ubuntu-latest&lt;br /&gt;
 timeout-minutes: 30&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 jobs.&amp;lt;job_id&amp;gt;.timeout-minutes&lt;br /&gt;
 The maximum number of minutes to let a job run before GitHub automatically cancels it. Default: 360&lt;br /&gt;
&lt;br /&gt;
If the timeout exceeds the job execution time limit for the runner, the job will be canceled when the execution time limit is met instead. For more information about job execution time limits, see &amp;quot;Usage limits, billing, and administration&amp;quot; for GitHub-hosted runners and &amp;quot;About self-hosted runners&amp;quot; for self-hosted runner usage limits.&lt;br /&gt;
&lt;br /&gt;
Usage Limits:&lt;br /&gt;
&lt;br /&gt;
There are some limits on GitHub Actions usage when using GitHub-hosted runners. These limits are subject to change. &amp;lt;ref&amp;gt;https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#usage-limits&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Job execution time - Each job in a workflow can run for up to 6 hours of execution time. If a job reaches this limit, the job is terminated and fails to complete.&lt;br /&gt;
&lt;br /&gt;
There are some limits on GitHub Actions usage when using self-hosted runners. These limits are subject to change. &amp;lt;ref&amp;gt;https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#usage-limits&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Job execution time - Each job in a workflow can run for up to 5 days of execution time. If a job reaches this limit, the job is terminated and fails to complete.&lt;br /&gt;
&lt;br /&gt;
=== Step Timeout ===&lt;br /&gt;
&lt;br /&gt;
 jobs.&amp;lt;job_id&amp;gt;.steps[*].timeout-minutes&lt;br /&gt;
 The maximum number of minutes to run the step before killing the process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Status Check Functions ==&lt;br /&gt;
&lt;br /&gt;
 Expressions - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/actions/learn-github-actions/expressions#status-check-functions&lt;br /&gt;
&lt;br /&gt;
 How to run a github-actions step, even if the previous step fails, while still failing the job - Stack Overflow&lt;br /&gt;
 https://stackoverflow.com/questions/58858429/how-to-run-a-github-actions-step-even-if-the-previous-step-fails-while-still-f&lt;br /&gt;
&lt;br /&gt;
=== success ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: The job has succeeded&lt;br /&gt;
    if: ${{ success() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== failure ===&lt;br /&gt;
&lt;br /&gt;
Returns true when any previous step of a job fails.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: The job has failed&lt;br /&gt;
    if: ${{ failure() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with step conclusion check:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
steps:&lt;br /&gt;
  ...&lt;br /&gt;
  - name: Failing step&lt;br /&gt;
    id: demo&lt;br /&gt;
    run: exit 1&lt;br /&gt;
  - name: The demo step has failed&lt;br /&gt;
    if: ${{ failure() &amp;amp;&amp;amp; steps.demo.conclusion == &#039;failure&#039; }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== always ===&lt;br /&gt;
&lt;br /&gt;
Causes the step to always execute, and returns true, even when canceled. The always expression is best used at the step level or on tasks that you expect to run even when a job is canceled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if: ${{ always() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 if: always()&lt;br /&gt;
&lt;br /&gt;
=== cancelled ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the workflow was canceled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if: ${{ cancelled() }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pass Status to Step ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
 steps.&amp;lt;id&amp;gt;.outcome != &#039;success&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Check status step&lt;br /&gt;
  id: check-step&lt;br /&gt;
  if: success()&lt;br /&gt;
  shell: bash&lt;br /&gt;
  run: |&lt;br /&gt;
    echo &amp;quot;Workflow successful&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- name: The step to call the action&lt;br /&gt;
   if: always()&lt;br /&gt;
   uses: ./path/to/action&lt;br /&gt;
   with:&lt;br /&gt;
    some-token: ${{ inputs.some-token }}&lt;br /&gt;
    some-value: ${{ inputs.some-value }}&lt;br /&gt;
    workflow-status: ${{ steps.check-step.outcome }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: https://stackoverflow.com/questions/75987303/how-to-pass-success-or-failure-to-a-github-action-from-a-workflow&lt;br /&gt;
&lt;br /&gt;
== Automatically Retry Job ==&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* https://stackoverflow.com/questions/71574593/how-to-automatically-retry-github-action-jobs-on-failure&lt;br /&gt;
* https://github.com/orgs/community/discussions/67654&lt;br /&gt;
* https://medium.com/@aarne.laur/retry-failed-github-actions-8661e7601c66&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Test&amp;diff=10104</id>
		<title>Test</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Test&amp;diff=10104"/>
		<updated>2026-07-27T20:33:02Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Test =&lt;br /&gt;
&lt;br /&gt;
[[/test]]&lt;br /&gt;
&lt;br /&gt;
[[../test]]&lt;br /&gt;
&lt;br /&gt;
[[./test]]&lt;br /&gt;
&lt;br /&gt;
[[home]]&lt;br /&gt;
&lt;br /&gt;
Test &amp;lt;ref&amp;gt;http://www.google.com&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref&amp;gt;Hello world&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flip Text ==&lt;br /&gt;
&lt;br /&gt;
To  reverse the text, press and hold simultaneously for five seconds the Main Menu, Scroll, and Select buttons.&lt;br /&gt;
&lt;br /&gt;
https://forums.apc.com/Assets/migrated/1323_AP8841.jpg&lt;br /&gt;
&lt;br /&gt;
Ref: [https://forums.apc.com/spaces/6/racks-rack-accessories-cooling/forums/general/10030/flip-the-display-on-ap8841]&lt;br /&gt;
&lt;br /&gt;
== Markdown ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
test&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10103</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10103"/>
		<updated>2026-07-27T18:07:02Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Python 3.14 with OpenSSL 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;markdown&amp;gt;&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;br /&gt;
&amp;lt;/markdown&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10102</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10102"/>
		<updated>2026-07-27T18:06:46Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.company.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 14. Verify Corporate Certificates&lt;br /&gt;
&lt;br /&gt;
Check the complete certificate chain:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
echo | \&lt;br /&gt;
/opt/openssl-3/bin/openssl s_client \&lt;br /&gt;
-connect artifactory.company.com:443 \&lt;br /&gt;
-showcerts&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Look for:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Verify return code: 0 (ok)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 15. Verify Which OpenSSL Python Is Actually Using&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldd /opt/python3.14/bin/python3.14 | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3 =&amp;gt; /opt/openssl-3/lib64/libssl.so.3&lt;br /&gt;
libcrypto.so.3 =&amp;gt; /opt/openssl-3/lib64/libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Optional: Create Convenience Symlinks&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ln -s /opt/python3.14/bin/python3.14 /usr/local/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
ln -s /opt/python3.14/bin/pip3.14 /usr/local/bin/pip3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
python3.14 --version&lt;br /&gt;
pip3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Troubleshooting&lt;br /&gt;
&lt;br /&gt;
## SSL module missing&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
fails with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ModuleNotFoundError: No module named &#039;_ssl&#039;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Rebuild Python and verify the configure output detects:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
checking for OpenSSL ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
_ssl module... yes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Requests certificate errors&lt;br /&gt;
&lt;br /&gt;
Enable debugging:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check Certifi:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Test with OS trust store:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Final Installed Layout&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/opt/openssl-3&lt;br /&gt;
/opt/python3.14&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
&lt;br /&gt;
- Does not interfere with system Python&lt;br /&gt;
- Does not interfere with DNF&lt;br /&gt;
- Uses OpenSSL 3.x&lt;br /&gt;
- Fully supports Python 3.14 TLS features&lt;br /&gt;
- Easier troubleshooting of enterprise certificate issues&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10101</id>
		<title>CentOS/8/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/8/Python_3.14&amp;diff=10101"/>
		<updated>2026-07-27T18:05:58Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== Python 3.14 with OpenSSL 3 ==  # Python 3.14 + OpenSSL 3.x on CentOS 8  This guide installs:  - OpenSSL 3.x in `/opt/openssl-3` - Python 3.14 in `/opt/python3.14` - Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp` - Isolation from the OS Python and OpenSSL versions  This approach is recommended for environments that use:  - Corporate TLS inspection appliances - Internal Artifactory servers - Self-signed enterprise CAs - Modern TLS requirements...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 with OpenSSL 3 ==&lt;br /&gt;
&lt;br /&gt;
# Python 3.14 + OpenSSL 3.x on CentOS 8&lt;br /&gt;
&lt;br /&gt;
This guide installs:&lt;br /&gt;
&lt;br /&gt;
- OpenSSL 3.x in `/opt/openssl-3`&lt;br /&gt;
- Python 3.14 in `/opt/python3.14`&lt;br /&gt;
- Modern TLS support for Python `ssl`, `urllib`, `requests`, and `aiohttp`&lt;br /&gt;
- Isolation from the OS Python and OpenSSL versions&lt;br /&gt;
&lt;br /&gt;
This approach is recommended for environments that use:&lt;br /&gt;
&lt;br /&gt;
- Corporate TLS inspection appliances&lt;br /&gt;
- Internal Artifactory servers&lt;br /&gt;
- Self-signed enterprise CAs&lt;br /&gt;
- Modern TLS requirements&lt;br /&gt;
&lt;br /&gt;
Python 3.14 requires OpenSSL 1.1.1 or newer for SSL support. [1](https://www.python.org/downloads/release/python-3140/)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 1. Install Build Dependencies&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
dnf groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
dnf install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 2. Download and Build OpenSSL 3.x&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Build:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 3. Configure Runtime Linker&lt;br /&gt;
&lt;br /&gt;
Create:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Refresh:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected output should include:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
libssl.so.3&lt;br /&gt;
libcrypto.so.3&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 4. Download Python 3.14&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3make -j$(nproc)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 7. Install Python&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
make install&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Python 3.14.6&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 8. Verify OpenSSL Integration&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 9. Verify HTTPS Works&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL 3.5.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 10. Install Common Packages&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install \&lt;br /&gt;
    requests \&lt;br /&gt;
    aiohttp \&lt;br /&gt;
    certifi \&lt;br /&gt;
    truststore&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
/opt/python3.14/bin/pip3.14 list&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 11. Verify Requests&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://www.python.org&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expected:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
OpenSSL: OpenSSL 3.x.x&lt;br /&gt;
200&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 12. Check Python Trust Stores&lt;br /&gt;
&lt;br /&gt;
Show OpenSSL trust path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certifi path:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
This helps troubleshoot situations where:&lt;br /&gt;
&lt;br /&gt;
- `curl` works&lt;br /&gt;
- Browser works&lt;br /&gt;
- Python Requests fails&lt;br /&gt;
&lt;br /&gt;
because Requests typically uses Certifi rather than the OS trust store.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# 13. Force Requests to Use the OS Trust Store&lt;br /&gt;
&lt;br /&gt;
For enterprise environments this is often recommended.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```python&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=CentOS/7/Python_3.14&amp;diff=10100</id>
		<title>CentOS/7/Python 3.14</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=CentOS/7/Python_3.14&amp;diff=10100"/>
		<updated>2026-07-27T18:02:45Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== Python 3.14 on CentOS 7 ==  === Dependencies === &amp;lt;pre&amp;gt; sudo yum groupinstall &amp;quot;Development Tools&amp;quot; -y  sudo yum install -y \     gcc \     gcc-c++ \     make \     wget \     openssl-devel \     bzip2-devel \     libffi-devel \     zlib-devel \     readline-devel \     sqlite-devel \     xz-devel \     tk-devel \     gdbm-devel \     ncurses-devel &amp;lt;/pre&amp;gt;  === Download ===  &amp;lt;pre&amp;gt; cd /usr/src  sudo wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz  sudo tar...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python 3.14 on CentOS 7 ==&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo yum groupinstall &amp;quot;Development Tools&amp;quot; -y&lt;br /&gt;
&lt;br /&gt;
sudo yum install -y \&lt;br /&gt;
    gcc \&lt;br /&gt;
    gcc-c++ \&lt;br /&gt;
    make \&lt;br /&gt;
    wget \&lt;br /&gt;
    openssl-devel \&lt;br /&gt;
    bzip2-devel \&lt;br /&gt;
    libffi-devel \&lt;br /&gt;
    zlib-devel \&lt;br /&gt;
    readline-devel \&lt;br /&gt;
    sqlite-devel \&lt;br /&gt;
    xz-devel \&lt;br /&gt;
    tk-devel \&lt;br /&gt;
    gdbm-devel \&lt;br /&gt;
    ncurses-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
sudo wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
sudo tar xzf Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.14.6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo ./configure \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Build ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo make -j$(nproc)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo make altinstall&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Verify ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python3.14 --version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Virtual Environment ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python3.14 -m venv ~/py314&lt;br /&gt;
&lt;br /&gt;
source ~/py314/bin/activate&lt;br /&gt;
&lt;br /&gt;
python --version&lt;br /&gt;
pip --version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Python 3.14 with OpenSSL 3.x ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
yum groupinstall -y &amp;quot;Development Tools&amp;quot;&lt;br /&gt;
&lt;br /&gt;
yum install -y \&lt;br /&gt;
    perl \&lt;br /&gt;
    perl-IPC-Cmd \&lt;br /&gt;
    wget \&lt;br /&gt;
    zlib-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download OpenSSL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.openssl.org/source/openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
tar xf openssl-3.5.1.tar.gz&lt;br /&gt;
&lt;br /&gt;
cd openssl-3.5.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./Configure \&lt;br /&gt;
    --prefix=/opt/openssl-3 \&lt;br /&gt;
    --openssldir=/opt/openssl-3 \&lt;br /&gt;
    shared \&lt;br /&gt;
    linux-x86_64&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build and Install&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/openssl-3/bin/openssl version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make OpenSSL Runtime Visible:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat &amp;gt;/etc/ld.so.conf.d/openssl3.conf &amp;lt;&amp;lt;EOF&lt;br /&gt;
/opt/openssl-3/lib64&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
# refresh&lt;br /&gt;
ldconfig&lt;br /&gt;
&lt;br /&gt;
# verify:&lt;br /&gt;
ldconfig -p | grep ssl&lt;br /&gt;
&lt;br /&gt;
 # expected:&lt;br /&gt;
 libssl.so.3&lt;br /&gt;
 libcrypto.so.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 3: Build Python 3.14 Against OpenSSL 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /usr/src&lt;br /&gt;
&lt;br /&gt;
wget https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
tar xf Python-3.14.6.tgz&lt;br /&gt;
&lt;br /&gt;
cd Python-3.14.6&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDFLAGS=&amp;quot;-Wl,-rpath,/opt/openssl-3/lib64&amp;quot; \&lt;br /&gt;
./configure \&lt;br /&gt;
    --prefix=/opt/python3.14 \&lt;br /&gt;
    --with-openssl=/opt/openssl-3 \&lt;br /&gt;
    --enable-optimizations \&lt;br /&gt;
    --with-ensurepip=install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make -j$(nproc)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify Python and SSL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/python3.14/bin/python3.14&lt;br /&gt;
 import ssl&lt;br /&gt;
 print(ssl.OPENSSL_VERSION)&lt;br /&gt;
  OpenSSL 3.5.x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify TLS Works:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/python3.14/bin/python3.14 -c &amp;quot;&lt;br /&gt;
import ssl&lt;br /&gt;
import urllib.request&lt;br /&gt;
&lt;br /&gt;
print(ssl.OPENSSL_VERSION)&lt;br /&gt;
print(urllib.request.urlopen(&#039;https://www.python.org&#039;).status)&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install requests:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/python3.14/bin/pip3.14 install requests&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify Your Corporate CA&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/opt/python3.14/bin/python3.14&lt;br /&gt;
&lt;br /&gt;
import ssl&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;OpenSSL:&amp;quot;, ssl.OPENSSL_VERSION)&lt;br /&gt;
&lt;br /&gt;
r = requests.get(&lt;br /&gt;
    &amp;quot;https://artifactory.sandisk.com&amp;quot;,&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(r.status_code)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check Which CA Store Python Uses&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import ssl&lt;br /&gt;
&lt;br /&gt;
print(ssl.get_default_verify_paths())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 and&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import certifi&lt;br /&gt;
&lt;br /&gt;
print(certifi.where())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Force Requests to use the OS trust store:&lt;br /&gt;
 pip install truststore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import truststore&lt;br /&gt;
&lt;br /&gt;
truststore.inject_into_ssl()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Yum&amp;diff=10099</id>
		<title>Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Yum&amp;diff=10099"/>
		<updated>2026-07-27T17:41:13Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* List Repositories */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fastest Mirror ==&lt;br /&gt;
&lt;br /&gt;
 sudo yum install yum-plugin-fastestmirror&lt;br /&gt;
 sudo yum clean&lt;br /&gt;
 sudo yum update&lt;br /&gt;
&lt;br /&gt;
== Show what&#039;s ready to update ==&lt;br /&gt;
&lt;br /&gt;
 yum check-update&lt;br /&gt;
&lt;br /&gt;
== List Repositories ==&lt;br /&gt;
&lt;br /&gt;
 yum repolist all&lt;br /&gt;
&lt;br /&gt;
Show enabled repos:&lt;br /&gt;
 yum repolist&lt;br /&gt;
&lt;br /&gt;
== Make Cache ==&lt;br /&gt;
&lt;br /&gt;
 yum clean all&lt;br /&gt;
 yum makecache&lt;br /&gt;
&lt;br /&gt;
== Lock package ==&lt;br /&gt;
&lt;br /&gt;
 yum install yum-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock add [package]&lt;br /&gt;
 yum versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 # dnf versionlock add [package]&lt;br /&gt;
 dnf versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 yum versionlock list&lt;br /&gt;
&lt;br /&gt;
 yum versionlock status&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock delete [package]&lt;br /&gt;
 yum versionlock delete falcon-sensor&lt;br /&gt;
&lt;br /&gt;
== RPM ==&lt;br /&gt;
&lt;br /&gt;
See [[RPM]]&lt;br /&gt;
&lt;br /&gt;
== dnf - Replacement for Yum ==&lt;br /&gt;
&lt;br /&gt;
See [[dnf]]&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Yum&amp;diff=10098</id>
		<title>Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Yum&amp;diff=10098"/>
		<updated>2026-07-27T17:15:26Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Show what&amp;#039;s ready to update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fastest Mirror ==&lt;br /&gt;
&lt;br /&gt;
 sudo yum install yum-plugin-fastestmirror&lt;br /&gt;
 sudo yum clean&lt;br /&gt;
 sudo yum update&lt;br /&gt;
&lt;br /&gt;
== Show what&#039;s ready to update ==&lt;br /&gt;
&lt;br /&gt;
 yum check-update&lt;br /&gt;
&lt;br /&gt;
== List Repositories ==&lt;br /&gt;
&lt;br /&gt;
 yum repolist all&lt;br /&gt;
&lt;br /&gt;
== Lock package ==&lt;br /&gt;
&lt;br /&gt;
 yum install yum-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock add [package]&lt;br /&gt;
 yum versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 # dnf versionlock add [package]&lt;br /&gt;
 dnf versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 yum versionlock list&lt;br /&gt;
&lt;br /&gt;
 yum versionlock status&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock delete [package]&lt;br /&gt;
 yum versionlock delete falcon-sensor&lt;br /&gt;
&lt;br /&gt;
== RPM ==&lt;br /&gt;
&lt;br /&gt;
See [[RPM]]&lt;br /&gt;
&lt;br /&gt;
== dnf - Replacement for Yum ==&lt;br /&gt;
&lt;br /&gt;
See [[dnf]]&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Yum&amp;diff=10097</id>
		<title>Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Yum&amp;diff=10097"/>
		<updated>2026-07-27T17:15:07Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* dnf - Replacement for Yum */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fastest Mirror ==&lt;br /&gt;
&lt;br /&gt;
 sudo yum install yum-plugin-fastestmirror&lt;br /&gt;
 sudo yum clean&lt;br /&gt;
 sudo yum update&lt;br /&gt;
&lt;br /&gt;
== Show what&#039;s ready to update ==&lt;br /&gt;
&lt;br /&gt;
 yum check-update&lt;br /&gt;
&lt;br /&gt;
== Lock package ==&lt;br /&gt;
&lt;br /&gt;
 yum install yum-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock add [package]&lt;br /&gt;
 yum versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 # dnf versionlock add [package]&lt;br /&gt;
 dnf versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 yum versionlock list&lt;br /&gt;
&lt;br /&gt;
 yum versionlock status&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock delete [package]&lt;br /&gt;
 yum versionlock delete falcon-sensor&lt;br /&gt;
&lt;br /&gt;
== RPM ==&lt;br /&gt;
&lt;br /&gt;
See [[RPM]]&lt;br /&gt;
&lt;br /&gt;
== dnf - Replacement for Yum ==&lt;br /&gt;
&lt;br /&gt;
See [[dnf]]&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=RPM_Package_Manager&amp;diff=10096</id>
		<title>RPM Package Manager</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=RPM_Package_Manager&amp;diff=10096"/>
		<updated>2026-07-27T17:12:18Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Verify System Packages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== RPM Package Manager (RPM) ==&lt;br /&gt;
&lt;br /&gt;
[http://www.rpm.org/ RPM Package Manager (RPM)]:&lt;br /&gt;
:&amp;quot;The RPM Package Manager (RPM) is a powerful command line driven package management system capable of installing, uninstalling, verifying, querying, and updating computer software packages. Each software package consists of an archive of files along with information about the package like its version, a description, and the like.&amp;quot; [http://www.rpm.org/]&lt;br /&gt;
&lt;br /&gt;
==RPM Commands==&lt;br /&gt;
 # List all installed packages&lt;br /&gt;
 rpm -qa&lt;br /&gt;
&lt;br /&gt;
 # List installed package by name&lt;br /&gt;
 rpm -q &amp;lt;package&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # List installed package details&lt;br /&gt;
 rpm -qi &amp;lt;package&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # List files in an installed package&lt;br /&gt;
 rpm -ql &amp;lt;package&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # List state of all files in an installed package (similar to -l)&lt;br /&gt;
 rpm -qs &amp;lt;package&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # Verify installed package (check to see if any files have been changed)&lt;br /&gt;
 rpm -V &amp;lt;package&amp;gt;&lt;br /&gt;
 rpm -Vv &amp;lt;package&amp;gt;&lt;br /&gt;
 rpm -qa -V  # show all files that have changed from all packages&lt;br /&gt;
&lt;br /&gt;
 # List package details (does not have to be installed)&lt;br /&gt;
 # Tell me all about the package contained in &amp;lt;file&amp;gt;.rpm, which doesn&#039;t have to be installed.&lt;br /&gt;
 rpm -qpi &amp;lt;file&amp;gt;.rpm&lt;br /&gt;
&lt;br /&gt;
 # List package contents (does not have to be installed)&lt;br /&gt;
 rpm -qpl &amp;lt;file&amp;gt;.rpm&lt;br /&gt;
 rpm -qpvl &amp;lt;file&amp;gt;.rpm&lt;br /&gt;
&lt;br /&gt;
 # Show which package file came from&lt;br /&gt;
 rpm -qf &amp;lt;file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # List packaged documentation&lt;br /&gt;
 rpm -qpd &amp;lt;file&amp;gt;.rpm&lt;br /&gt;
&lt;br /&gt;
 # List packaged configuration files&lt;br /&gt;
 rpm -qpc &amp;lt;file&amp;gt;.rpm&lt;br /&gt;
&lt;br /&gt;
 # Check if you were bitten by the FC6 i686 bug:&lt;br /&gt;
 rpm -q --qf=&#039;%{name}-%{version}-%{release}.%{arch}\n&#039; kernel&lt;br /&gt;
 rpm -qa --queryformat &amp;quot;%{NAME}-%{VERSION}.%{RELEASE} (%{ARCH})\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # Rebuild RPM database: (generally does not happen with FC)&lt;br /&gt;
 rm -f /var/lib/rpm/__db*&lt;br /&gt;
 rpmdb -vv --rebuilddb&lt;br /&gt;
&lt;br /&gt;
 # List RPM dependencies: [http://www.cyberciti.biz/faq/how-do-i-find-what-dependencies-a-rpm-file-has/]&lt;br /&gt;
 rpm -qpR [file.rpm]&lt;br /&gt;
 rpm -qR [package]&lt;br /&gt;
 rpm -q --requires [package]&lt;br /&gt;
&lt;br /&gt;
 # Remove a package:&lt;br /&gt;
 rpm -e [package]&lt;br /&gt;
&lt;br /&gt;
 # Install a package:&lt;br /&gt;
 rpm -Uvh [file.rpm]&lt;br /&gt;
&lt;br /&gt;
==How to extract SPEC file from a Source RPM==&lt;br /&gt;
[http://www.linuxquestions.org/questions/programming-9/how-to-extract-spec-file-from-rpm-file-426847/ How to extract spec file from rpm file]:&lt;br /&gt;
:&amp;quot;A .spec is similar to a Makefile. When you install an application from tarball it (usually) doesnt automagically install the Makefile. When you make a rpm from spec it doesnt include the spec file. So, no there isnt any way.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To see scripts:&lt;br /&gt;
 rpm -qp --scripts &amp;lt;file&amp;gt;.rpm&lt;br /&gt;
&lt;br /&gt;
Extract SPEC file from source RPM:&lt;br /&gt;
:&amp;quot;You can extract the spec file from a source rpm file (some times a binary rpm file), using command:&amp;quot;&lt;br /&gt;
 rpm2cpio {FullNameOfSourceRPM} | cpio -iumd {NameOfSourceRPM.spec}&lt;br /&gt;
&lt;br /&gt;
List files in rpm file:&lt;br /&gt;
 rpm -qpl [file.rpm]&lt;br /&gt;
 rpm2cpio [file.rpm] | cpio -t&lt;br /&gt;
&lt;br /&gt;
Extract RPM contents from RPM:&lt;br /&gt;
 rpm2cpio [file.rpm] | cpio -idmv&lt;br /&gt;
&lt;br /&gt;
 i: Restore archive&lt;br /&gt;
 d: Create leading directories where needed&lt;br /&gt;
 m: Retain previous file modification times when creating files&lt;br /&gt;
 v: Verbose i.e. display progress&lt;br /&gt;
&lt;br /&gt;
==Signing==&lt;br /&gt;
Signing RPM [http://sial.org/howto/rpm/]&lt;br /&gt;
&lt;br /&gt;
Generate gpg key:&lt;br /&gt;
 gpg --gen-key&lt;br /&gt;
 gpg --armor --export kenneth@kennethburgener.org &amp;gt; RPM-GPG-KEY-kenneth&lt;br /&gt;
&lt;br /&gt;
Configure rpm (~/.rpmmacros):&lt;br /&gt;
 %_signature gpg&lt;br /&gt;
 %_gpg_name kenneth@kennethburgener.org&lt;br /&gt;
 #or %_gpg_name Kenneth Burgener&lt;br /&gt;
&lt;br /&gt;
Check signatures:&lt;br /&gt;
 rpm --checksig [file(s).rpm]&lt;br /&gt;
 rpm -K [file(s).rpm]&lt;br /&gt;
 &lt;br /&gt;
 # signed:&lt;br /&gt;
 [file.rpm]: (sha1) dsa sha1 md5 gpg OK&lt;br /&gt;
 &lt;br /&gt;
 # not signed:&lt;br /&gt;
 [file.rpm]: md5 OK&lt;br /&gt;
&lt;br /&gt;
Delete signature:&lt;br /&gt;
 rpm --delsign [file(s).rpm]&lt;br /&gt;
&lt;br /&gt;
NOTE: You cannot resign an RPM v3 file with RPM v4.  When you go to check the signature you will see an error.&lt;br /&gt;
 # Check RPM file version&lt;br /&gt;
 rpm -qp [file.rpm] --qf &#039;%{rpmversion}\n&#039;&lt;br /&gt;
&lt;br /&gt;
 # Error when trying to install a bad signed RPM with Yum&lt;br /&gt;
 warning: rpmts_HdrFromFdno:  Header V3 DSA signature: NOKEY, key ID [ID]&lt;br /&gt;
 Public key for [PACKAGE] is not installed&lt;br /&gt;
&lt;br /&gt;
Resign package:&lt;br /&gt;
 rpm --resign [file(s).rpm]&lt;br /&gt;
 rpm --addsign [file(s).rpm]&lt;br /&gt;
&lt;br /&gt;
 [trogdor@hal i386]$ rpm --resign *rpm&lt;br /&gt;
 error: You must set &amp;quot;%_gpg_name&amp;quot; in your macro file&lt;br /&gt;
 Pass phrase check failed&lt;br /&gt;
 &lt;br /&gt;
 [trogdor@hal i386]$ cat &amp;gt; ~/.rpmmacros&lt;br /&gt;
 %_gpg_name      Kenneth Burgener&lt;br /&gt;
&lt;br /&gt;
You cannot sign a version 3 RPM file.  Show RPM file&#039;s version:&lt;br /&gt;
 rpm -qp [file.rpm] --qf &#039;%{rpmversion}\n&#039;&lt;br /&gt;
Import signature:&lt;br /&gt;
 rpm --import [signature_file]&lt;br /&gt;
&lt;br /&gt;
List imported signatures:&lt;br /&gt;
 rpm -q gpg-pubkey --qf &#039;%{name}-%{version}-%{release} --&amp;gt; %{summary}\n&#039;&lt;br /&gt;
&lt;br /&gt;
===Automate Signing===&lt;br /&gt;
&amp;quot;You can automate it by not putting a password on the gpgkey.  most of the rpms are manually signed for this reason.  and all of extras are manually signed. the only automated signed would be in rawhide  and i think they are generally not signed at all.&lt;br /&gt;
&lt;br /&gt;
iirc, even with a blank passwd, rpm&#039;s default behavior is to ask for a&lt;br /&gt;
password anyway,&lt;br /&gt;
&lt;br /&gt;
&#039;expect&#039; knows what to do :)&lt;br /&gt;
&lt;br /&gt;
Yes, rpm always asks... And yes, expect knows what to do:&lt;br /&gt;
 #!/usr/bin/expect&lt;br /&gt;
 set p &amp;quot;&amp;quot;&lt;br /&gt;
 set f [lindex $argv 0]&lt;br /&gt;
 spawn rpm --resign $f&lt;br /&gt;
 expect &amp;quot;Enter pass phrase:&amp;quot;&lt;br /&gt;
 send -- &amp;quot;$p\r&amp;quot;&lt;br /&gt;
 expect eof&lt;br /&gt;
&lt;br /&gt;
The other way; Use perl (&lt;br /&gt;
&lt;br /&gt;
http://search.cpan.org/~nanardon/RPM4-0.20/lib/RPM4.pm). RPM4 also knows how to do it...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Reference: [http://osdir.com/ml/redhat.fedora.buildsystem/2006-11/msg00056.html Re: automate rpm signing?: msg#00056]&lt;br /&gt;
&lt;br /&gt;
== Rebuilding a SRPM ==&lt;br /&gt;
&lt;br /&gt;
=== [http://perso.b2b2c.ca/sarrazip/dev/rpm-building-crash-course.html RPM Building Crash Course] ===&lt;br /&gt;
&lt;br /&gt;
==== Avoiding root ====&lt;br /&gt;
&lt;br /&gt;
By default, RPM packages are built in the /usr/src/redhat directory, which is only writable by root. You can have the rpmbuild command use another directory (e.g., /home/your_userid/rpm) by putting this line in a file called .rpmmacros in your home directory:&lt;br /&gt;
&lt;br /&gt;
 %_topdir /home/your_userid/rpm&lt;br /&gt;
&lt;br /&gt;
You must then create the following subdirectories in that directory:&lt;br /&gt;
&lt;br /&gt;
 cd /home/your_userid/rpm&lt;br /&gt;
 mkdir SOURCES SPECS BUILD SRPMS&lt;br /&gt;
 mkdir -p RPMS/i386 RPMS/athlon RPMS/i486 RPMS/i586 RPMS/i686 RPMS/noarch&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo &amp;quot;%_topdir $HOME&amp;quot; &amp;gt; ~/.rpmmacros&lt;br /&gt;
 mkdir $HOME/rpm&lt;br /&gt;
 cd $HOME/rpm&lt;br /&gt;
 mkdir SOURCES SPECS BUILD SRPMS&lt;br /&gt;
 mkdir -p RPMS/i386 RPMS/athlon RPMS/i486 RPMS/i586 RPMS/i686 RPMS/noarch&lt;br /&gt;
&lt;br /&gt;
==== Building from a source RPM (SRPM) ====&lt;br /&gt;
&lt;br /&gt;
Install the .src.rpm file this way:&lt;br /&gt;
&lt;br /&gt;
 rpm -i somepackage-1.0-1.src.rpm&lt;br /&gt;
&lt;br /&gt;
This will create files in the SOURCES directory of your RPM building directory tree, and a .spec file in the SPECS directory.&lt;br /&gt;
&lt;br /&gt;
Then go the SPECS directory and give the command to build the RPM:&lt;br /&gt;
&lt;br /&gt;
 cd /home/your_userid/rpm/SPECS&lt;br /&gt;
 rpmbuild -bb somepackage.spec&lt;br /&gt;
&lt;br /&gt;
Give the -ba option instead if you also want to build the SRPM. The binary RPM packages will typically be created in the RPMS/i386 directory (on a PC-based system).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Rebuilding a source RPM (SRPM) ====&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /usr/src/redhat/&lt;br /&gt;
 rpmbuild --rebuild sourcerpm.src.rpm&lt;br /&gt;
&lt;br /&gt;
==== Building from a source archive ====&lt;br /&gt;
&lt;br /&gt;
When a source archive (e.g., somepackage-1.0.tar.gz) contains a .spec file, one can give the following command to build the RPM without having to deploy the archive:&lt;br /&gt;
&lt;br /&gt;
 rpmbuild -tb somepackage-1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
Give the -ta option instead if you also want to build the SRPM.&lt;br /&gt;
&lt;br /&gt;
=== [http://postfix.state-of-mind.de/patrick.koetter/smtpauth/building_RPMS_from_SRPMS.html 7. Building RPMS from SOURCE or SRPMS] ===&lt;br /&gt;
&lt;br /&gt;
7. Building RPMS from SOURCE or SRPMS&lt;br /&gt;
&lt;br /&gt;
If you haven&#039;t done so before: It is easy to build or rebuild RPMS from SRPMS. Let&#039;s get a quick overview how we build RPMS in our HOWTO.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT NOTE: Never build RPMS as root.&lt;br /&gt;
&lt;br /&gt;
# Log into your machine as a regular user.&lt;br /&gt;
# create a mirror image of the main RPM directory structure in your $HOME and&lt;br /&gt;
# tell RPM to use these directories instead of the original ones.&lt;br /&gt;
&lt;br /&gt;
7.1. Create RPM directories&lt;br /&gt;
&lt;br /&gt;
RPM needs a certain directory structure to build RPMS from SOURCE or from SRPMS. When we build them as non-root user, we cannot use the default location because only root is allowed to write to those directories. So we create the same directory structure in our regular users $HOME-directory:&lt;br /&gt;
&lt;br /&gt;
 [user@example.com]$ mkdir $HOME/rpm $HOME/rpm/SOURCES $HOME/rpm/SPECS $HOME/rpm/BUILD $HOME/rpm/SRPMS $HOME/rpm/RPMS $HOME/rpm/RPMS/i386&lt;br /&gt;
&lt;br /&gt;
When we are done with this, the directory tree of the new rpm directory in our $HOME-directory should look like that:&lt;br /&gt;
&lt;br /&gt;
Example 1. directory tree of new rpm directory&lt;br /&gt;
&lt;br /&gt;
 rpm&lt;br /&gt;
 |-- BUILD&lt;br /&gt;
 |-- RPMS&lt;br /&gt;
 |   `-- i386&lt;br /&gt;
 |-- SOURCES&lt;br /&gt;
 |-- SPECS&lt;br /&gt;
 `-- SRPMS&lt;br /&gt;
&lt;br /&gt;
7.2. Set environment variables&lt;br /&gt;
&lt;br /&gt;
Now we need to tell the RPM-Manager that the non-root user wants this location to build RPMS instead of the default location.&lt;br /&gt;
&lt;br /&gt;
 [user@example.com]$ echo &amp;quot;%_topdir $HOME/rpm&amp;quot; &amp;gt;&amp;gt; $HOME/.rpmmacros&lt;br /&gt;
&lt;br /&gt;
Note: If you want to dig deeper into building RPMS you can find excellent information in the [http://www.rpm.org/max-rpm/ Maximum RPM HOWTO] at [http://www.rpm.org/ rpm.org].&lt;br /&gt;
&lt;br /&gt;
==Building a RPM==&lt;br /&gt;
[http://www.rpm.org/max-rpm/ Max RPM]&lt;br /&gt;
&lt;br /&gt;
Install rpm build tools:&lt;br /&gt;
 yum install rpm-build&lt;br /&gt;
&lt;br /&gt;
Configuring your ~/.rpmmacros:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%packager	Kenneth Burgener &amp;lt;kenneth.burgener@oeey.com&amp;gt;&lt;br /&gt;
%vendor		Name of your project&lt;br /&gt;
&lt;br /&gt;
%_topdir	/home/build/rpm&lt;br /&gt;
%_tmppath	/home/build/rpm/tmp&lt;br /&gt;
&lt;br /&gt;
%_signature	gpg&lt;br /&gt;
%_gpg_name	kenneth.burgener@oeey.com&lt;br /&gt;
# %_gpg_name	Kenneth Burgener &amp;lt;kenneth.burgener@oeey.com&amp;gt;&lt;br /&gt;
%_gpgbin	/usr/bin/gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%_sourcedir	/home/build/rpm/SOURCE&lt;br /&gt;
%_specdir	/home/build/rpm/SPEC&lt;br /&gt;
%_srcrpmdir	/home/build/rpm/SRPMS&lt;br /&gt;
%_builddir	/home/build/rpm/BUILD&lt;br /&gt;
%_rpmdir	/home/build/rpm/RPMS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See current rpm configurations:&lt;br /&gt;
 rpm --showrc | grep -i specdir&lt;br /&gt;
&lt;br /&gt;
Create folders:&lt;br /&gt;
 mkdir ~/rpm; cd ~/rpm&lt;br /&gt;
 mkdir -p BUILD RPMS RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS tmp&lt;br /&gt;
&lt;br /&gt;
Building RPM and SRPM:&lt;br /&gt;
 rpmbuild -ba package.spec&lt;br /&gt;
 &lt;br /&gt;
 # spec in tar file:&lt;br /&gt;
 rpmbuild -ta package.tar.gz&lt;br /&gt;
&lt;br /&gt;
Check your binary packages for commonly overlooked errors ([http://rpmlint.zarb.org/ rpmlint website]):&lt;br /&gt;
 rpmlint [file.rpm]&lt;br /&gt;
&lt;br /&gt;
Steps of: rpmbuild -ba [file.spec]&lt;br /&gt;
* Read and parse the filename.spec file&lt;br /&gt;
* Run the %prep section to unpack the source code into a temporary directory and apply any patches&lt;br /&gt;
* Run the %build section to compile the code&lt;br /&gt;
* Run the %install section to install the code into directories on the build machine&lt;br /&gt;
* Read the list of files from the %files section, gather them up, and create binary and source RPM files&lt;br /&gt;
* Run the %clean section to remove the temporary build directory&lt;br /&gt;
&lt;br /&gt;
==SPEC file==&lt;br /&gt;
Install and uninstall scripts:&lt;br /&gt;
 %pre     Runs before the package is installed&lt;br /&gt;
 %post    Runs after the package is installed&lt;br /&gt;
 %preun   Runs before the package is uninstalled&lt;br /&gt;
 %postun  Runs after the package is uninstalled &lt;br /&gt;
&lt;br /&gt;
 %pre-install&lt;br /&gt;
 %post-install&lt;br /&gt;
 %verify&lt;br /&gt;
 %pre-uninstall&lt;br /&gt;
 %post-uninstall&lt;br /&gt;
&lt;br /&gt;
Tips:&lt;br /&gt;
*These scripts will be deleted upon termination of a section, preventing you from looking at them.  You can cheat and get a look at them by forcing an error in that section.  Just add &amp;quot;exit 1&amp;quot; to your spec file in the appropriate section.  Another useful thing is to &amp;quot;set; exit 1&amp;quot; in a spec file.  This will exit and spit out a list of defined environment variables.  Finally, you can place &amp;quot;bash -i&amp;quot; in a spec file to stop rpmbuild and drop to a shell where you can take a look around.&lt;br /&gt;
*Use %config(noreplace) - this will save configuration files from being replaced or over-written on update. &lt;br /&gt;
&lt;br /&gt;
===Simple SPEC===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Summary: CP Worker&lt;br /&gt;
Name: cp-worker&lt;br /&gt;
Version: 1.0&lt;br /&gt;
Release: 1&lt;br /&gt;
License: Commercial&lt;br /&gt;
BuildArch: noarch&lt;br /&gt;
Group: Applications&lt;br /&gt;
Source0: nx-thirdparty.jar&lt;br /&gt;
Source1: nx-upgrade.jar&lt;br /&gt;
Source2: log4j.properties&lt;br /&gt;
Source3: memcached.xml&lt;br /&gt;
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot&lt;br /&gt;
Requires: cp-bootstrap&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%description&lt;br /&gt;
%{summary}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%prep&lt;br /&gt;
#%setup -q&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
%build&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%install&lt;br /&gt;
# Clean build root&lt;br /&gt;
%{__rm} -rf %{buildroot}&lt;br /&gt;
&lt;br /&gt;
# Copy upgrade files&lt;br /&gt;
%{__mkdir} -p %{buildroot}/usr/cca/loader %{buildroot}/usr/cca/conf&lt;br /&gt;
%{__cp} -a %{SOURCE0} %{SOURCE1} %{buildroot}/usr/cca/loader&lt;br /&gt;
%{__cp} -a %{SOURCE2} %{SOURCE3} %{buildroot}/usr/cca/conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%clean&lt;br /&gt;
%{__rm} -rf %{buildroot}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%pre&lt;br /&gt;
&lt;br /&gt;
%post&lt;br /&gt;
&lt;br /&gt;
%preun&lt;br /&gt;
&lt;br /&gt;
%postun&lt;br /&gt;
&lt;br /&gt;
%files&lt;br /&gt;
%defattr(-,cca,cca)&lt;br /&gt;
%doc README docs/*&lt;br /&gt;
/usr/*&lt;br /&gt;
%config /usr/cca/conf/memcache.xml&lt;br /&gt;
%config(noreplace) /usr/cca/conf/memcache2.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%changelog&lt;br /&gt;
* Wed Jul 12 2007 Jesse Keating &amp;lt;jkeating@redhat.com&amp;gt; - 2.10.0-2&lt;br /&gt;
- item 1&lt;br /&gt;
- item 2&lt;br /&gt;
&lt;br /&gt;
* Wed Feb 12 2006 Jesse Keating &amp;lt;jkeating@redhat.com&amp;gt; - 2.10.0-1&lt;br /&gt;
- item 1&lt;br /&gt;
- item 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sample SPEC Files==&lt;br /&gt;
&lt;br /&gt;
===nail===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Summary: Nail&lt;br /&gt;
Name: nail&lt;br /&gt;
Version: 12.2&lt;br /&gt;
Release: 1&lt;br /&gt;
License: GPL&lt;br /&gt;
BuildArch: i386&lt;br /&gt;
Group: Applications&lt;br /&gt;
Source0: nail-12.2.tar.gz&lt;br /&gt;
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%description&lt;br /&gt;
Nail is a replacement for the mail command.  Nail allows for attachments.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%prep&lt;br /&gt;
%setup -q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%build&lt;br /&gt;
# Make nail&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
%install&lt;br /&gt;
# Clean build root&lt;br /&gt;
%{__rm} -rf %{buildroot}&lt;br /&gt;
&lt;br /&gt;
# Install nail&lt;br /&gt;
make DESTDIR=%{buildroot} install&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%clean&lt;br /&gt;
# Clean build root&lt;br /&gt;
rm -rf %{buildroot}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%pre&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%files&lt;br /&gt;
%defattr(-,root,root,-)&lt;br /&gt;
/etc/nail.rc&lt;br /&gt;
/usr/local/bin/nail&lt;br /&gt;
/usr/local/share/man/man1/nail.1&lt;br /&gt;
%config /etc/nail.rc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Building a RPM Tutorials===&lt;br /&gt;
IBM Packaging software with RPM:&lt;br /&gt;
*[http://www.ibm.com/developerworks/library/l-rpm1/ IBM: Packaging software with RPM, Part 1 (Using RPM on Red Hat Linux 7.1)]&lt;br /&gt;
*[http://www.ibm.com/developerworks/library/l-rpm2/ IBM: Packaging software with RPM, Part 2 (Building without root, patching software, and distributing RPMs)]&lt;br /&gt;
*[http://www-128.ibm.com/developerworks/linux/library/l-rpm3.html IBM: Packaging software with RPM, Part 3 (Running scripts at install and uninstall)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[http://www.redhat.com/docs/books/max-rpm/max-rpm-html/ch-rpm-build.html Building Packages: A Simple Example]&lt;br /&gt;
*[http://genetikayos.com/code/repos/rpm-tutorial/trunk/rpm-tutorial.html Building RPM Tutorial - T.R. Fullhart]&lt;br /&gt;
*[https://pmc.ucsc.edu/~dmk/notes/RPMs/Creating_RPMs.html Creating RPMs]&lt;br /&gt;
*[http://developer.novell.com/wiki/index.php/Using_Build.rpm_to_Package_an_OpenSource_Project Novell: Using Build.rpm to Package an OpenSource Project]&lt;br /&gt;
*[http://www.brandonhutchinson.com/Building_an_RPM.html Building an RPM]&lt;br /&gt;
*[http://susefaq.sourceforge.net/articles/rpm.html RPM RedHat Package Manager]&lt;br /&gt;
*[http://sipx-wiki.calivia.com/index.php/Building_RPM_tips Building RPM tips]&lt;br /&gt;
*[http://www.tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap3sec20.html How to use RPM Commands]&lt;br /&gt;
&lt;br /&gt;
===Examples===&lt;br /&gt;
*[http://tldp.org/HOWTO/Font-HOWTO/rpm.html Create RPMs of Your Fonts]&lt;br /&gt;
&lt;br /&gt;
== RPM Version ==&lt;br /&gt;
&lt;br /&gt;
Manual Dependencies - http://www.rpm.org/max-rpm-snapshot/s1-rpm-depend-manual-dependencies.html&lt;br /&gt;
:Version Requirements&lt;br /&gt;
&lt;br /&gt;
Version:&lt;br /&gt;
 Version: 0.13.1&lt;br /&gt;
 Version: 2.7&lt;br /&gt;
&lt;br /&gt;
 Requires: bar &amp;gt;= 2.7, baz = 2.1&lt;br /&gt;
&lt;br /&gt;
Version with Release:&lt;br /&gt;
 Release: 4&lt;br /&gt;
&lt;br /&gt;
 Requires: bar &amp;gt;= 2.7-4, baz = 2.1-1&lt;br /&gt;
&lt;br /&gt;
Epoch numbers:&lt;br /&gt;
 Epoch: 42&lt;br /&gt;
&lt;br /&gt;
 Requires: foo = 42:&lt;br /&gt;
 Requires: foo &amp;gt;= 42:&lt;br /&gt;
 Requires: foo &amp;gt;= 42:1.0&lt;br /&gt;
&lt;br /&gt;
Note: You must include the epoch in a requires if it exists in the package. If you think of epoch numbers as being nothing more than very simple version numbers, you&#039;ll be on the mark.  Epoch is the most significant component of a package&#039;s complete version identifier with regards to RPM&#039;s version comparison algorithm. It might seem that using epoch numbers is a lot of extra trouble, and you&#039;re right.&lt;br /&gt;
&lt;br /&gt;
== RPM HOWTO ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.rpm.org/max-rpm/ Maximum RPM]&lt;br /&gt;
*&amp;lt;s&amp;gt;[http://www.rpm.org/RPM-HOWTO/ RPM HOWTO]&amp;lt;/s&amp;gt;&lt;br /&gt;
**[http://www.rpm.org/wiki/Docs RPM.org - list of documentation]&lt;br /&gt;
*[http://www.tldp.org/HOWTO/text/RPM-HOWTO RPM at Idle (Text)] [http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/RPM-HOWTO.html (HTML)]&lt;br /&gt;
*[http://docs.fedoraproject.org/drafts/rpm-guide-en/ Fedora RPM Guide]&lt;br /&gt;
&lt;br /&gt;
==To Read==&lt;br /&gt;
*http://www.informit.com/articles/article.asp?p=440160&amp;amp;rl=1&lt;br /&gt;
*http://www.cyberciti.biz/tips/redhat-centos-fedora-linux-setup-repo.html&lt;br /&gt;
*http://www.oracle.com/technology/tech/linux/htdocs/yum-repository-setup.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://www.redhat.com/archives/fedora-list/2005-May/msg03438.html&lt;br /&gt;
*http://www.phy.duke.edu/~rgb/General/yum_HOWTO/yum_HOWTO/yum_HOWTO-10.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://www.gurulabs.com/GURULABS-RPM-LAB/GURULABS-RPM-GUIDE-v1.0.PDF&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://www.ibm.com/developerworks/library/l-rpm1/&lt;br /&gt;
*https://pmc.ucsc.edu/~dmk/notes/RPMs/Creating_RPMs.html&lt;br /&gt;
*http://www.rpm.org/RPM-HOWTO/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://zod.freshrpms.net/rpm.html?id=118&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://www.google.com/search?hl=en&amp;amp;q=Hi+everybody%2C++I+developed+a+small+application+using+Java.+I+want+to+distribute+it+as+a+RPM+or+a+binary+package.+How+to+create+our+own+RPM+%2Fbinary+package+Question&amp;amp;btnG=Google+Search&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://www.linuxjournal.com/node/1000229&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://en.wikipedia.org/wiki/RPM_Package_Manager&lt;br /&gt;
*http://docs.fedoraproject.org/drafts/rpm-guide-en/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://www.cyberciti.biz/tips/how-to-extract-an-rpm-package-without-installing-it.html&lt;br /&gt;
*http://www.altap.cz/salam_en/features/rpm_viewer.html&lt;br /&gt;
*http://www.losurs.org/docs/tips/redhat/unpack&lt;br /&gt;
*http://www.rpm.org/max-rpm/s1-rpm-miscellania-rpm2cpio.html&lt;br /&gt;
*http://www.linux-sxs.org/housekeeping/rpmextract.html&lt;br /&gt;
*http://www.ale.org/archive/ale/ale-1999-05/msg00494.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*http://docs.python.org/dist/creating-rpms.html&lt;br /&gt;
*http://download1.swsoft.com/Plesk/Plesk7.5/Doc/plesk-7.5r-sdk-html/docs/plesk_modules/unix/ch11.html&lt;br /&gt;
*http://www.linuxforums.org/forum/redhat-fedora-linux-help/44921-how-create-rpm-binary-packages.html&lt;br /&gt;
*http://www.netadmintools.com/art272.html&lt;br /&gt;
*http://www.ibm.com/developerworks/library/l-rpm1/&lt;br /&gt;
*http://tldp.org/HOWTO/RPM-HOWTO/build.html&lt;br /&gt;
*http://forums.fedoraforum.org/archive/index.php/t-65432.html&lt;br /&gt;
*http://genetikayos.com/code/repos/rpm-tutorial/trunk/rpm-tutorial.html&lt;br /&gt;
*https://pmc.ucsc.edu/~dmk/notes/RPMs/Creating_RPMs.html&lt;br /&gt;
*http://sial.org/howto/yum/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*https://lists.dulug.duke.edu/pipermail/yum/2004-July/004752.html&lt;br /&gt;
*http://people.redhat.com/jkeating/fedora-release.spec&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/RPM_Package_Manager Wiki: RPM Package Manager]&lt;br /&gt;
&lt;br /&gt;
==Issues==&lt;br /&gt;
===error unpacking file===&lt;br /&gt;
 error: unpacking of archive failed on file /usr/java/jdk1.5.0_14/src.zip;481a3ec9: cpio: read&lt;br /&gt;
&lt;br /&gt;
The rpm is corrupted.  In this case it was the rpm in the yum cache was bad.  Clean cache and try again.&lt;br /&gt;
 yum clean all&lt;br /&gt;
 yum install [package]&lt;br /&gt;
&lt;br /&gt;
==Sample SPEC files==&lt;br /&gt;
&lt;br /&gt;
===Apache sample===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Summary: apache web server&lt;br /&gt;
Name: apache&lt;br /&gt;
Version: 2.0.54&lt;br /&gt;
Release: 1&lt;br /&gt;
License: Apache&lt;br /&gt;
Group: application&lt;br /&gt;
Source0: %{name}-%{version}.tar.gz&lt;br /&gt;
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot&lt;br /&gt;
%description&lt;br /&gt;
Apache is a great webserver&lt;br /&gt;
&lt;br /&gt;
%prep&lt;br /&gt;
%setup -q&lt;br /&gt;
&lt;br /&gt;
%build&lt;br /&gt;
./configure --prefix=/usr/local&lt;br /&gt;
make&lt;br /&gt;
make test&lt;br /&gt;
&lt;br /&gt;
%install&lt;br /&gt;
rm -rf $RPM_BUILD_ROOT&lt;br /&gt;
make root=$RPM_BUILD_ROOT install&lt;br /&gt;
&lt;br /&gt;
%clean&lt;br /&gt;
rm -rf $RPM_BUILD_ROOT&lt;br /&gt;
&lt;br /&gt;
%files&lt;br /&gt;
%defattr(-,root,root,-)&lt;br /&gt;
%doc&lt;br /&gt;
/usr/*&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sample1===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%define name skstream&lt;br /&gt;
%define version 0.2.2&lt;br /&gt;
%define release 1&lt;br /&gt;
&lt;br /&gt;
Summary: Portable C++ classes for IP(sockets) applications.&lt;br /&gt;
Name: %{name}&lt;br /&gt;
Version: %{version}&lt;br /&gt;
Release: %{release}&lt;br /&gt;
Source: ftp://ftp.worldforge.org/pub/worldforge/libs/%{name}-%{version}.tar.gz&lt;br /&gt;
Vendor: The WorldForge Project&lt;br /&gt;
URL: http://www.worldforge.org/&lt;br /&gt;
License: LGPL&lt;br /&gt;
Group: System Environment/Libraries&lt;br /&gt;
Prefix: %{_prefix}&lt;br /&gt;
&lt;br /&gt;
%description&lt;br /&gt;
This library contains C++ utility classes for using IP(sockets).&lt;br /&gt;
&lt;br /&gt;
%package devel&lt;br /&gt;
Summary: Libraries, includes to develop applications with %{name}.&lt;br /&gt;
Group: Development/Libraries&lt;br /&gt;
Requires: %{name} = %{version}&lt;br /&gt;
&lt;br /&gt;
%description devel&lt;br /&gt;
The %{name}-devel package contains the header files and static libraries for&lt;br /&gt;
building applications which use %{name}.&lt;br /&gt;
&lt;br /&gt;
%prep&lt;br /&gt;
%setup -q&lt;br /&gt;
&lt;br /&gt;
%build&lt;br /&gt;
if [ -x ./configure ]; then&lt;br /&gt;
  CFLAGS=&amp;quot;$RPM_OPT_FLAGS&amp;quot; ./configure --prefix=%{_prefix}&lt;br /&gt;
else&lt;br /&gt;
  CFLAGS=&amp;quot;$RPM_OPT_FLAGS&amp;quot; ./autogen.sh --prefix=%{_prefix}&lt;br /&gt;
fi&lt;br /&gt;
make&lt;br /&gt;
&lt;br /&gt;
%install&lt;br /&gt;
rm -rf $RPM_BUILD_ROOT&lt;br /&gt;
make DESTDIR=$RPM_BUILD_ROOT install&lt;br /&gt;
&lt;br /&gt;
%clean&lt;br /&gt;
rm -rf $RPM_BUILD_ROOT&lt;br /&gt;
&lt;br /&gt;
%post -p /sbin/ldconfig&lt;br /&gt;
&lt;br /&gt;
%postun -p /sbin/ldconfig&lt;br /&gt;
&lt;br /&gt;
%files&lt;br /&gt;
%defattr(-,root,root)&lt;br /&gt;
%doc AUTHORS ChangeLog COPYING INSTALL NEWS README TODO&lt;br /&gt;
%{_prefix}/lib/lib*.so.*&lt;br /&gt;
&lt;br /&gt;
%files devel&lt;br /&gt;
%defattr(-,root,root)&lt;br /&gt;
%doc AUTHORS ChangeLog COPYING INSTALL NEWS README TODO&lt;br /&gt;
%{_prefix}/bin/*-config&lt;br /&gt;
%{_prefix}/lib/lib*.a&lt;br /&gt;
%{_prefix}/lib/lib*.so&lt;br /&gt;
%{_prefix}/include/*&lt;br /&gt;
%{_prefix}/share/aclocal/*&lt;br /&gt;
&lt;br /&gt;
%changelog&lt;br /&gt;
* Thu Mar 7 2002 T.R. Fullhart &amp;lt;kayos@kayos.org&amp;gt;&lt;br /&gt;
- First draft of the spec file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://tldp.org/HOWTO/Font-HOWTO/rpm.html Font RPM Example]===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Name: myfonts&lt;br /&gt;
Summary: Collection of My Funny Fonts&lt;br /&gt;
Version: 1.0&lt;br /&gt;
Release: 1&lt;br /&gt;
License: GPL&lt;br /&gt;
Group: User Interface/X&lt;br /&gt;
Source: %{name}.tar.gz&lt;br /&gt;
BuildRoot: %{_tmppath}/build-root-%{name}&lt;br /&gt;
BuildArch: noarch&lt;br /&gt;
Requires: freetype&lt;br /&gt;
Packager: Avi Alkalay &amp;lt;avi@unix.sh&amp;gt;&lt;br /&gt;
Prefix: /usr/share/fonts&lt;br /&gt;
Url: http://myfonts.com/&lt;br /&gt;
&lt;br /&gt;
%description&lt;br /&gt;
These are the fonts used in our marketing campaign, designed by our marketing agency specially for us.&lt;br /&gt;
The package includes the following fonts: Bodoni, Bodoni Black, Company Logo, Outline Company Logo, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%prep&lt;br /&gt;
&lt;br /&gt;
%setup -q -n %{name}&lt;br /&gt;
&lt;br /&gt;
%build&lt;br /&gt;
&lt;br /&gt;
%install&lt;br /&gt;
mkdir -p $RPM_BUILD_ROOT/%{prefix}&lt;br /&gt;
cp -r %{name}/ $RPM_BUILD_ROOT/%{prefix}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%clean&lt;br /&gt;
rm -rf $RPM_BUILD_ROOT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%files&lt;br /&gt;
%defattr(-,root,root,0755)&lt;br /&gt;
%{prefix}/%{name}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%post&lt;br /&gt;
{&lt;br /&gt;
	ttmkfdir -d %{prefix}/%{name} \&lt;br /&gt;
		-o %{prefix}/%{name}/fonts.scale&lt;br /&gt;
	umask 133&lt;br /&gt;
	/usr/X11R6/bin/mkfontdir %{prefix}/%{name}&lt;br /&gt;
	/usr/sbin/chkfontpath -q -a %{prefix}/%{name}&lt;br /&gt;
	[ -x /usr/bin/fc-cache ] &amp;amp;&amp;amp; /usr/bin/fc-cache&lt;br /&gt;
} &amp;amp;&amp;gt; /dev/null || :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%preun&lt;br /&gt;
{&lt;br /&gt;
	if [ &amp;quot;$1&amp;quot; = &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
		cd %{prefix}/%{name}&lt;br /&gt;
		rm -f fonts.dir fonts.scale fonts.cache*&lt;br /&gt;
	fi&lt;br /&gt;
} &amp;amp;&amp;gt; /dev/null || :&lt;br /&gt;
&lt;br /&gt;
%postun&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;quot;0&amp;quot; ]; then&lt;br /&gt;
  /usr/sbin/chkfontpath -q -r %{prefix}/%{name}&lt;br /&gt;
fi&lt;br /&gt;
[ -x /usr/bin/fc-cache ] &amp;amp;&amp;amp; /usr/bin/fc-cache&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%changelog&lt;br /&gt;
* Thu Dec 14 2002 Avi Alkalay &amp;lt;avi@unix.sh&amp;gt; 1.0&lt;br /&gt;
- Tested&lt;br /&gt;
- Ready for deployment&lt;br /&gt;
* Thu Dec 10 2002 Avi Alkalay &amp;lt;avi@unix.sh&amp;gt; 0.9&lt;br /&gt;
- First version of the template&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===freshrpm-release===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# $Id: freshrpms-release.spec 3341 2005-06-28 18:40:26Z thias $&lt;br /&gt;
# Authority: matthias&lt;br /&gt;
&lt;br /&gt;
Summary: Freshrpms.net release file and package configuration&lt;br /&gt;
Name: freshrpms-release&lt;br /&gt;
Version: 1.1&lt;br /&gt;
Release: 1.fc&lt;br /&gt;
License: GPL&lt;br /&gt;
Group: System Environment/Base&lt;br /&gt;
Source0: GPL&lt;br /&gt;
Source1: RPM-GPG-KEY-freshrpms&lt;br /&gt;
Source2: freshrpms.repo&lt;br /&gt;
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root&lt;br /&gt;
BuildArch: noarch&lt;br /&gt;
&lt;br /&gt;
%description&lt;br /&gt;
Freshrpms.net release file. This package also contains yum configuration to&lt;br /&gt;
use the freshrpms.net provided rpm packages, as well as the public gpg key&lt;br /&gt;
used to sign them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%prep&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%build&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%install&lt;br /&gt;
%{__rm} -rf %{buildroot}&lt;br /&gt;
# Install license to be included in the docs and gpg key as pubkey&lt;br /&gt;
%{__cp} -a %{SOURCE0} %{SOURCE1} .&lt;br /&gt;
# Install gpg public key&lt;br /&gt;
%{__install} -D -p -m 0644 %{SOURCE1} \&lt;br /&gt;
    %{buildroot}%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-freshrpms&lt;br /&gt;
# Install yum repo file&lt;br /&gt;
%{__install} -D -p -m 0644 %{SOURCE2} \&lt;br /&gt;
    %{buildroot}%{_sysconfdir}/yum.repos.d/freshrpms.repo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%clean&lt;br /&gt;
%{__rm} -rf %{buildroot}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%post&lt;br /&gt;
# Import Freshrpms.net gpg key if needed&lt;br /&gt;
rpm -q gpg-pubkey-e42d547b-3960bdf1 &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || \&lt;br /&gt;
    rpm --import %{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-freshrpms&lt;br /&gt;
# We don&#039;t want a possible error to leave the previous package installed&lt;br /&gt;
exit 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%files&lt;br /&gt;
%defattr(-, root, root, 0755)&lt;br /&gt;
%doc GPL&lt;br /&gt;
%pubkey RPM-GPG-KEY-freshrpms&lt;br /&gt;
%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-freshrpms&lt;br /&gt;
%config(noreplace) %{_sysconfdir}/yum.repos.d/freshrpms.repo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
%changelog&lt;br /&gt;
* Tue Jun 28 2005 Matthias Saou &amp;lt;http://freshrpms.net/&amp;gt; 1.1-1&lt;br /&gt;
- Put gpg public key in /etc/pki/rpm-gpg and add gpgkey line to yum file.&lt;br /&gt;
&lt;br /&gt;
* Wed Nov 10 2004 Matthias Saou &amp;lt;http://freshrpms.net/&amp;gt; 1-1&lt;br /&gt;
- Initial RPM release, inspired by fedora-release.&lt;br /&gt;
- No /etc/freshrpms-release (for now at least), as it&#039;s basically useless :-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==apache scripts==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[build@build rpm]$ rpm -q --scripts httpd&lt;br /&gt;
&lt;br /&gt;
preinstall scriptlet (using /bin/sh):&lt;br /&gt;
# Add the &amp;quot;apache&amp;quot; user&lt;br /&gt;
/usr/sbin/useradd -c &amp;quot;Apache&amp;quot; -u 48 \&lt;br /&gt;
        -s /sbin/nologin -r -d /var/www apache 2&amp;gt; /dev/null || :&lt;br /&gt;
&lt;br /&gt;
postinstall scriptlet (using /bin/sh):&lt;br /&gt;
# Register the httpd service&lt;br /&gt;
/sbin/chkconfig --add httpd&lt;br /&gt;
&lt;br /&gt;
preuninstall scriptlet (using /bin/sh):&lt;br /&gt;
if [ $1 = 0 ]; then&lt;br /&gt;
        /sbin/service httpd stop &amp;gt; /dev/null 2&amp;gt;&amp;amp;1&lt;br /&gt;
        /sbin/chkconfig --del httpd&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verify System Packages ==&lt;br /&gt;
&lt;br /&gt;
Crackers frequently hack system utilities to hide their presence&lt;br /&gt;
on the system, particularly things like /bin/ps, /bin/login,&lt;br /&gt;
/bin/netstat (pretty much anything in the /bin, /usr/bin, /sbin,&lt;br /&gt;
and /usr/sbin directories).  For a quick list of rpm packages&lt;br /&gt;
that might be affected you can do:&lt;br /&gt;
&lt;br /&gt;
 rpm -qf /bin/* /sbin/* | sort -u &amp;gt; /tmp/critpackages&lt;br /&gt;
&lt;br /&gt;
Then a quick check for changed files.  This doesn&#039;t show the&lt;br /&gt;
package names, but that&#039;s easy to find with ``rpm -qf fname&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 rpm -V `cat /tmp/critpackages`&lt;br /&gt;
&lt;br /&gt;
Source: [http://lists.centos.org/pipermail/centos/2008-December/069596.html CentOS - OT: Ping failed (SOLVED)]&lt;br /&gt;
&lt;br /&gt;
== Rebuild RPM Database ==&lt;br /&gt;
&lt;br /&gt;
 sudo ls -l /var/lib/rpm&lt;br /&gt;
 sudo rm -f /var/lib/rpm/__db*&lt;br /&gt;
&lt;br /&gt;
 yum clean all&lt;br /&gt;
 rm -f /var/lib/rpm/__db*&lt;br /&gt;
 rpm --rebuilddb&lt;br /&gt;
&lt;br /&gt;
 sudo yum clean all&lt;br /&gt;
 sudo yum list&lt;br /&gt;
&lt;br /&gt;
 yum update&lt;br /&gt;
&lt;br /&gt;
If rpm --rebuilddb fails&lt;br /&gt;
 sudo mkdir -p /root/rpmdb-backup&lt;br /&gt;
 sudo cp -a /var/lib/rpm /root/rpmdb-backup/&lt;br /&gt;
&lt;br /&gt;
 cd /var/lib/rpm&lt;br /&gt;
&lt;br /&gt;
 sudo rm -f __db*&lt;br /&gt;
&lt;br /&gt;
 sudo rpmdb --rebuilddb&lt;br /&gt;
&lt;br /&gt;
### OR ###&lt;br /&gt;
&lt;br /&gt;
 sudo rpm --rebuilddb&lt;br /&gt;
&lt;br /&gt;
If the database is severely damaged, export the readable headers and recreate the database:&lt;br /&gt;
 sudo mkdir /root/rpmdb-recovery&lt;br /&gt;
 sudo rpm -qa &amp;gt; /root/rpmdb-recovery/package-list.txt&lt;br /&gt;
&lt;br /&gt;
If that command fails, move the database aside and rebuild:&lt;br /&gt;
 sudo mv /var/lib/rpm /var/lib/rpm.corrupt&lt;br /&gt;
 sudo mkdir /var/lib/rpm&lt;br /&gt;
 sudo rpm --initdb&lt;br /&gt;
&lt;br /&gt;
== Check Dependencies ==&lt;br /&gt;
&lt;br /&gt;
rpmcheck.pl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
my $result=0;&lt;br /&gt;
my @packagelist=`rpm -qa --queryformat &amp;quot;%{NAME}-%{VERSION}.%{RELEASE} (%{ARCH})\n&amp;quot; | sort`;&lt;br /&gt;
&lt;br /&gt;
PACKAGES:&lt;br /&gt;
foreach my $package (&amp;lt;DATA&amp;gt;) {&lt;br /&gt;
  foreach my $item (@packagelist) {&lt;br /&gt;
    next PACKAGES if ( &amp;quot;$package&amp;quot; eq &amp;quot;$item&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
  print &amp;quot;Package missing: $package&amp;quot;;&lt;br /&gt;
  $result=1;&lt;br /&gt;
}&lt;br /&gt;
exit $result;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__DATA__&lt;br /&gt;
binutils-2.17.50.0.6.9.el5 (x86_64)&lt;br /&gt;
compat-db-4.2.52.5.1 (i386)&lt;br /&gt;
compat-db-4.2.52.5.1 (x86_64)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
simplerpmcheck.pl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
my $result=0;&lt;br /&gt;
my @packagelist=`rpm -qa --queryformat &amp;quot;%{NAME}\n&amp;quot;`;&lt;br /&gt;
&lt;br /&gt;
PACKAGES:&lt;br /&gt;
foreach my $package (&amp;lt;DATA&amp;gt;) {&lt;br /&gt;
  foreach my $item (@packagelist) {&lt;br /&gt;
    next PACKAGES if ( &amp;quot;$package&amp;quot; eq &amp;quot;$item&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
  print &amp;quot;Package missing: $package&amp;quot;;&lt;br /&gt;
  $result=1;&lt;br /&gt;
}&lt;br /&gt;
exit $result;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__DATA__&lt;br /&gt;
compat-libstdc++-33&lt;br /&gt;
elfutils-libelf&lt;br /&gt;
elfutils-libelf-devel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Error: rpmdb open failed ===&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
 Error: rpmdb open failed&lt;br /&gt;
&lt;br /&gt;
Solution: [http://linuxhostingsupport.net/blog/yum-update-error-rpmdb-open-failed]&lt;br /&gt;
 yum clean all&lt;br /&gt;
 rm -f /var/lib/rpm/__db*&lt;br /&gt;
 rpm --rebuilddb&lt;br /&gt;
 yum update&lt;br /&gt;
&lt;br /&gt;
=== error: cannot open Packages database ===&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
 error: cannot open Packages database in /var/lib/rpm&lt;br /&gt;
&lt;br /&gt;
Solution: [http://linuxhostingsupport.net/blog/yum-update-error-rpmdb-open-failed]&lt;br /&gt;
 yum clean all&lt;br /&gt;
 rm -f /var/lib/rpm/__db*&lt;br /&gt;
 rpm --rebuilddb&lt;br /&gt;
 yum update&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Games/Hand_and_Foot&amp;diff=10095</id>
		<title>Games/Hand and Foot</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Games/Hand_and_Foot&amp;diff=10095"/>
		<updated>2026-07-26T23:06:11Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Redirected page to Hand and Foot&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Hand and Foot]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Cards&amp;diff=10094</id>
		<title>Cards</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Cards&amp;diff=10094"/>
		<updated>2026-07-26T23:04:05Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;X&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;X&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Hand_and_Foot&amp;diff=10093</id>
		<title>Hand and Foot</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Hand_and_Foot&amp;diff=10093"/>
		<updated>2026-07-26T23:03:06Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;X&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;X&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Dnf&amp;diff=10092</id>
		<title>Dnf</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Dnf&amp;diff=10092"/>
		<updated>2026-07-24T22:59:28Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* pin package */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DNF ==&lt;br /&gt;
&lt;br /&gt;
Dandified YUM (DNF) is the default software package manager for Fedora, Red Hat Enterprise Linux (RHEL), and related distributions&lt;br /&gt;
&lt;br /&gt;
== Upgrade ==&lt;br /&gt;
&lt;br /&gt;
 dnf upgrade&lt;br /&gt;
&lt;br /&gt;
=== update alias ===&lt;br /&gt;
&lt;br /&gt;
 &#039;update&#039; appears to be an alias for upgrade&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
$ dnf update --help&lt;br /&gt;
usage: dnf upgrade&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
== pin package ==&lt;br /&gt;
&lt;br /&gt;
dependency:&lt;br /&gt;
 # sudo dnf install -y python2-dnf-plugin-versionlock  # older rhel versions (repo: rhel-7-server-extras-rpms)&lt;br /&gt;
 sudo dnf install -y python3-dnf-plugin-versionlock&lt;br /&gt;
 sudo dnf install -y dnf-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
Version lock package:&lt;br /&gt;
 sudo dnf versionlock add &amp;lt;package-name&amp;gt;&lt;br /&gt;
 sudo dnf versionlock add kernel&lt;br /&gt;
 sudo dnf versionlock add falcon-sensor&lt;br /&gt;
 sudo dnf versionlock add httpd-2.4.57-5.el9&lt;br /&gt;
&lt;br /&gt;
List:&lt;br /&gt;
 dnf versionlock list&lt;br /&gt;
&lt;br /&gt;
Remove:&lt;br /&gt;
 sudo dnf versionlock delete &amp;lt;package-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear all pins:&lt;br /&gt;
 sudo dnf versionlock clear&lt;br /&gt;
&lt;br /&gt;
== Disable repo ==&lt;br /&gt;
&lt;br /&gt;
List repo ids:&lt;br /&gt;
 dnf repolist --all&lt;br /&gt;
&lt;br /&gt;
Disable repo:&lt;br /&gt;
 # sudo dnf config-manager --disable &amp;lt;repo_id&amp;gt;&lt;br /&gt;
 sudo dnf config-manager --disable epel&lt;br /&gt;
 sudo dnf config-manager --disable docker-ce-stable&lt;br /&gt;
&lt;br /&gt;
 # alt:&lt;br /&gt;
 sudo dnf config-manager setopt epel.enabled=0&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
 dnf repolist --all | grep disabled&lt;br /&gt;
&lt;br /&gt;
Disable for only one command:&lt;br /&gt;
 sudo dnf --disablerepo=epel-testing update&lt;br /&gt;
&lt;br /&gt;
Renable:&lt;br /&gt;
 sudo dnf config-manager --enable epel-testing&lt;br /&gt;
&lt;br /&gt;
== yum - Replaced by DNF ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Dnf&amp;diff=10091</id>
		<title>Dnf</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Dnf&amp;diff=10091"/>
		<updated>2026-07-24T22:46:43Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* pin package */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DNF ==&lt;br /&gt;
&lt;br /&gt;
Dandified YUM (DNF) is the default software package manager for Fedora, Red Hat Enterprise Linux (RHEL), and related distributions&lt;br /&gt;
&lt;br /&gt;
== Upgrade ==&lt;br /&gt;
&lt;br /&gt;
 dnf upgrade&lt;br /&gt;
&lt;br /&gt;
=== update alias ===&lt;br /&gt;
&lt;br /&gt;
 &#039;update&#039; appears to be an alias for upgrade&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
$ dnf update --help&lt;br /&gt;
usage: dnf upgrade&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
== pin package ==&lt;br /&gt;
&lt;br /&gt;
dependency:&lt;br /&gt;
 # sudo dnf install -y python2-dnf-plugin-versionlock  # older rhel versions&lt;br /&gt;
 sudo dnf install -y python3-dnf-plugin-versionlock&lt;br /&gt;
 sudo dnf install -y dnf-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
Version lock package:&lt;br /&gt;
 sudo dnf versionlock add &amp;lt;package-name&amp;gt;&lt;br /&gt;
 sudo dnf versionlock add kernel&lt;br /&gt;
 sudo dnf versionlock add falcon-sensor&lt;br /&gt;
 sudo dnf versionlock add httpd-2.4.57-5.el9&lt;br /&gt;
&lt;br /&gt;
List:&lt;br /&gt;
 dnf versionlock list&lt;br /&gt;
&lt;br /&gt;
Remove:&lt;br /&gt;
 sudo dnf versionlock delete &amp;lt;package-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear all pins:&lt;br /&gt;
 sudo dnf versionlock clear&lt;br /&gt;
&lt;br /&gt;
== Disable repo ==&lt;br /&gt;
&lt;br /&gt;
List repo ids:&lt;br /&gt;
 dnf repolist --all&lt;br /&gt;
&lt;br /&gt;
Disable repo:&lt;br /&gt;
 # sudo dnf config-manager --disable &amp;lt;repo_id&amp;gt;&lt;br /&gt;
 sudo dnf config-manager --disable epel&lt;br /&gt;
 sudo dnf config-manager --disable docker-ce-stable&lt;br /&gt;
&lt;br /&gt;
 # alt:&lt;br /&gt;
 sudo dnf config-manager setopt epel.enabled=0&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
 dnf repolist --all | grep disabled&lt;br /&gt;
&lt;br /&gt;
Disable for only one command:&lt;br /&gt;
 sudo dnf --disablerepo=epel-testing update&lt;br /&gt;
&lt;br /&gt;
Renable:&lt;br /&gt;
 sudo dnf config-manager --enable epel-testing&lt;br /&gt;
&lt;br /&gt;
== yum - Replaced by DNF ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Dnf&amp;diff=10090</id>
		<title>Dnf</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Dnf&amp;diff=10090"/>
		<updated>2026-07-24T22:00:06Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Disable repo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DNF ==&lt;br /&gt;
&lt;br /&gt;
Dandified YUM (DNF) is the default software package manager for Fedora, Red Hat Enterprise Linux (RHEL), and related distributions&lt;br /&gt;
&lt;br /&gt;
== Upgrade ==&lt;br /&gt;
&lt;br /&gt;
 dnf upgrade&lt;br /&gt;
&lt;br /&gt;
=== update alias ===&lt;br /&gt;
&lt;br /&gt;
 &#039;update&#039; appears to be an alias for upgrade&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
$ dnf update --help&lt;br /&gt;
usage: dnf upgrade&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
== pin package ==&lt;br /&gt;
&lt;br /&gt;
dependency:&lt;br /&gt;
 # sudo dnf install -y python2-dnf-plugin-versionlock  # older rhel versions&lt;br /&gt;
 sudo dnf install -y python3-dnf-plugin-versionlock&lt;br /&gt;
 sudo dnf install -y dnf-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
Version lock package:&lt;br /&gt;
 sudo dnf versionlock add &amp;lt;package-name&amp;gt;&lt;br /&gt;
 # sudo dnf versionlock add kernel&lt;br /&gt;
 # sudo dnf versionlock add httpd-2.4.57-5.el9&lt;br /&gt;
&lt;br /&gt;
List:&lt;br /&gt;
 dnf versionlock list&lt;br /&gt;
&lt;br /&gt;
Remove:&lt;br /&gt;
 sudo dnf versionlock delete &amp;lt;package-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear all pins:&lt;br /&gt;
 sudo dnf versionlock clear&lt;br /&gt;
&lt;br /&gt;
== Disable repo ==&lt;br /&gt;
&lt;br /&gt;
List repo ids:&lt;br /&gt;
 dnf repolist --all&lt;br /&gt;
&lt;br /&gt;
Disable repo:&lt;br /&gt;
 # sudo dnf config-manager --disable &amp;lt;repo_id&amp;gt;&lt;br /&gt;
 sudo dnf config-manager --disable epel&lt;br /&gt;
 sudo dnf config-manager --disable docker-ce-stable&lt;br /&gt;
&lt;br /&gt;
 # alt:&lt;br /&gt;
 sudo dnf config-manager setopt epel.enabled=0&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
 dnf repolist --all | grep disabled&lt;br /&gt;
&lt;br /&gt;
Disable for only one command:&lt;br /&gt;
 sudo dnf --disablerepo=epel-testing update&lt;br /&gt;
&lt;br /&gt;
Renable:&lt;br /&gt;
 sudo dnf config-manager --enable epel-testing&lt;br /&gt;
&lt;br /&gt;
== yum - Replaced by DNF ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Dnf&amp;diff=10089</id>
		<title>Dnf</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Dnf&amp;diff=10089"/>
		<updated>2026-07-24T21:58:42Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;== DNF ==  Dandified YUM (DNF) is the default software package manager for Fedora, Red Hat Enterprise Linux (RHEL), and related distributions  == Upgrade ==   dnf upgrade  === update alias ===   &amp;#039;update&amp;#039; appears to be an alias for upgrade  ``` $ dnf update --help usage: dnf upgrade ```  == pin package ==  dependency:  # sudo dnf install -y python2-dnf-plugin-versionlock  # older rhel versions  sudo dnf install -y python3-dnf-plugin-versionlock  sudo dnf install -y dnf-pl...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== DNF ==&lt;br /&gt;
&lt;br /&gt;
Dandified YUM (DNF) is the default software package manager for Fedora, Red Hat Enterprise Linux (RHEL), and related distributions&lt;br /&gt;
&lt;br /&gt;
== Upgrade ==&lt;br /&gt;
&lt;br /&gt;
 dnf upgrade&lt;br /&gt;
&lt;br /&gt;
=== update alias ===&lt;br /&gt;
&lt;br /&gt;
 &#039;update&#039; appears to be an alias for upgrade&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
$ dnf update --help&lt;br /&gt;
usage: dnf upgrade&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
== pin package ==&lt;br /&gt;
&lt;br /&gt;
dependency:&lt;br /&gt;
 # sudo dnf install -y python2-dnf-plugin-versionlock  # older rhel versions&lt;br /&gt;
 sudo dnf install -y python3-dnf-plugin-versionlock&lt;br /&gt;
 sudo dnf install -y dnf-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
Version lock package:&lt;br /&gt;
 sudo dnf versionlock add &amp;lt;package-name&amp;gt;&lt;br /&gt;
 # sudo dnf versionlock add kernel&lt;br /&gt;
 # sudo dnf versionlock add httpd-2.4.57-5.el9&lt;br /&gt;
&lt;br /&gt;
List:&lt;br /&gt;
 dnf versionlock list&lt;br /&gt;
&lt;br /&gt;
Remove:&lt;br /&gt;
 sudo dnf versionlock delete &amp;lt;package-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear all pins:&lt;br /&gt;
 sudo dnf versionlock clear&lt;br /&gt;
&lt;br /&gt;
== Disable repo ==&lt;br /&gt;
&lt;br /&gt;
List repo ids:&lt;br /&gt;
 dnf repolist --all&lt;br /&gt;
&lt;br /&gt;
Disable repo:&lt;br /&gt;
 sudo dnf config-manager --disable &amp;lt;repo_id&amp;gt;&lt;br /&gt;
 # sudo dnf config-manager --disable epel&lt;br /&gt;
&lt;br /&gt;
 # alt:&lt;br /&gt;
 sudo dnf config-manager setopt epel.enabled=0&lt;br /&gt;
&lt;br /&gt;
Verify:&lt;br /&gt;
 dnf repolist --all | grep disabled&lt;br /&gt;
&lt;br /&gt;
Disable for only one command:&lt;br /&gt;
 sudo dnf --disablerepo=epel-testing update&lt;br /&gt;
&lt;br /&gt;
Renable:&lt;br /&gt;
 sudo dnf config-manager --enable epel-testing&lt;br /&gt;
&lt;br /&gt;
== yum - Replaced by DNF ==&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Yum&amp;diff=10088</id>
		<title>Yum</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Yum&amp;diff=10088"/>
		<updated>2026-07-24T21:46:54Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Lock package */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fastest Mirror ==&lt;br /&gt;
&lt;br /&gt;
 sudo yum install yum-plugin-fastestmirror&lt;br /&gt;
 sudo yum clean&lt;br /&gt;
 sudo yum update&lt;br /&gt;
&lt;br /&gt;
== Show what&#039;s ready to update ==&lt;br /&gt;
&lt;br /&gt;
 yum check-update&lt;br /&gt;
&lt;br /&gt;
== Lock package ==&lt;br /&gt;
&lt;br /&gt;
 yum install yum-plugin-versionlock&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock add [package]&lt;br /&gt;
 yum versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 # dnf versionlock add [package]&lt;br /&gt;
 dnf versionlock add falcon-sensor&lt;br /&gt;
&lt;br /&gt;
 yum versionlock list&lt;br /&gt;
&lt;br /&gt;
 yum versionlock status&lt;br /&gt;
&lt;br /&gt;
 # yum versionlock delete [package]&lt;br /&gt;
 yum versionlock delete falcon-sensor&lt;br /&gt;
&lt;br /&gt;
== dnf - Replacement for Yum ==&lt;br /&gt;
&lt;br /&gt;
See [[dnf]]&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10087</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10087"/>
		<updated>2026-07-24T21:12:14Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* PR Management */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Delete Branch on GitHub ==&lt;br /&gt;
&lt;br /&gt;
 gh api \&lt;br /&gt;
  -X DELETE \&lt;br /&gt;
  repos/OWNER/REPO/git/refs/heads/BRANCH&lt;br /&gt;
&lt;br /&gt;
reference: https://docs.github.com/en/rest/git/refs?apiVersion=2026-03-10#delete-a-reference&lt;br /&gt;
&lt;br /&gt;
NOTE: Must have &amp;quot;Write&amp;quot; permission on the &#039;&#039;&#039;Contents&#039;&#039;&#039; - Repository contents, commits, branches, downloads, releases, and merges. &amp;lt;ref&amp;gt;https://docs.github.com/rest/overview/permissions-required-for-github-apps#repository-permissions-for-contents&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10086</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10086"/>
		<updated>2026-07-24T20:52:12Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Checkout PR to repo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== PR Management ==&lt;br /&gt;
&lt;br /&gt;
=== Merge PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr merge &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
=== Closing an Unmerged PR ===&lt;br /&gt;
&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt;&lt;br /&gt;
 gh pr close &amp;lt;pr-number&amp;gt; --delete branch&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10085</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10085"/>
		<updated>2026-07-24T17:49:53Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Repo Update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Checkout PR to repo ==&lt;br /&gt;
&lt;br /&gt;
 gh pr checkout [PR#]&lt;br /&gt;
&lt;br /&gt;
Reference: https://cli.github.com/manual/gh_pr_checkout&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10084</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10084"/>
		<updated>2026-07-24T17:34:22Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Clone Repo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]  [folder]&lt;br /&gt;
 # eg. gh repo clone myorg/myrepo  myrepo&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
See current protocol:  (https is default)&lt;br /&gt;
 gh config get git_protocol&lt;br /&gt;
  https&lt;br /&gt;
  # or&lt;br /&gt;
  ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10083</id>
		<title>GitHub/GH Client</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/GH_Client&amp;diff=10083"/>
		<updated>2026-07-24T00:42:47Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Clone Repo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Github GH Client ==&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
 https://github.com/cli/cli/releases/tag/v2.41.0&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/cli/cli/releases/download/v2.41.0/gh_2.41.0_linux_amd64.deb&lt;br /&gt;
 dpkg -i gh_2.41.0_linux_amd64.deb&lt;br /&gt;
&lt;br /&gt;
Really really old version:&lt;br /&gt;
 pip3 install gh&lt;br /&gt;
&lt;br /&gt;
=== winget ===&lt;br /&gt;
&lt;br /&gt;
See [[WinGet#GitHub Client]]&lt;br /&gt;
&lt;br /&gt;
 winget install --id GitHub.cli --source winget&lt;br /&gt;
&lt;br /&gt;
== Doc ==&lt;br /&gt;
&lt;br /&gt;
 https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Repo List ==&lt;br /&gt;
&lt;br /&gt;
 gh repo list&lt;br /&gt;
&lt;br /&gt;
== Clone Repo ==&lt;br /&gt;
&lt;br /&gt;
https:&lt;br /&gt;
 gh repo clone [ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
ssh:&lt;br /&gt;
 gh repo clone git@github.com:[ORG_or_OWNER]/[REPO]&lt;br /&gt;
&lt;br /&gt;
Set protocol to be ssh:&lt;br /&gt;
 gh config set git_protocol ssh&lt;br /&gt;
&lt;br /&gt;
== Repo Update ==&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Sync destination repository from source repository. Syncing uses the default branch of the source repository to update the matching branch on the destination repository so they are equal. A fast forward update will be used except when the `--force` flag is specified, then the two branches will be synced using a hard reset.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent&lt;br /&gt;
  $ gh repo sync&lt;br /&gt;
&lt;br /&gt;
  # Sync local repository from remote parent on specific branch&lt;br /&gt;
  $ gh repo sync --branch v1&lt;br /&gt;
&lt;br /&gt;
  --force           Hard reset the branch of the destination repository to match the source repository&lt;br /&gt;
&lt;br /&gt;
== Auth ==&lt;br /&gt;
&lt;br /&gt;
 gh auth status&lt;br /&gt;
&lt;br /&gt;
Bad status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  X Failed to log in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - The token in /home/user/.config/gh/hosts.yml is invalid.&lt;br /&gt;
  - To re-authenticate, run: gh auth login -h github.com&lt;br /&gt;
  - To forget about this account, run: gh auth logout -h github.com -u YOUR-USER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good status:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth status&lt;br /&gt;
github.com&lt;br /&gt;
  ✓ Logged in to github.com account YOUR-USER (/home/user/.config/gh/hosts.yml)&lt;br /&gt;
  - Active account: true&lt;br /&gt;
  - Git operations protocol: ssh&lt;br /&gt;
  - Token: ghp_************************************&lt;br /&gt;
  - Token scopes: &#039;admin:public_key&#039;, &#039;read:org&#039;, &#039;repo&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Login ===&lt;br /&gt;
&lt;br /&gt;
 gh auth login -h github.com&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# gh auth login -h github.com&lt;br /&gt;
? What is your preferred protocol for Git operations on this host? SSH&lt;br /&gt;
? Upload your SSH public key to your GitHub account? /root/.ssh/github.pub&lt;br /&gt;
? Title for your SSH key: GitHub CLI&lt;br /&gt;
? How would you like to authenticate GitHub CLI? Paste an authentication token&lt;br /&gt;
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens&lt;br /&gt;
The minimum required scopes are &#039;repo&#039;, &#039;read:org&#039;, &#039;admin:public_key&#039;.&lt;br /&gt;
? Paste your authentication token: ****************************************&lt;br /&gt;
- gh config set -h github.com git_protocol ssh&lt;br /&gt;
✓ Configured git protocol&lt;br /&gt;
! Authentication credentials saved in plain text&lt;br /&gt;
✓ SSH key already existed on your GitHub account: /root/.ssh/github.pub&lt;br /&gt;
✓ Logged in as YOUR-USER-NAME&lt;br /&gt;
! You were already logged in to this account&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with a web browser, grab the one-time code, and visit:&lt;br /&gt;
 https://github.com/login/device&lt;br /&gt;
&lt;br /&gt;
=== GH_TOKEN ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRIVATE_KEY=&#039;private_key.pem&#039;&lt;br /&gt;
APP_ID=&#039;12345&#039;&lt;br /&gt;
INSTALLATION_ID=&#039;54321&#039;&lt;br /&gt;
&lt;br /&gt;
JWT=`./make-jwt.py $PRIVATE_KEY $APP_ID`&lt;br /&gt;
GH_TOKEN=`curl -s --request POST --url &amp;quot;https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens&amp;quot; --header &amp;quot;Accept: application/vnd.github+json&amp;quot; --header &amp;quot;Authorization: Bearer $JWT&amp;quot; --header &amp;quot;X-GitHub-Api-Version: 2022-11-28&amp;quot; | python -c &amp;quot;import sys, json; print(json.load(sys.stdin)[&#039;token&#039;])&amp;quot;`&lt;br /&gt;
echo &amp;quot;export GH_TOKEN=$GH_TOKEN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See [[make-jwt.py]]&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 printf &amp;lt;YOUR_TOKEN&amp;gt; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
 export PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 printf &amp;quot;%s&amp;quot; &amp;quot;$PAT&amp;quot; | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
 $PAT=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
 $PAT | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set PAT=&amp;lt;YOUR_TOKEN&amp;gt;&lt;br /&gt;
 echo %PAT% | gh auth login --with-token&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
GH_TOKEN:&lt;br /&gt;
* Run gh commands: Once the environment variable is set, the gh client will automatically use this token for authentication without needing to run gh auth login&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
 export GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows Powershell:&lt;br /&gt;
  $env:GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Windows CMD:&lt;br /&gt;
 set GH_TOKEN=&amp;quot;&amp;lt;YOUR_TOKEN&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== api ==&lt;br /&gt;
&lt;br /&gt;
 gh api&lt;br /&gt;
&lt;br /&gt;
 ref: https://cli.github.com/manual/gh_api&lt;br /&gt;
&lt;br /&gt;
== Action Runners ==&lt;br /&gt;
&lt;br /&gt;
 https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28&lt;br /&gt;
&lt;br /&gt;
=== List ===&lt;br /&gt;
&lt;br /&gt;
page 1 (pagination)&lt;br /&gt;
 gh api /orgs/ORG/actions/runners&lt;br /&gt;
&lt;br /&gt;
=== Installation Key ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Visual_Studio_Code&amp;diff=10082</id>
		<title>Visual Studio Code</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Visual_Studio_Code&amp;diff=10082"/>
		<updated>2026-07-23T22:19:17Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Unverified Extensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sort Lines ==&lt;br /&gt;
&lt;br /&gt;
 Sort lines - Visual Studio Marketplace&lt;br /&gt;
 https://marketplace.visualstudio.com/items?itemName=Tyriar.sort-lines&lt;br /&gt;
&lt;br /&gt;
Shortcut key: F9&lt;br /&gt;
&lt;br /&gt;
== Upper Case ==&lt;br /&gt;
&lt;br /&gt;
In Visual Studio it was:&lt;br /&gt;
&lt;br /&gt;
To convert text to all upper case, choose Edit &amp;gt; Advanced &amp;gt; Make Uppercase or press Ctrl+Shift+U. To convert text to all lower case, choose Edit &amp;gt; Advanced &amp;gt; Make Lowercase or press Ctrl+U.&lt;br /&gt;
 Make Uppercase or press Ctrl+Shift+U&lt;br /&gt;
 Make Lowercase or press Ctrl+U&lt;br /&gt;
&lt;br /&gt;
So, to mimmic, set the following Keyboard Shortcuts:&lt;br /&gt;
* Transform to Uppercase -&amp;gt; editor.action.transformToUppercase -&amp;gt; Ctrl+Shift+U&lt;br /&gt;
* Transform to Uppercase -&amp;gt; editor.action.transformToUppercase -&amp;gt; Ctrl+U&lt;br /&gt;
&lt;br /&gt;
They conflict with existing shortcuts, but doesn&#039;t appear to cause any problems...&lt;br /&gt;
&lt;br /&gt;
== Chocolatey Install ==&lt;br /&gt;
&lt;br /&gt;
 choco install vscode&lt;br /&gt;
&lt;br /&gt;
 https://update.code.visualstudio.com/1.94.0/win32-x64/stable&lt;br /&gt;
&lt;br /&gt;
== End of Line Character ==&lt;br /&gt;
&lt;br /&gt;
Settings -&amp;gt; &amp;quot;files: Eol&amp;quot; and change from &amp;quot;auto&amp;quot; to &amp;quot;\n&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/q8zR8Vp.png&lt;br /&gt;
&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
Can switch live using the setting in the &amp;quot;status bar&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/uPREQTr.png&lt;br /&gt;
&lt;br /&gt;
== WSL ==&lt;br /&gt;
&lt;br /&gt;
 code --remote wsl+Ubuntu /home/jim/projects/c&lt;br /&gt;
&lt;br /&gt;
ref: &amp;lt;ref&amp;gt;https://code.visualstudio.com/docs/remote/wsl&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Folding ==&lt;br /&gt;
&lt;br /&gt;
Collapse Code Blocks&lt;br /&gt;
&lt;br /&gt;
* Fold All: Ctrl+K Ctrl+0 (Windows/Linux) or Cmd+K Cmd+0 (macOS) collapses all foldable regions. &lt;br /&gt;
* Unfold All: Ctrl+K Ctrl+J (Windows/Linux) or Cmd+K Cmd+J (macOS) expands all collapsed regions. &lt;br /&gt;
* Fold Current Block: Ctrl+Shift+[ (Windows/Linux) or Cmd+Shift+[ (macOS) folds the innermost uncollapsed region at the cursor.&lt;br /&gt;
* Unfold Current Block: Ctrl+Shift+] (Windows/Linux) or Cmd+Shift+] (macOS) unfolds the collapsed region at the cursor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expand to 2nd level:&lt;br /&gt;
* First expand all:&lt;br /&gt;
** Ctrl+K Ctrl+J&lt;br /&gt;
* Second expand &lt;br /&gt;
** Ctrl+K Ctrl+2&lt;br /&gt;
&lt;br /&gt;
== List Plugins and Versions ==&lt;br /&gt;
&lt;br /&gt;
List VS Code extensions and Versions:&lt;br /&gt;
 code --list-extensions --show-versions&lt;br /&gt;
&lt;br /&gt;
=== Glassworm Malware Returns ===&lt;br /&gt;
&lt;br /&gt;
 Glassworm malware returns in third wave of malicious VS Code packages&lt;br /&gt;
 https://www.bleepingcomputer.com/news/security/glassworm-malware-returns-in-third-wave-of-malicious-vs-code-packages/&lt;br /&gt;
&lt;br /&gt;
== Settings Files ==&lt;br /&gt;
&lt;br /&gt;
Open the command pallet and type &amp;quot;&amp;gt;&amp;quot; then &amp;quot;settings&amp;quot; to see the 3 options for:&lt;br /&gt;
* Preferences: Open Workspace Settings (JSON) - [projectpath]\  .vscode\settings.json&lt;br /&gt;
* Preferences: Open Default Settings (JSON) - \defaultSettings.jsonc&lt;br /&gt;
* Preferences: Open User Settings (JSON) - %APPDATA%\Code\User\settings.json&lt;br /&gt;
&lt;br /&gt;
== New Windows Maximized ==&lt;br /&gt;
&lt;br /&gt;
To make VS Code open maximized by default, you need to adjust two settings in the Settings UI or your settings.json file. &lt;br /&gt;
&lt;br /&gt;
Configure Settings&lt;br /&gt;
# Open Settings: Open the VS Code Settings UI by pressing Ctrl+, (Windows/Linux) or Cmd+, (Mac).&lt;br /&gt;
# Search for newWindowDimensions: In the search bar, type &amp;quot;newWindowDimensions&amp;quot;.&lt;br /&gt;
# Set the Value: In the dropdown menu for the Window: New Window Dimensions setting, select maximized. This ensures that new windows open in a maximized state.&lt;br /&gt;
# Search for restoreFullscreen: Next, search for &amp;quot;restoreFullscreen&amp;quot;.&lt;br /&gt;
# Enable the Setting: Check the box for the Window: Restore Fullscreen setting. This makes VS Code remember its last state, including being maximized, when it is closed and reopened.&lt;br /&gt;
# Restart VS Code: Close all VS Code windows and reopen the application. It should now open maximized by default. &lt;br /&gt;
&lt;br /&gt;
Alternatively, you can add these lines to your settings.json file (accessible via the command palette with Preferences: Open Settings (JSON) (ctrl-p, &amp;quot;&amp;gt;&amp;quot;, &amp;quot;open user settings.json&amp;quot;)&lt;br /&gt;
 &amp;quot;window.newWindowDimensions&amp;quot;: &amp;quot;maximized&amp;quot;,&lt;br /&gt;
 &amp;quot;window.restoreFullscreen&amp;quot;: true&lt;br /&gt;
&lt;br /&gt;
== Fix Already Published Branch ==&lt;br /&gt;
&lt;br /&gt;
When cloning from a shallow clone, and switching to another branch, this will confuse Visual Code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 git config --get-all remote.origin.fetch &amp;amp;&amp;amp; echo &amp;quot;---REMOTE REFS---&amp;quot; &amp;amp;&amp;amp; git for-each-ref refs/remotes/origin | head -20&lt;br /&gt;
&lt;br /&gt;
&amp;quot;This is the signature of a --single-branch clone/fetch. Because main wasn&#039;t covered by that refspec, Git didn&#039;t treat origin/main as a tracking branch — so VS Code thought main was unpublished.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
# Restored the standard refspec: +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
# Fetched all branches from origin&lt;br /&gt;
# Set main to track origin/main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you hit this again (local branch shows &amp;quot;Publish&amp;quot; even though it exists on the remote), here&#039;s the sequence:&lt;br /&gt;
&lt;br /&gt;
1. Diagnose** — check whether the branch has an upstream and whether the fetch refspec is restricted:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
git status -sb                          # look for missing [origin/...] next to branch&lt;br /&gt;
git config --get-all remote.origin.fetch   # should be +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
2. Fix the refspec** (only if it&#039;s narrowed to a single branch):&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
git config remote.origin.fetch &amp;quot;+refs/heads/*:refs/remotes/origin/*&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
3. Fetch and set the upstream:**&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
git fetch origin&lt;br /&gt;
git branch --set-upstream-to=origin/main main&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Quick one-liner for the common case:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
git config remote.origin.fetch &amp;quot;+refs/heads/*:refs/remotes/origin/*&amp;quot; &amp;amp;&amp;amp; git fetch origin &amp;amp;&amp;amp; git branch --set-upstream-to=origin/main main&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* Replace `main` / `origin` with the relevant branch and remote names.&lt;br /&gt;
* If `origin/&amp;lt;branch&amp;gt;` truly doesn&#039;t exist on the remote yet, the real fix is to publish it: `git push -u origin &amp;lt;branch&amp;gt;` (the `-u` sets the upstream at the same time).&lt;br /&gt;
* For any branch you&#039;re currently on, `git push -u origin HEAD` both publishes and sets tracking in one step.&lt;br /&gt;
&lt;br /&gt;
== Verified Extensions ==&lt;br /&gt;
&lt;br /&gt;
A list of publishers who have been “verified”, and their popular extensions used by Developers.&lt;br /&gt;
&lt;br /&gt;
=== CodeScene ===&lt;br /&gt;
* CodeScene - Integrates CodeScene analysis into VS Code. Keeps your code clean and maintainable.&lt;br /&gt;
&lt;br /&gt;
=== GitKraken ===&lt;br /&gt;
* GitLens - Git supercharged - Supercharge Git within VS Code — Visualize code authorship at a glance via Git blame annotations and CodeLens, seamlessly navigate and explore Git repositories, gain valuable insights via rich visualizations and powerful comparison commands, and so much more&lt;br /&gt;
&lt;br /&gt;
=== Microsoft ===&lt;br /&gt;
* autopep8 - Formatting support for Python files using the autopep8 formatter.&lt;br /&gt;
* C/C++ - C/C++ IntelliSense, debugging, and code browsing.&lt;br /&gt;
* C/C++ DevTools - Enhanced development tools for C++ in VS Code&lt;br /&gt;
* C/C++ Extension Pack - Popular extensions for C++ development in Visual Studio Code.&lt;br /&gt;
* C/C++ Themes - UI Themes for C/C++ extension.&lt;br /&gt;
* C# - Base language support for C#&lt;br /&gt;
* C# Dev Kit - Official C# extension from Microsoft&lt;br /&gt;
* Container Tools - Makes it easy to create, manage, and debug containerized applications.&lt;br /&gt;
* CMake Tools - Extended CMake support in Visual Studio Code&lt;br /&gt;
* Dev Containers - Open any folder or repository inside a Docker container and take advantage of Visual Studio Code&#039;s full feature set.&lt;br /&gt;
* Docker - Makes it easy to create, manage, and debug containerized applications.&lt;br /&gt;
* Flake8 - Linting support for Python files using Pylint.&lt;br /&gt;
* GitHub Copilot Chat - AI chat features powered by Copilot&lt;br /&gt;
* Hex Editor - Allows viewing and editing files in a hex editor&lt;br /&gt;
* Kubernetes - Develop, deploy and debug Kubernetes applications&lt;br /&gt;
* Makefile Tools - Provide makefile support in VS Code: C/C++ IntelliSense, build, debug/run.&lt;br /&gt;
* Mono Debug - Visual Studio Code debugger extension for Mono&lt;br /&gt;
* .NET Extension Pack - The ultimate collection of extensions for working with .NET in VS Code!&lt;br /&gt;
* .NET Install Tool - This extension installs and manages different versions of the .NET SDK and Runtime.&lt;br /&gt;
* PowerShell - Develop PowerShell modules, commands and scripts in Visual Studio Code!&lt;br /&gt;
* Pylance - A performant, feature-rich language server for Python in VS Code&lt;br /&gt;
* Pylint - Linting support for Python files using Pylint.&lt;br /&gt;
* Python - Python language support with extension access points for IntelliSense (Pylance), Debugging (Python Debugger), linting, formatting, refactoring, unit tests, and more.&lt;br /&gt;
* Python Debugger - Python Debugger extension using debugpy.&lt;br /&gt;
* Python Environments - Provides a unified python environment experience&lt;br /&gt;
* Remote - SSH - Open any folder on a remote machine using SSH and take advantage of VS Code&#039;s full feature set.&lt;br /&gt;
* Remote - SSH; Editing configuration Files - Edit SSH configuration files&lt;br /&gt;
* Remote Development - An extension pack that lets you open any folder in a container, on a remote machine, or in WSL and take advantage of VS Code&#039;s full feature set.&lt;br /&gt;
* Remote Explorer - View remote machines for SSH and Tunnels.&lt;br /&gt;
* Remote Repositories - Remotely browse and edit git repositories&lt;br /&gt;
* Remote Tunnels - Connect to a remote machine through a Tunnel&lt;br /&gt;
* Serial Monitor - Send and receive text from serial ports.&lt;br /&gt;
* WSL - Open any folder in the Windows Subsystem for Linux (WSL) and take advantage of Visual Studio Code&#039;s full feature set.&lt;br /&gt;
&lt;br /&gt;
=== Red Hat ===&lt;br /&gt;
* Ansible - Ansible language support&lt;br /&gt;
* YAML - YAML Language Support by Red Hat, with built-in Kubernetes syntax support&lt;br /&gt;
&lt;br /&gt;
== Unverified Extensions ==&lt;br /&gt;
&lt;br /&gt;
A list of “unverified” publishers.  Validated by the sheer number of download counts (in the millions).&lt;br /&gt;
&lt;br /&gt;
=== Kevin Rose ===&lt;br /&gt;
==== Python Indent ====&lt;br /&gt;
Python Indent - Correct Python indentation&lt;br /&gt;
&lt;br /&gt;
=== Matt Bierner ===&lt;br /&gt;
==== Markdown Preview Mermaid Support ====&lt;br /&gt;
Markdown Preview Mermaid Support - (Published: August 2017, Installs: 5M) Adds Mermaid diagram and flowchart support to VS Code&#039;s builtin markdown preview&lt;br /&gt;
&lt;br /&gt;
=== Mermaid Chart ===&lt;br /&gt;
==== Mermaid ====&lt;br /&gt;
Mermaid - (Published: June 2023, Installs: 952k)() - &amp;quot;The official Mermaid Editor plugin by the Mermaid open source team, now with AI-powered diagramming! Create, edit and preview diagrams seamlessly within VS Code&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Mechatroner ===&lt;br /&gt;
==== Rainbow CSV ====&lt;br /&gt;
Rainbow CSV - (20M) Highlight CSV and TSV files, Run SQL-like queries &lt;br /&gt;
&lt;br /&gt;
=== oderwat ===&lt;br /&gt;
==== indent-rainbow ====&lt;br /&gt;
indent-rainbow (Published: February 2016, Installs: 13M) - Makes indentation easier to read (colored indentation)&lt;br /&gt;
&lt;br /&gt;
=== Ukoloff ===&lt;br /&gt;
==== win-ca ====&lt;br /&gt;
win-ca - (200k) &amp;quot;Make Trusted Root Certificates @Windows available to VSCode extensions&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Git&amp;diff=10081</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Git&amp;diff=10081"/>
		<updated>2026-07-23T20:43:40Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Show siged commits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- == Subpage Table of Contents == --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Subpage Table of Contents&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Special:PrefixIndex/{{PAGENAME}}/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Git ==&lt;br /&gt;
&lt;br /&gt;
[http://git-scm.com/ Git - Fast Version Control System]&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;Git is...&lt;br /&gt;
:Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.&lt;br /&gt;
:Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
:Git is...&lt;br /&gt;
&lt;br /&gt;
:Git is an open source, distributed version control system designed to handle everything from small to very large projects with speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
:Every Git clone is a full-fledged repository with complete history and full revision tracking capabilities, not dependent on network access or a central server. Branching and merging are fast and easy to do.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Git_(software) Git (software) - Wikipedia]:&lt;br /&gt;
:&amp;quot;Git is a free distributed revision control, or software source code management project with an emphasis on being fast. Git was initially created by Linus Torvalds for Linux kernel development.&lt;br /&gt;
&lt;br /&gt;
:Every Git working directory is a full-fledged repository with complete history and full revision tracking capabilities, not dependent on network access or a central server.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== .gitconfig ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[user]&lt;br /&gt;
	name = Kenneth Burgener&lt;br /&gt;
	email = kenneth@oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To set from the command line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git config --global user.name &amp;quot;Kenneth Burgener&amp;quot;&lt;br /&gt;
git config --global user.email kenneth@oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List settings:&lt;br /&gt;
 git config -l&lt;br /&gt;
&lt;br /&gt;
== [http://en.wikipedia.org/wiki/Git_(software)#Name Name] ==&lt;br /&gt;
&lt;br /&gt;
Linus Torvalds has quipped about the name &amp;quot;git&amp;quot;, which is British English slang for a stupid or unpleasant person:&lt;br /&gt;
&lt;br /&gt;
:&amp;quot;I&#039;m an egotistical bastard, and I name all my projects after myself. First Linux, now git.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Custom Bash Prompt ==&lt;br /&gt;
&lt;br /&gt;
Customize your Bash prompt - makandropedia - http://makandracards.com/makandra/1090-customize-your-bash-prompt&lt;br /&gt;
&lt;br /&gt;
GIT adds a __git_ps1 function that will output your branch. You can add onto it by specifying a string argument. A &#039;%s&#039; in the string will be replaced by the branch. I configured it to also show the short hash. Below is how I did it: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
get_sha() {&lt;br /&gt;
    git rev-parse --short HEAD 2&amp;gt;/dev/null&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
get_hg_id() {&lt;br /&gt;
    id=&amp;quot;$(hg id -bt 2&amp;gt; /dev/null| sed -r &#039;s/[\(\)]+//g&#039;)&amp;quot;&lt;br /&gt;
    if [ -n &amp;quot;$id&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;($id)&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
PS1=&#039;${debian_chroot:+($debian_chroot)}&#039;&lt;br /&gt;
PS1=$PS1&#039;\[\033[00;32m\]\u@\h\[\033[00m\]:&#039;&lt;br /&gt;
PS1=$PS1&#039;\[\033[02;48m\]\w\[\033[00m\]&#039;&lt;br /&gt;
PS1=$PS1&#039;\[\033[00;35m\]$(__git_ps1 &amp;quot;(%s $(get_sha))&amp;quot;)$(get_hg_id)\[\033[00m\]&#039;&lt;br /&gt;
PS1=$PS1&#039;\[\033[01;38m\]\$\[\033[00m\] &#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== HEAD Alias ==&lt;br /&gt;
&lt;br /&gt;
 HEAD^ vs HEAD~ vs HEAD^3 vs HEAD~3&lt;br /&gt;
&lt;br /&gt;
Rules of thumb&lt;br /&gt;
* Use ~ most of the time — to go back a number of generations, usually what you want&lt;br /&gt;
* Use ^ on merge commits — because they have two or more (immediate) parents&lt;br /&gt;
&lt;br /&gt;
Mnemonics:&lt;br /&gt;
* Tilde ~ is almost linear in appearance and wants to go backward in a straight line&lt;br /&gt;
* Caret ^ suggests an interesting segment of a tree or a fork in the road&lt;br /&gt;
&lt;br /&gt;
Caret:&lt;br /&gt;
* HEAD^ means the first immediate parent of the tip of the current branch. HEAD^ is short for HEAD^1, and you can also address HEAD^2 and so on as appropriate.&lt;br /&gt;
&lt;br /&gt;
 HEAD^ == HEAD^1&lt;br /&gt;
 HEAD~ == HEAD~1&lt;br /&gt;
&lt;br /&gt;
 HEAD^^ == HEAD^2&lt;br /&gt;
 HEAD~~ == HEAD~2&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git]&lt;br /&gt;
ref: [https://www.golinuxcloud.com/git-head-caret-vs-tilde-at-sign-examples/]&lt;br /&gt;
&lt;br /&gt;
== Config Locations ==&lt;br /&gt;
&lt;br /&gt;
=== Local Repo Config ===&lt;br /&gt;
&lt;br /&gt;
Local Repo Config  (default context)&lt;br /&gt;
 /REPOPATH/.git/config&lt;br /&gt;
 C:\REPOPATH\.git\config  (--edit will report /c/REPOPATH/.git/config)&lt;br /&gt;
&lt;br /&gt;
 # because default context...&lt;br /&gt;
 git config  --edit&lt;br /&gt;
 git config  --list&lt;br /&gt;
&lt;br /&gt;
 git config --local --edit&lt;br /&gt;
 git config --local --list&lt;br /&gt;
&lt;br /&gt;
=== Global Repo Config ===&lt;br /&gt;
&lt;br /&gt;
 ~/.gitconfig&lt;br /&gt;
 C:\Users\USERNAME\.gitconfig  (--edit will report ~/.gitconfig)&lt;br /&gt;
&lt;br /&gt;
 git config --global --edit&lt;br /&gt;
 git config --global --list&lt;br /&gt;
&lt;br /&gt;
=== System Wide Config ===&lt;br /&gt;
&lt;br /&gt;
 /etc/gitconfig&lt;br /&gt;
 C:\Program Files\Git\etc\gitconfig  (--edit will report /etc/gitconfig)&lt;br /&gt;
&lt;br /&gt;
 git config --system --edit&lt;br /&gt;
 git config --system --list&lt;br /&gt;
&lt;br /&gt;
== Commands ==&lt;br /&gt;
&lt;br /&gt;
=== gittutorial ===&lt;br /&gt;
&lt;br /&gt;
gittutorial - A tutorial introduction to git (for version 1.5.1 or newer):&lt;br /&gt;
 man gittutorial&lt;br /&gt;
&lt;br /&gt;
=== config ===&lt;br /&gt;
&lt;br /&gt;
Configure name and email:&lt;br /&gt;
 $ git config --global user.name &amp;quot;Kenneth Burgener&amp;quot;&lt;br /&gt;
 $ git config --global user.email kenneth@t0e.org&lt;br /&gt;
&lt;br /&gt;
=== init ===&lt;br /&gt;
&lt;br /&gt;
Initialize git repository:&lt;br /&gt;
 git init    # current folder&lt;br /&gt;
 git init .  # current folder&lt;br /&gt;
 git init [dir]  # initialize folder (create folder if needed)&lt;br /&gt;
&lt;br /&gt;
=== clone ===&lt;br /&gt;
&lt;br /&gt;
Clone an existing repository:&lt;br /&gt;
 git clone [repo]           # clone [repo] to local dir named [repo] (only current branch)&lt;br /&gt;
 git clone [repo] [newrepo] # clone [repo] to new local dir named [newrepo]&lt;br /&gt;
&lt;br /&gt;
==== clone reference ====&lt;br /&gt;
&lt;br /&gt;
To speed up cloning using a local reference:&lt;br /&gt;
 git clone --reference /local/repo/path  ssh://remote_repo  new_repo&lt;br /&gt;
&lt;br /&gt;
=== add ===&lt;br /&gt;
&lt;br /&gt;
Add files to be tracked:&lt;br /&gt;
 git add .&lt;br /&gt;
 git add [file1] [file2] ...&lt;br /&gt;
&lt;br /&gt;
==== undo add ====&lt;br /&gt;
&lt;br /&gt;
This will undo the git add:&lt;br /&gt;
 git reset [file]&lt;br /&gt;
&lt;br /&gt;
==== add removed ====&lt;br /&gt;
&lt;br /&gt;
To add commits with &#039;rm&#039; or &#039;mv&#039;: [https://stackoverflow.com/questions/492558/removing-multiple-files-from-a-git-repo-that-have-already-been-deleted-from-disk]&lt;br /&gt;
 git add -u&lt;br /&gt;
&lt;br /&gt;
To stage your whole working tree:&lt;br /&gt;
 git add -u :/&lt;br /&gt;
&lt;br /&gt;
To stage just the current path:&lt;br /&gt;
 git add -u .&lt;br /&gt;
&lt;br /&gt;
To handle only removed files:&lt;br /&gt;
 git rm `git ls-files -d`&lt;br /&gt;
 # or&lt;br /&gt;
 git ls-files -z -d | xargs -0 --no-run-if-empty git rm&lt;br /&gt;
&lt;br /&gt;
XY problem: [https://stackoverflow.com/questions/1856654/how-to-add-and-commit-removals-made-with-rm-instead-of-git-rm]&lt;br /&gt;
 git commit -a&lt;br /&gt;
: which would automatically pick up deletions, committing current state of tracked files in working directory&lt;br /&gt;
&lt;br /&gt;
 git add -A&lt;br /&gt;
: which would add not ignored untracked files and remove no longer existing files, e.g. if you want to create commit from sideways update of working directory, e.g. unpacking a snapshot or result of rsync.&lt;br /&gt;
&lt;br /&gt;
=== commit ===&lt;br /&gt;
&lt;br /&gt;
Commit changes:&lt;br /&gt;
 git commit       # include only &#039;added&#039; files&lt;br /&gt;
 git commit -a    # also include modified tracked files&lt;br /&gt;
 git commit -a -m &#039;message&#039; # specify message&lt;br /&gt;
&lt;br /&gt;
=== status ===&lt;br /&gt;
&lt;br /&gt;
Show status: (shows: Changes to be committed, Changed but not updated, Untracked files)&lt;br /&gt;
 git status&lt;br /&gt;
&lt;br /&gt;
=== log ===&lt;br /&gt;
&lt;br /&gt;
View commit log:&lt;br /&gt;
 git log&lt;br /&gt;
 git log -1  # show last commit&lt;br /&gt;
 git log -p  # diffs at each step&lt;br /&gt;
 git log --stat --summary  # overview&lt;br /&gt;
&lt;br /&gt;
 git log --stat  # show files with change summaries&lt;br /&gt;
 git log --name-only  # show files only&lt;br /&gt;
 git log --name-status  # show file names with simple mod attribute&lt;br /&gt;
&lt;br /&gt;
 git log --name-status HEAD^..HEAD&lt;br /&gt;
&lt;br /&gt;
 git log -1 --stat  # show last commit stats&lt;br /&gt;
&lt;br /&gt;
 git log -n 8 --oneline --graph --decorate&lt;br /&gt;
&lt;br /&gt;
==== glog ====&lt;br /&gt;
&lt;br /&gt;
Graphical Log: (ascii art)&lt;br /&gt;
 git log --graph&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
glog - a git log alias for a decent view of your repo [https://coderwall.com/p/syqplg/glog-a-git-log-alias-for-a-decent-view-of-your-repo]&lt;br /&gt;
&lt;br /&gt;
To create this alias, add the following to your .gitconfig&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
   glog = log --all --pretty=&#039;format:%d %Cgreen%h%Creset %an - %s&#039; --graph&lt;br /&gt;
&lt;br /&gt;
==== gitk ====&lt;br /&gt;
&lt;br /&gt;
Graphical Commit Viewer for Git&lt;br /&gt;
&lt;br /&gt;
 gitk [file]&lt;br /&gt;
&lt;br /&gt;
 gitk --follow [file]&lt;br /&gt;
&lt;br /&gt;
Shows change history of file in nice graphical view.&lt;br /&gt;
&lt;br /&gt;
ref: https://www.youtube.com/watch?v=wkJ4leOuK_o&lt;br /&gt;
&lt;br /&gt;
=== show ===&lt;br /&gt;
&lt;br /&gt;
 git show    # show summary and diff of current position&lt;br /&gt;
 git show --summary    # show summary of current position&lt;br /&gt;
&lt;br /&gt;
=== git id ===&lt;br /&gt;
&lt;br /&gt;
git show could be used as a git id:&lt;br /&gt;
 git show&lt;br /&gt;
 git show --summary&lt;br /&gt;
 git show -q  # seems to work like --summary but not mentioned&lt;br /&gt;
&lt;br /&gt;
 git rev-parse HEAD       # hash only&lt;br /&gt;
 git show -s --format=%H  # hash only&lt;br /&gt;
 git show -s --format=%h  # short hash&lt;br /&gt;
&lt;br /&gt;
.gitconfig:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[alias]&lt;br /&gt;
id = rev-parse HEAD&lt;br /&gt;
sha = rev-parse HEAD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== diff ===&lt;br /&gt;
&lt;br /&gt;
See difference between changes and committed:&lt;br /&gt;
 git diff    # Show only changes not added to the index&lt;br /&gt;
 git diff --cached&lt;br /&gt;
&lt;br /&gt;
 git diff HEAD..origin  # show change between fetch and pull&lt;br /&gt;
 git diff origin/master&lt;br /&gt;
&lt;br /&gt;
 git diff HEAD@{1}  # show changes since before the last pull&lt;br /&gt;
 git diff HEAD@{1} [filename]   # same, but specify file&lt;br /&gt;
&lt;br /&gt;
 git diff HEAD^&lt;br /&gt;
 git diff HEAD^ -- /foo/bar/baz.txt&lt;br /&gt;
&lt;br /&gt;
 git diff [shaOfHisCheckIn]^ [shaOfHisCheckIn]&lt;br /&gt;
 git diff [shaOfHisCheckIn]{^,}&lt;br /&gt;
&lt;br /&gt;
After doing a &#039;git fetch&#039;:&lt;br /&gt;
  git log HEAD..origin&lt;br /&gt;
&lt;br /&gt;
Alias for origin/master:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[alias]&lt;br /&gt;
        difff = diff origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Diff Ignore White Space ===&lt;br /&gt;
&lt;br /&gt;
These options can be combined as needed to achieve the desired level of whitespace ignoring for your specific git diff comparison.&lt;br /&gt;
&lt;br /&gt;
  git diff --ignore-all-space&lt;br /&gt;
 --ignore-all-space: or -w: This option completely ignores all whitespace when comparing lines. It treats lines with different amounts of whitespace (including the presence or absence of whitespace) as identical if the non-whitespace content is the same.&lt;br /&gt;
Code&lt;br /&gt;
&lt;br /&gt;
 git diff --ignore-space-change&lt;br /&gt;
 --ignore-space-change: or -b: This option ignores changes in the amount of whitespace, but still acknowledges the presence or absence of whitespace. For example, it would treat &amp;quot;a b&amp;quot; and &amp;quot;a b&amp;quot; as the same, but &amp;quot;ab&amp;quot; and &amp;quot;a b&amp;quot; as different.&lt;br /&gt;
Code&lt;br /&gt;
&lt;br /&gt;
 git diff --ignore-space-at-eol&lt;br /&gt;
 --ignore-space-at-eol: This option specifically ignores whitespace changes that occur only at the end of lines (trailing whitespace).&lt;br /&gt;
Code&lt;br /&gt;
&lt;br /&gt;
 git diff --ignore-blank-lines&lt;br /&gt;
 --ignore-blank-lines: This option skips diffs where the only changes are the addition or removal of blank lines.&lt;br /&gt;
Code&lt;br /&gt;
&lt;br /&gt;
=== Color Diff ===&lt;br /&gt;
&lt;br /&gt;
 git diff --color=always | less -r&lt;br /&gt;
&lt;br /&gt;
Use less -r as pager:&lt;br /&gt;
&lt;br /&gt;
 git config --global color.ui true&lt;br /&gt;
 git config --global core.pager &#039;less -r&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[color]&lt;br /&gt;
    ui = true&lt;br /&gt;
[core]&lt;br /&gt;
    pager = less -r&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ref: https://unix.stackexchange.com/questions/19317/can-less-retain-colored-output&lt;br /&gt;
&lt;br /&gt;
=== branch ===&lt;br /&gt;
&lt;br /&gt;
Branching:&lt;br /&gt;
 git branch              # list branches - master is default&lt;br /&gt;
 git branch [branch]     # create branch&lt;br /&gt;
 git checkout [branch]   # checkout desired branch&lt;br /&gt;
 git merge [branch]      # merge desired branch into current branch&lt;br /&gt;
 git branch -d [branch]  # delete merged branch (close a branch)&lt;br /&gt;
 git branch -D [branch]  # Terminate with extreme prejudice&lt;br /&gt;
&lt;br /&gt;
=== Remote Branch ===&lt;br /&gt;
&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch mybranch&lt;br /&gt;
 # note: does not auto checkout the new branch!&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
&lt;br /&gt;
 # ... make changes ...&lt;br /&gt;
&lt;br /&gt;
 git push --set-upstream origin mybranch&lt;br /&gt;
&lt;br /&gt;
=== Auto Setup Remote Branch ===&lt;br /&gt;
&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git push&lt;br /&gt;
fatal: The current branch SOMEBRANCH/SOMEBRANCH has no upstream branch.&lt;br /&gt;
To push the current branch and set the remote as upstream, use&lt;br /&gt;
&lt;br /&gt;
    git push --set-upstream origin SOMEBRANCH/SOMEBRANCH&lt;br /&gt;
&lt;br /&gt;
To have this happen automatically for branches without a tracking&lt;br /&gt;
upstream, see &#039;push.autoSetupRemote&#039; in &#039;git help config&#039;.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Delete Remote Branch ====&lt;br /&gt;
&lt;br /&gt;
 # git push &amp;lt;remote_name&amp;gt; --delete &amp;lt;branch_name&amp;gt;&lt;br /&gt;
 git push origin --delete mybranch&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely]&lt;br /&gt;
&lt;br /&gt;
Filter and delete remote branches:&lt;br /&gt;
 git branch -a | grep remotes/origin/SOMETHING | sed &#039;s#remotes/origin/##&#039; | xargs -l1 git push origin --delete&lt;br /&gt;
&lt;br /&gt;
==== List Remote Branches ====&lt;br /&gt;
&lt;br /&gt;
List only remote branches fetched locally:&lt;br /&gt;
 git branch -r&lt;br /&gt;
&lt;br /&gt;
To fetch a list of all remote branches:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 &lt;br /&gt;
 # I believe this equivalent to:&lt;br /&gt;
   git remote update&lt;br /&gt;
&lt;br /&gt;
To update all locally fetched remote branches:&lt;br /&gt;
 git pull --all&lt;br /&gt;
&lt;br /&gt;
=== merge ===&lt;br /&gt;
&lt;br /&gt;
Merge branches:&lt;br /&gt;
 git merge [branch]  # merge [branch] into current branch&lt;br /&gt;
&lt;br /&gt;
Merge &#039;test&#039; branch back into master:&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git merge &#039;test&#039;&lt;br /&gt;
&lt;br /&gt;
To close (delete) the merged branch:&lt;br /&gt;
 git branch -d &#039;test&#039;&lt;br /&gt;
&lt;br /&gt;
==== Squash Merge ====&lt;br /&gt;
&lt;br /&gt;
Squash Merge: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/5308816/how-can-i-merge-multiple-commits-onto-another-branch-as-a-single-squashed-commit&amp;lt;/ref&amp;gt;&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git merge --squash bugfix&lt;br /&gt;
 git commit&lt;br /&gt;
&lt;br /&gt;
==== Diverged Branches ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
repo# git pull&lt;br /&gt;
From github.com:myrepo&lt;br /&gt;
 * branch                    releases/myrepo -&amp;gt; FETCH_HEAD&lt;br /&gt;
hint: You have divergent branches and need to specify how to reconcile them.&lt;br /&gt;
hint: You can do so by running one of the following commands sometime before&lt;br /&gt;
hint: your next pull:&lt;br /&gt;
hint:&lt;br /&gt;
hint:   git config pull.rebase false  # merge (the default strategy)&lt;br /&gt;
hint:   git config pull.rebase true   # rebase&lt;br /&gt;
hint:   git config pull.ff only       # fast-forward only&lt;br /&gt;
hint:&lt;br /&gt;
hint: You can replace &amp;quot;git config&amp;quot; with &amp;quot;git config --global&amp;quot; to set a default&lt;br /&gt;
hint: preference for all repositories. You can also pass --rebase, --no-rebase,&lt;br /&gt;
hint: or --ff-only on the command line to override the configured default per&lt;br /&gt;
hint: invocation.&lt;br /&gt;
fatal: Need to specify how to reconcile divergent branches.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I prefer rebase.true&lt;br /&gt;
&lt;br /&gt;
=== Merge Conflict ===&lt;br /&gt;
&lt;br /&gt;
==== Abort Merge ====&lt;br /&gt;
&lt;br /&gt;
 git merge --abort&lt;br /&gt;
 git reset --hard&lt;br /&gt;
 git reset --soft HEAD~&lt;br /&gt;
&lt;br /&gt;
=== pull ===&lt;br /&gt;
&lt;br /&gt;
Merge clones and pull from remote:&lt;br /&gt;
 git pull [repo] [branch]    # pull changes from another clone&lt;br /&gt;
&lt;br /&gt;
Dry run:&lt;br /&gt;
 git pull --dry-run&lt;br /&gt;
&lt;br /&gt;
To try a pull without staving:&lt;br /&gt;
 git pull --no-commit&lt;br /&gt;
 git reset --merge&lt;br /&gt;
&lt;br /&gt;
Dry run: [http://stackoverflow.com/questions/17222440/is-there-in-git-git-pull-dry-run-option]&lt;br /&gt;
 git fetch origin &amp;amp;&amp;amp; git merge origin/master --no-commit --no-ff &amp;amp;&amp;amp; git reset --merge&lt;br /&gt;
&lt;br /&gt;
After a dirty pull merge to clean up log:&lt;br /&gt;
 git rebase origin/master&lt;br /&gt;
&lt;br /&gt;
=== Remotes ===&lt;br /&gt;
&lt;br /&gt;
Working with Remotes:&lt;br /&gt;
 git fetch [repo] [branch]             # pull change info only (safe)&lt;br /&gt;
 git log -p HEAD..FETCH_HEAD           # review changes&lt;br /&gt;
 git remote add [RemoteName] [RemoteRepoURL]   # add remote repo&lt;br /&gt;
 git remote -v                         # list remote repos&lt;br /&gt;
 git branch -r                         # list remote repos branches&lt;br /&gt;
 git fetch [rrepo]                     # pull changes info&lt;br /&gt;
 git log -p [branch]..[rrepo]/[branch] # see changes to remote repo compared to local&lt;br /&gt;
 git merge [rrepo]/[branch]            # merge remote branch to local&lt;br /&gt;
 git pull . remotes/[rrepo]/[branch]   #  alternate form of merge&lt;br /&gt;
 &lt;br /&gt;
 git pull                              # can pull changes directly if is clone&lt;br /&gt;
 git config --get remote.origin.url    # see what original clone was (origin)&lt;br /&gt;
 &lt;br /&gt;
 git push origin master&lt;br /&gt;
&lt;br /&gt;
Change remote url: [https://help.github.com/articles/changing-a-remote-s-url/]&lt;br /&gt;
 git remote set-url origin ssh://git@gitserver/git/path&lt;br /&gt;
&lt;br /&gt;
=== Git Hub ===&lt;br /&gt;
&lt;br /&gt;
~/.gitconfig:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[user]&lt;br /&gt;
    name = Kilo Force&lt;br /&gt;
    email = kiloforce@oeey.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initial setup:&lt;br /&gt;
 mkdir gittest&lt;br /&gt;
 cd gittest&lt;br /&gt;
 git init .&lt;br /&gt;
 touch README.TXT&lt;br /&gt;
 git add README.TXT&lt;br /&gt;
 git commit -m &#039;initial commit&#039;&lt;br /&gt;
 git remote add origin https://bitbucket.org/kiloforce/gittest&lt;br /&gt;
 git push origin master&lt;br /&gt;
&lt;br /&gt;
 git clone https://bitbucket.org/kiloforce/gittest&lt;br /&gt;
 git add file.txt&lt;br /&gt;
 git commit -a -m &#039;file commit&#039;&lt;br /&gt;
 git push&lt;br /&gt;
&lt;br /&gt;
=== Prune and Sync Branches ===&lt;br /&gt;
&lt;br /&gt;
 git fetch --prune --prune-tags&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
   cleanhouse = fetch --prune --prune-tags&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
   cleanhouse = !sh -c &#039;git fetch --prune --prune-tags &amp;amp;&amp;amp; git prune &amp;amp;&amp;amp; git gc&#039;&lt;br /&gt;
&lt;br /&gt;
=== Tags ===&lt;br /&gt;
&lt;br /&gt;
 git tag                # list tags&lt;br /&gt;
 git tag -l             # list tags&lt;br /&gt;
 git tag -l &amp;lt;pattern&amp;gt;   # list tags matching pattern&lt;br /&gt;
 git log --decorate     # list tags in log&lt;br /&gt;
 git tag [tag]          # tag current position&lt;br /&gt;
 git log master..[tag]  # show logs from master to tag&lt;br /&gt;
 git log [tag]..master  # show logs from tag to master (rev)&lt;br /&gt;
 git checkout [tag]     # update to certain tag&lt;br /&gt;
 git describe           # show the current tag&lt;br /&gt;
&lt;br /&gt;
Sync tags: [https://stackoverflow.com/questions/10491146/in-git-how-do-i-sync-my-tags-against-a-remote-server]&lt;br /&gt;
 git fetch -p -P&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 git fetch --prune --prune-tags&lt;br /&gt;
 # or&lt;br /&gt;
 git fetch -p -P origin&lt;br /&gt;
 # or&lt;br /&gt;
 git fetch --prune --prune-tags origin&lt;br /&gt;
&lt;br /&gt;
 # FORCE [rejected] ... (would clobber existing tag)&lt;br /&gt;
 git fetch -p -P -f origin&lt;br /&gt;
&lt;br /&gt;
 git fetch [&amp;lt;options&amp;gt;] [&amp;lt;repository&amp;gt;&lt;br /&gt;
 # -p, --prune&lt;br /&gt;
 # -P, --prune-tags&lt;br /&gt;
 # -f, --force&lt;br /&gt;
==== Force Sync Tags ====&lt;br /&gt;
&lt;br /&gt;
If you get a &amp;quot;would clobber existing tag&amp;quot;, you can delete and force: [https://stackoverflow.com/questions/1841341/remove-local-git-tags-that-are-no-longer-on-the-remote-repository]&lt;br /&gt;
 git tag -l | xargs git tag -d&lt;br /&gt;
 git fetch --tags&lt;br /&gt;
&lt;br /&gt;
 alias git-sync-tags=&#039;git tag -l | xargs git tag -d ; git fetch --tags&#039;&lt;br /&gt;
&lt;br /&gt;
=== clean ===&lt;br /&gt;
&lt;br /&gt;
Show what will be deleted:&lt;br /&gt;
 git clean -n&lt;br /&gt;
&lt;br /&gt;
To Clean:&lt;br /&gt;
 git clean -f&lt;br /&gt;
&lt;br /&gt;
Remove directories:&lt;br /&gt;
 git clean -fd&lt;br /&gt;
&lt;br /&gt;
Remove ignored files:&lt;br /&gt;
 git clean -fX&lt;br /&gt;
&lt;br /&gt;
Remove ignored and non-ignored files:&lt;br /&gt;
 git clean -fx&lt;br /&gt;
&lt;br /&gt;
Ref: [http://stackoverflow.com/questions/61212/how-to-remove-local-untracked-files-from-the-current-git-working-tree]&lt;br /&gt;
&lt;br /&gt;
=== reset ===&lt;br /&gt;
&lt;br /&gt;
DON&#039;T TRY THIS ON ONE FILE!&lt;br /&gt;
&lt;br /&gt;
Reset whole tree: (revert changes) [http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html]&lt;br /&gt;
 # won&#039;t touch new files&lt;br /&gt;
 git reset --hard HEAD^    # reset to head (does not rm new files)&lt;br /&gt;
 git reset --hard HEAD     # return the entire working tree to the last committed state&lt;br /&gt;
&lt;br /&gt;
Reset to changeset (similar to checkout):&lt;br /&gt;
 git reset --hard &amp;lt;HASH&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Throw away local changes:&lt;br /&gt;
 git reset --hard origin/[BRANCH]&lt;br /&gt;
&lt;br /&gt;
Soft, Mixed, Hard:&lt;br /&gt;
https://i.stack.imgur.com/qRAte.jpg&lt;br /&gt;
* Soft - undo commit, but keep index&lt;br /&gt;
* Mixed - undo commit, and undo index, but keep working directory  ** DEFAULT **&lt;br /&gt;
* Hard - reset commit, reset index and reset working directory&lt;br /&gt;
ref: [https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard]&lt;br /&gt;
&lt;br /&gt;
=== Reset Hard with Prejudice ===&lt;br /&gt;
&lt;br /&gt;
 git clean -xdf &amp;amp;&amp;amp; git reset --hard HEAD&lt;br /&gt;
&lt;br /&gt;
Drop local commits&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
&lt;br /&gt;
=== revert like ===&lt;br /&gt;
&lt;br /&gt;
re-checkout all files, overwriting any local changes.  This is most similar to &amp;quot;svn revert&amp;quot; if you&#039;re used to Subversion commands:&lt;br /&gt;
 git checkout .&lt;br /&gt;
&lt;br /&gt;
Reset on file:&lt;br /&gt;
 git checkout -- hello.rb&lt;br /&gt;
 git checkout HEAD hello.rb&lt;br /&gt;
&lt;br /&gt;
=== rollback like ===&lt;br /&gt;
&lt;br /&gt;
rollback or undo the last commit [http://stackoverflow.com/questions/927358/how-do-you-undo-the-last-commit]&lt;br /&gt;
&lt;br /&gt;
 git reset --soft HEAD~&lt;br /&gt;
&lt;br /&gt;
 git commit -m &amp;quot;Something terribly misguided&amp;quot;&lt;br /&gt;
 git reset --soft HEAD~&lt;br /&gt;
 &amp;lt;&amp;lt; edit files as necessary &amp;gt;&amp;gt;&lt;br /&gt;
 git add ...&lt;br /&gt;
 #git commit -c ORIG_HEAD&lt;br /&gt;
 #git commit -a -m &amp;quot;Something right&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Or with prejudice:&lt;br /&gt;
 git reset --hard HEAD&lt;br /&gt;
&lt;br /&gt;
=== Stash ===&lt;br /&gt;
&lt;br /&gt;
Stash changes&lt;br /&gt;
 git stash&lt;br /&gt;
 git stash save &amp;quot;message&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Apply last change without deleting:&lt;br /&gt;
 git stash apply&lt;br /&gt;
&lt;br /&gt;
Apply last change with deleting:&lt;br /&gt;
 git stash pop&lt;br /&gt;
&lt;br /&gt;
Delete last stash:&lt;br /&gt;
 git stash drop&lt;br /&gt;
 git stash drop stash@{1}  # drop stash 1&lt;br /&gt;
&lt;br /&gt;
List stashes:&lt;br /&gt;
 git stash&lt;br /&gt;
&lt;br /&gt;
Show files in last stash:&lt;br /&gt;
 git show&lt;br /&gt;
&lt;br /&gt;
=== Amend ===&lt;br /&gt;
&lt;br /&gt;
(similar to annotate / amend commit message)&lt;br /&gt;
&lt;br /&gt;
Changing a commit message, and/or files [https://help.github.com/articles/changing-a-commit-message/]&lt;br /&gt;
&lt;br /&gt;
 git commit --amend&lt;br /&gt;
&lt;br /&gt;
Change author:&lt;br /&gt;
 git commit --amend --author=&amp;quot;Author Name &amp;lt;email@address.com&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Changing an older commit with rebase: [http://stackoverflow.com/questions/3042437/change-commit-author-at-one-specific-commit]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git rebase -i [change_set_prior_to_target]&lt;br /&gt;
# change &amp;quot;pick&amp;quot; for target changesets&lt;br /&gt;
git commit --amend --author=&amp;quot;Author Name &amp;lt;email@address.com&amp;gt;&amp;quot;&lt;br /&gt;
git rebase --continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 git commit --amend --reset-author --no-edit&lt;br /&gt;
&lt;br /&gt;
=== Cherry Pick ===&lt;br /&gt;
&lt;br /&gt;
 git cherry-pick [hash]&lt;br /&gt;
&lt;br /&gt;
Cherry Pick a range: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/1670970/how-to-cherry-pick-multiple-commits&amp;lt;/ref&amp;gt;&lt;br /&gt;
 git cherry-pick [hash]^...[hash]&lt;br /&gt;
&lt;br /&gt;
==== Cherry Pick From Anther Repository ====&lt;br /&gt;
&lt;br /&gt;
Cherry Pick From Anther Repository &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/5120038/is-it-possible-to-cherry-pick-a-commit-from-another-git-repository&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 git remote add other https://example.link/repository.git&lt;br /&gt;
 git fetch other&lt;br /&gt;
 # or git fetch other BRANCH&lt;br /&gt;
 git cherry-pick first_commit...last_commit&lt;br /&gt;
 ...&lt;br /&gt;
 # when done:&lt;br /&gt;
 git remote remove other&lt;br /&gt;
&lt;br /&gt;
=== Submodules ===&lt;br /&gt;
&lt;br /&gt;
 git submodule init&lt;br /&gt;
 git submodule sync&lt;br /&gt;
 git submodule update&lt;br /&gt;
 # or&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
Show submodule commit versions and branches:&lt;br /&gt;
 git submodule status&lt;br /&gt;
&lt;br /&gt;
== Helpful Aliases ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[alias]&lt;br /&gt;
&lt;br /&gt;
    cp = cherry-pick&lt;br /&gt;
&lt;br /&gt;
    ####CAN&#039;T OVERRIDE BASE NAME pull = pull --rebase&lt;br /&gt;
    pul = pull --rebase&lt;br /&gt;
    rpull = pull --rebase&lt;br /&gt;
    pulll = pull --rebase&lt;br /&gt;
    unstage = restore --staged&lt;br /&gt;
&lt;br /&gt;
    # difff = diff origin/master&lt;br /&gt;
    # difff = diff origin&lt;br /&gt;
    difff = !sh -c &#039;git diff origin/`git rev-parse --abbrev-ref HEAD`&#039;&lt;br /&gt;
&lt;br /&gt;
    # uncommit ref: https://stackoverflow.com/questions/2845731/how-to-uncommit-my-last-commit-in-git&lt;br /&gt;
    # rollback just commit:&lt;br /&gt;
    uncommit = reset --soft HEAD^&lt;br /&gt;
    # rollback commit and changes:&lt;br /&gt;
    uncommithard = reset --hard HEAD^&lt;br /&gt;
&lt;br /&gt;
    rollback = reset --soft HEAD^&lt;br /&gt;
    rollbackhard = reset --hard HEAD~&lt;br /&gt;
    resethard = reset --hard HEAD~&lt;br /&gt;
&lt;br /&gt;
    pending = log origin/master..HEAD&lt;br /&gt;
    pendingdiff = diff origin/master..HEAD&lt;br /&gt;
    # show changed files&lt;br /&gt;
    flog = log --stat&lt;br /&gt;
    # show graph of commits&lt;br /&gt;
    glog = log --all --pretty=&#039;format:%d %Cgreen%h%Creset %an - %s&#039; --graph&lt;br /&gt;
    # show tags&lt;br /&gt;
    tlog = log --decorate&lt;br /&gt;
    ref = !sh -c &#039;git ls-remote | grep $(git rev-parse HEAD)&#039;&lt;br /&gt;
&lt;br /&gt;
    amend = commit --amend&lt;br /&gt;
&lt;br /&gt;
    showpatch = am --show-current-patch&lt;br /&gt;
&lt;br /&gt;
    lfs-files = lfs ls-files&lt;br /&gt;
    lfsfiles = lfs ls-files&lt;br /&gt;
    lfs-ls = lfs ls-files&lt;br /&gt;
    lfsls = lfs ls-files&lt;br /&gt;
&lt;br /&gt;
    cleanhouse = !sh -c &#039;git fetch --prune --prune-tags &amp;amp;&amp;amp; git prune &amp;amp;&amp;amp; git gc&#039;&lt;br /&gt;
&lt;br /&gt;
    ignored = ls-files --others --ignored --exclude-standard&lt;br /&gt;
&lt;br /&gt;
    #gud = status -s&lt;br /&gt;
    gud = !echo &#039;go home you&#039;\\&#039;&#039;re drunk&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
=== Manual Installation ===&lt;br /&gt;
&lt;br /&gt;
Remove existing:&lt;br /&gt;
 yum remove git&lt;br /&gt;
 apt-get remove git&lt;br /&gt;
&lt;br /&gt;
Install dependencies:&lt;br /&gt;
 yum -y install gcc make curl-devel openssl-devel expat-devel autoconf gettext&lt;br /&gt;
 # ? perl-ExtUtils-MakeMaker&lt;br /&gt;
 sudo apt-get install curl libcurl4-openssl-dev libexpat1-dev gettext zlib1g-dev autoconf&lt;br /&gt;
   suod apt-get install tclsh  # is this needed?&lt;br /&gt;
&lt;br /&gt;
Visit here to determine the version you want:&lt;br /&gt;
 https://git-scm.com/download/linux&lt;br /&gt;
 # it will say &amp;quot;The latest version is &amp;quot;2.45.1&amp;quot; (as of 14-May-2024)&lt;br /&gt;
&lt;br /&gt;
 # or manually find in the list:&lt;br /&gt;
 http://kernel.org/pub/software/scm/git&lt;br /&gt;
&lt;br /&gt;
Download Git source:&lt;br /&gt;
 # GIT_VER=1.7.8.3   # removed&lt;br /&gt;
 # GIT_VER=1.8.2.3   # 09-May-2013 earliest 1.x still available&lt;br /&gt;
 # GIT_VER=1.8.3.4   # 22-Jul-2013&lt;br /&gt;
 # GIT_VER=2.6.3     # 05-Nov-2015&lt;br /&gt;
 # GIT_VER=2.25.1      # 17-Feb-2020&lt;br /&gt;
 # GIT_VER=2.44.0    # 23-Feb-2024&lt;br /&gt;
 GIT_VER=2.45.1    # 14-May-2024&lt;br /&gt;
 &lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 # wget http://git-core.googlecode.com/files/git-$GIT_VER.tar.gz&lt;br /&gt;
 wget http://kernel.org/pub/software/scm/git/git-$GIT_VER.tar.gz&lt;br /&gt;
 tar -zvxf git-$GIT_VER.tar.gz&lt;br /&gt;
 cd git-$GIT_VER&lt;br /&gt;
&lt;br /&gt;
Configure install:&lt;br /&gt;
 make configure&lt;br /&gt;
 # ./configure --prefix=/opt/git&lt;br /&gt;
 ./configure&lt;br /&gt;
 make clean&lt;br /&gt;
 make all&lt;br /&gt;
 sudo make install&lt;br /&gt;
 &lt;br /&gt;
Git man pages: (optional step)&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 # wget http://git-core.googlecode.com/files/git-manpages-$GIT_VER.tar.gz&lt;br /&gt;
 wget http://kernel.org/pub/software/scm/git/git-manpages-$GIT_VER.tar.gz&lt;br /&gt;
 sudo tar -zvxf git-manpages-$GIT_VER.tar.gz -C /opt/git/share/man/&lt;br /&gt;
&lt;br /&gt;
Paths: /etc/bashrc&lt;br /&gt;
 export PATH=/opt/git/bin:$PATH&lt;br /&gt;
 export MANPATH=/opt/git/share/man/:$MANPATH&lt;br /&gt;
 echo -e &amp;quot;\n\nexport PATH=/opt/git/bin:\$PATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
 echo -e &amp;quot;\n\nexport MANPATH=/opt/git/share/man/:\$MANPATH\n&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile&lt;br /&gt;
&lt;br /&gt;
Note: the NO_GETTEXT=1 is needed to avoid a &amp;quot;Makefile:252: po/bg.msg] Error 127&amp;quot; &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/50800829/compile-git-without-gettext?newreg=5ed483890d174baf8ac5b4ee1edf0acb&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other Installation Options ===&lt;br /&gt;
&lt;br /&gt;
Manually install man pages:&lt;br /&gt;
 # dependencies: (need RPMforge)&lt;br /&gt;
 #   yum install asciidoc libxslt xmlto&lt;br /&gt;
 make man&lt;br /&gt;
 sudo make install-man&lt;br /&gt;
&lt;br /&gt;
 /etc/bashrc:&lt;br /&gt;
   export PATH=/opt/git/bin:$PATH&lt;br /&gt;
   export MANPATH=/opt/git/share/man/&lt;br /&gt;
&lt;br /&gt;
 # direct usage&lt;br /&gt;
 man -M ~/share/man git-commit&lt;br /&gt;
 # or&lt;br /&gt;
 export MANPATH=~/share/man&lt;br /&gt;
 man git-commit&lt;br /&gt;
&lt;br /&gt;
Personal install: (non configure method)&lt;br /&gt;
 # personal install ~/bin ~/lib ~/share ... (prefix=~):&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
Global install: (non configure method)&lt;br /&gt;
 $ make prefix=/usr/local all doc info&lt;br /&gt;
 sudo make prefix=/usr/local install install-doc install-html install-info&lt;br /&gt;
&lt;br /&gt;
=== Install with Ubuntu PPA ===&lt;br /&gt;
&lt;br /&gt;
 sudo add-apt-repository ppa:git-core/ppa&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt -y install git&lt;br /&gt;
 sudo apt -y upgrade git&lt;br /&gt;
&lt;br /&gt;
=== Installation with DAG ===&lt;br /&gt;
&lt;br /&gt;
Install with DAG:&lt;br /&gt;
 # http://dag.wieers.com/rpm/packages/git/git-1.5.2.1-1.el5.rf.i386.rpm&lt;br /&gt;
 rpm -Uvh http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm&lt;br /&gt;
 yum install rpmforge-release  # update rpmforge&lt;br /&gt;
 yum install git&lt;br /&gt;
&lt;br /&gt;
=== FreeBSD Installation ===&lt;br /&gt;
&lt;br /&gt;
  pkg_add -r git&lt;br /&gt;
&lt;br /&gt;
=== Installation OF LFS ===&lt;br /&gt;
&lt;br /&gt;
 # git clone git@github.com:git-lfs/git-lfs.git&lt;br /&gt;
&lt;br /&gt;
 wget https://github.com/git-lfs/git-lfs/releases/download/v3.5.1/git-lfs-linux-amd64-v3.5.1.tar.gz&lt;br /&gt;
 tar -zvxf git-lfs-linux-amd64-v3.5.1.tar.gz&lt;br /&gt;
 sudo cp git-lfs-3.5.1/git-lfs /opt/git/bin/&lt;br /&gt;
&lt;br /&gt;
== Use alternative ssh key ==&lt;br /&gt;
&lt;br /&gt;
 export GIT_SSH_COMMAND=&amp;quot;ssh -i /path/to/git-private-access-key&amp;quot;&lt;br /&gt;
 git clone REPO&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
 GIT_SSH_COMMAND=&amp;quot;ssh -i /path/to/git-private-access-key&amp;quot;  git clone REPO&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
 git clone -c &amp;quot;core.sshCommand=ssh -i ~/.ssh/&amp;lt;key&amp;gt;&amp;quot; git@github.com:&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;.git&lt;br /&gt;
&lt;br /&gt;
or wrapper:&lt;br /&gt;
&lt;br /&gt;
 ~/.gitwrap.sh:&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 ssh -i ~/.ssh/gitkey_rsa &amp;quot;$@&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 export GIT_SSH=~/gitwrap.sh&lt;br /&gt;
&lt;br /&gt;
or per repo config:&lt;br /&gt;
&lt;br /&gt;
 vim .git/config&lt;br /&gt;
&lt;br /&gt;
 [core]&lt;br /&gt;
     sshCommand = ssh -i &amp;lt;IDENTITY_KEY_LOCATION&amp;gt; -o IdentitiesOnly=yes&lt;br /&gt;
&lt;br /&gt;
ref: bash - How to specify the private SSH-key to use when executing shell command on Git? - Stack Overflow - https://stackoverflow.com/questions/4565700/how-to-specify-the-private-ssh-key-to-use-when-executing-shell-command-on-git&lt;br /&gt;
&lt;br /&gt;
== Create Central Repo ==&lt;br /&gt;
&lt;br /&gt;
Create a shared bare repo:&lt;br /&gt;
 ## Set permission&lt;br /&gt;
 umask 0002&lt;br /&gt;
 mkdir git&lt;br /&gt;
 chown :sharedgroup git&lt;br /&gt;
 # chmod g+ws git&lt;br /&gt;
 chmod g+s git&lt;br /&gt;
 cd git&lt;br /&gt;
&lt;br /&gt;
 # git init --bare some_project.git&lt;br /&gt;
 # git clone --mirror some_existing_project.git&lt;br /&gt;
 # git init --bare --shared some_project.git&lt;br /&gt;
 mkdir some_project.git ; cd some_project.git&lt;br /&gt;
 git init --bare --shared .&lt;br /&gt;
&lt;br /&gt;
 ## Fix permissions and ownership&lt;br /&gt;
 # chown some_project.git :sharedgroup -R&lt;br /&gt;
 # find some_project.git -type d -exec chmod g+ws {} \;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config - with shared setting&lt;br /&gt;
[core]&lt;br /&gt;
        repositoryformatversion = 0&lt;br /&gt;
        filemode = true&lt;br /&gt;
        bare = true&lt;br /&gt;
        sharedrepository = 1&lt;br /&gt;
[receive]&lt;br /&gt;
        denyNonFastforwards = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Central Repo&lt;br /&gt;
 git clone [workingrepo] [dir] --mirror  # create bare repo  (ie dir=&#039;central&#039;)&lt;br /&gt;
&lt;br /&gt;
 ## Make group editable:&lt;br /&gt;
 find test-git.git -type d -exec chmod g+s {} \;&lt;br /&gt;
 chmod g+w test-git.git -R&lt;br /&gt;
 chown :git -R test-git.git/&lt;br /&gt;
&lt;br /&gt;
 git clone [repo]  # clone bare repo&lt;br /&gt;
 ... make changes and commit ...&lt;br /&gt;
 git push  # push changes to repo&lt;br /&gt;
&lt;br /&gt;
 git clone kenneth@git.oeey.com:/git/oeey-git.git oeey-git.git --mirror&lt;br /&gt;
&lt;br /&gt;
=== Mirror Repo ===&lt;br /&gt;
&lt;br /&gt;
Create local mirror:&lt;br /&gt;
 git clone [URL] [dir] --mirror&lt;br /&gt;
 cd [dir]&lt;br /&gt;
 git update-server-info    # DON&#039;T FORGET THIS STEP!&lt;br /&gt;
&lt;br /&gt;
==== Sync Mirror ====&lt;br /&gt;
&lt;br /&gt;
 git remote update&lt;br /&gt;
&lt;br /&gt;
cron job:&lt;br /&gt;
 # 1 AM Sync git mirror&lt;br /&gt;
 0 1 * * *       /usr/bin/git --git-dir=/git/some_git_repo.git remote update&lt;br /&gt;
&lt;br /&gt;
==== Set Mirror Default Branch ====&lt;br /&gt;
&lt;br /&gt;
Option #1 - hack HEAD directly&lt;br /&gt;
 /HEAD&lt;br /&gt;
 ref: refs/heads/main_branch&lt;br /&gt;
&lt;br /&gt;
Option #2 - use symbolic-ref:&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/main_branch&lt;br /&gt;
&lt;br /&gt;
ref:&lt;br /&gt;
* Set the default branch in a Git repository (Example) - https://coderwall.com/p/wmizjg/set-the-default-branch-in-a-git-repository&lt;br /&gt;
* Git: Correct way to change Active Branch in a bare repository? - Stack Overflow - https://stackoverflow.com/questions/3301956/git-correct-way-to-change-active-branch-in-a-bare-repository&lt;br /&gt;
&lt;br /&gt;
== Migrate Repo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir new_repo&lt;br /&gt;
cd new_repo&lt;br /&gt;
git init .&lt;br /&gt;
&lt;br /&gt;
cd ../old_repo&lt;br /&gt;
git remote add origin [path]/new_repo  # or url&lt;br /&gt;
# or manually modify .git/config to point to new repo&lt;br /&gt;
&lt;br /&gt;
git push origin master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Git add is different ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Many revision control systems provide an add command that tells the system to start tracking changes to a new file. Git&#039;s add command does something simpler and more powerful: git add is used both for new and newly modified files, and in both cases it takes a snapshot of the given files and stages that content in the index, ready for inclusion in the next commit.&amp;quot; [http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html]&lt;br /&gt;
&lt;br /&gt;
== cheat git ==&lt;br /&gt;
&lt;br /&gt;
[http://cheat.errtheblog.com/s/git cheat git]&lt;br /&gt;
&lt;br /&gt;
[http://github.com/guides/git-cheat-sheet Git Cheat Sheet - Guides - GitHub]&lt;br /&gt;
&lt;br /&gt;
== forking ==&lt;br /&gt;
&lt;br /&gt;
http://phonegap.pbworks.com/Git%3A-Forking-PhoneGap%C2%A0Documentation&lt;br /&gt;
&lt;br /&gt;
http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/&lt;br /&gt;
&lt;br /&gt;
Help.GitHub - Forking a project - http://help.github.com/forking/&lt;br /&gt;
 #Fork in GitHub&lt;br /&gt;
 &lt;br /&gt;
 # setup&lt;br /&gt;
 git clone git@github.com:billyanyteen/github-services.git&lt;br /&gt;
 cd github-services&lt;br /&gt;
 git remote add upstream git://github.com/pjhyett/github-services.git&lt;br /&gt;
 git fetch upstream&lt;br /&gt;
 &lt;br /&gt;
 # push changes&lt;br /&gt;
 git push origin master&lt;br /&gt;
 &lt;br /&gt;
 # pull changes&lt;br /&gt;
 #git fetch upstream&lt;br /&gt;
 #git merge upstream/master&lt;br /&gt;
 git pull upstream master&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Git forking for fun and profit /by @assaf - http://labnotes.org/2008/04/30/git-forking-for-fun-and-profit/&lt;br /&gt;
* Setting up a long term fork with Git » Programblings - http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/&lt;br /&gt;
* Help.GitHub - Sending pull requests - http://help.github.com/pull-requests/&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
=== git-rm ===&lt;br /&gt;
&lt;br /&gt;
git-rm - Remove files from the working tree and from the index - http://www.kernel.org/pub/software/scm/git/docs/git-rm.html&lt;br /&gt;
&lt;br /&gt;
=== git-mv ===&lt;br /&gt;
&lt;br /&gt;
git-mv - Move or rename a file, a directory, or a symlink - http://www.kernel.org/pub/software/scm/git/docs/git-mv.html&lt;br /&gt;
&lt;br /&gt;
== Log ==&lt;br /&gt;
&lt;br /&gt;
Committed history:&lt;br /&gt;
 git log&lt;br /&gt;
&lt;br /&gt;
Pretty one line logs: (last 3 logs)&lt;br /&gt;
 git log --pretty=oneline -3&lt;br /&gt;
&lt;br /&gt;
== Diff ==&lt;br /&gt;
&lt;br /&gt;
Diff of dirty, tracked files in the tree to the content added to the index:&lt;br /&gt;
 git diff&lt;br /&gt;
&lt;br /&gt;
Diff between index and HEAD of the current branch -- i.e. the changes that will be committed on git commit:&lt;br /&gt;
 git diff --cached&lt;br /&gt;
&lt;br /&gt;
== Patch ==&lt;br /&gt;
&lt;br /&gt;
Create patch:&lt;br /&gt;
 git diff --no-prefix origin/master/HEAD &amp;gt; my_bugNNN.patch&lt;br /&gt;
&lt;br /&gt;
Creating the patch: [http://ariejan.net/2009/10/26/how-to-create-and-apply-a-patch-with-git/]&lt;br /&gt;
 git format-patch [remote]/master --stdout &amp;gt; fix_empty_poster.patch&lt;br /&gt;
&lt;br /&gt;
What changes in patch:&lt;br /&gt;
 git apply --stat fix_empty_poster.patch&lt;br /&gt;
&lt;br /&gt;
Test patch before applying (for conflicting files):&lt;br /&gt;
 git apply --check fix_empty_poster.patch&lt;br /&gt;
&lt;br /&gt;
Apply patch:&lt;br /&gt;
 git apply fix_empty_poster.patch&lt;br /&gt;
&lt;br /&gt;
Apply and signoff patch: (alternate to apply patch with signoff)&lt;br /&gt;
 git am --signoff&lt;br /&gt;
&lt;br /&gt;
== Branches ==&lt;br /&gt;
&lt;br /&gt;
List branches: (* indicates current)&lt;br /&gt;
 git branch       # list local branches&lt;br /&gt;
 git branch -r    # list remote branches&lt;br /&gt;
 git branch -a    # list remote and local branches&lt;br /&gt;
 git branch -v    # list local branches and source&lt;br /&gt;
&lt;br /&gt;
Create branch:&lt;br /&gt;
 git branch [BRANCH]  # local branch of current point in history:&lt;br /&gt;
 git push origin origin:refs/heads/[BRANCH]  # remote empty branch&lt;br /&gt;
&lt;br /&gt;
List origin of current checkout branch: (also lists remote branches)&lt;br /&gt;
 git ls-remote&lt;br /&gt;
&lt;br /&gt;
Checkout branch:&lt;br /&gt;
 git checkout [BRANCH]     # checkout branch&lt;br /&gt;
 git checkout [REMOTE]/[BRANCH]&lt;br /&gt;
 git checkout [LOCALNAME] [REMOTE]/[BRANCH]&lt;br /&gt;
 git checkout -b [BRANCH]   # create and checkout branch&lt;br /&gt;
  #or&lt;br /&gt;
  git switch -c [BRANCH]&lt;br /&gt;
 git checkout --track -b [BRANCH]  # create and set push to use upstream (if not default)&lt;br /&gt;
&lt;br /&gt;
Delete branch:&lt;br /&gt;
 git branch -d [BRANCH]  # delete merged branch (close branch)&lt;br /&gt;
 git branch -D [BRANCH]  # delete non merged branch - destructive&lt;br /&gt;
 git push origin :[BRANCH]  # delete remote branch&lt;br /&gt;
 git push origin :heads/[BRANCH]  # delete remote branch (not sure difference from previous)&lt;br /&gt;
&lt;br /&gt;
Create/Push remote branch:&lt;br /&gt;
 git push [REMOTE] [BRANCH]&lt;br /&gt;
 git push origin [BRANCH]&lt;br /&gt;
 git push [REMOTE] [LOCALBRANCH]:[BRANCH]&lt;br /&gt;
 git push origin origin:refs/heads/[BRANCH]  # remote empty branch&lt;br /&gt;
&lt;br /&gt;
Merge (See [[#Merging]])&lt;br /&gt;
 git merge [BRANCH]   # merge branch into current&lt;br /&gt;
&lt;br /&gt;
Determine branch of a detached head: [http://stackoverflow.com/questions/6059336/what-is-the-simplest-way-to-find-the-current-git-branch-name-when-in-detached-he]&lt;br /&gt;
 git describe --contains --all HEAD&lt;br /&gt;
 git log -n 1 --pretty=%d HEAD&lt;br /&gt;
 git show -s --pretty=%d HEAD&lt;br /&gt;
 git branch --contains HEAD  # not best&lt;br /&gt;
&lt;br /&gt;
Automate creating remote branches: [http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# git-create-branch &amp;lt;branch_name&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
if [ $# -ne 1 ]; then&lt;br /&gt;
         echo 1&amp;gt;&amp;amp;2 Usage: $0 branch_name&lt;br /&gt;
         exit 127&lt;br /&gt;
fi&lt;br /&gt;
 &lt;br /&gt;
set branch_name = $1&lt;br /&gt;
git push origin origin:refs/heads/${branch_name}&lt;br /&gt;
git fetch origin&lt;br /&gt;
git checkout --track -b ${branch_name} origin/${branch_name}&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compare Branches ===&lt;br /&gt;
&lt;br /&gt;
Show diff&lt;br /&gt;
 git diff branch1..branch2&lt;br /&gt;
 git diff branch2..    # compare to current branch&lt;br /&gt;
 git diff branch1...branch2    # only with changes in one but not both with 3 dots (mutually exclusive)&lt;br /&gt;
&lt;br /&gt;
Show only files changed:&lt;br /&gt;
 git diff --name-only  branch1..branch2&lt;br /&gt;
 # with status change:&lt;br /&gt;
 git diff --name-status  branch1..branch2&lt;br /&gt;
 # file with more status details:&lt;br /&gt;
 git diff --stat  branch2..&lt;br /&gt;
&lt;br /&gt;
 eg. diff --name-status&lt;br /&gt;
 M somefile/file1&lt;br /&gt;
&lt;br /&gt;
Show commits between branches&lt;br /&gt;
 git cherry branch2    # and current branch&lt;br /&gt;
 git cherry branch1 branch2&lt;br /&gt;
 git cherry -v branch2    # commit and commit title&lt;br /&gt;
&lt;br /&gt;
 eg. cherry -v&lt;br /&gt;
 + 95aaeac2f9e446018479bd00fc280ab217xxxxxx some title1&lt;br /&gt;
 + 4854da061b80a902b0d2ca0ac367c53d47xxxxxx some title2&lt;br /&gt;
&lt;br /&gt;
Show log between branches:&lt;br /&gt;
 git log branch1..branch2&lt;br /&gt;
 git log branch1...branch2    # show commits either but not both with 3 dots (mutually exclusive)&lt;br /&gt;
 git log branch2..    # compare to current branch&lt;br /&gt;
&lt;br /&gt;
-- others --&lt;br /&gt;
&lt;br /&gt;
Pretty visual output (glog style): &amp;lt;Ref&amp;gt;https://stackoverflow.com/questions/13965391/how-do-i-see-the-commit-differences-between-branches-in-git&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 git log --left-right --graph --cherry-pick --oneline  branch1..branch2&lt;br /&gt;
 git log --left-right --graph --cherry-pick --oneline  branch2..&lt;br /&gt;
&lt;br /&gt;
 git log --graph --pretty=format:&#039;%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset&#039; --abbrev-commit --date=relative master..branch-X&lt;br /&gt;
&lt;br /&gt;
 git log --oneline --graph --all --decorate --abbrev-commit&lt;br /&gt;
 git log --oneline --graph --all --decorate --abbrev-commit branch2..&lt;br /&gt;
&lt;br /&gt;
 git log --all --graph --pretty=format:&#039;%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset&#039;&lt;br /&gt;
&lt;br /&gt;
 git log --oneline --graph --all --decorate&lt;br /&gt;
   # --oneline is short for --pretty=oneline --abbrev-commit&lt;br /&gt;
&lt;br /&gt;
 # commits in develop that are not in master:&lt;br /&gt;
 git log --oneline --no-merges  origin/master..origin/develop&lt;br /&gt;
&lt;br /&gt;
 # show files which ones are modified (not glog style)&lt;br /&gt;
 git diff --stat --no-merges  origin/master..origin/develop&lt;br /&gt;
&lt;br /&gt;
 # show commits about to be merged&lt;br /&gt;
 # HEAD is more convenient to use than branch name&lt;br /&gt;
 git fetch&lt;br /&gt;
 git log --oneline --no-merges  origin/master..HEAD&lt;br /&gt;
&lt;br /&gt;
== Make Two Branches Identical ==&lt;br /&gt;
&lt;br /&gt;
Fake &amp;quot;theirs strategy&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if you want DOWNSTREAM to reflect exactly what UPSTREAM is:&lt;br /&gt;
&lt;br /&gt;
 git switch -c tmp UPSTREAM&lt;br /&gt;
 git merge -s ours DOWNSTREAM   # ignoring all changes from main&lt;br /&gt;
 git switch DOWNSTREAM&lt;br /&gt;
 git merge tmp                  # fast-forward to tmp HEAD, which is dev&lt;br /&gt;
 git branch -D tmp              # deleting tmp&lt;br /&gt;
&lt;br /&gt;
This has the benefit of recording the upstream ancestor as the first parent, so that the merge means &amp;quot;absorb this out-of-date topic branch&amp;quot; rather than &amp;quot;destroy this topic branch and replace it with upstream&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
ref: github - git command for making one branch like another - Stack Overflow https://stackoverflow.com/questions/4911794/git-command-for-making-one-branch-like-another/4912267#4912267&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
The three main ways to do this:&lt;br /&gt;
&lt;br /&gt;
1. Don&#039;t bother. Abandon branch A, make a new A2, and use that.&lt;br /&gt;
&lt;br /&gt;
2. Use git reset or equivalent to re-point A elsewhere.&lt;br /&gt;
&lt;br /&gt;
 Methods 1 and 2 are effectively the same in the long run. For instance, suppose you start by abandoning A. Everyone develops on A2 instead for a while. Then, once everyone is using A2, you delete the name A entirely. Now that A is gone, you can even rename A2 to A (everyone else using it will have to do the same rename, of course). At this point, what, if anything, looks different between the case where you used method 1 and the case where you used method 2? (There is one place you may still be able to see a difference, depending on how long your &amp;quot;long run&amp;quot; is and when you expire old reflogs.)&lt;br /&gt;
&lt;br /&gt;
3. Make a merge, using a special strategy (see &amp;quot;alternative merge strategies&amp;quot; below). What you want here is -s theirs, but it doesn&#039;t exist and you must fake it.&lt;br /&gt;
&lt;br /&gt;
git - Making two branches identical - Stack Overflow - https://stackoverflow.com/questions/36320517/making-two-branches-identical&lt;br /&gt;
&lt;br /&gt;
== Tags ==&lt;br /&gt;
&lt;br /&gt;
Create tag:&lt;br /&gt;
 git tag [TAG]&lt;br /&gt;
 git tag -a [TAG]  # with message using editor&lt;br /&gt;
 git tag -a [TAG] -m &#039;message&#039;  # with message&lt;br /&gt;
&lt;br /&gt;
List tags:&lt;br /&gt;
 git tag&lt;br /&gt;
 git tag -l [PATTERN]&lt;br /&gt;
 git show [TAG]  # show tag details and messages&lt;br /&gt;
&lt;br /&gt;
Delete tag:&lt;br /&gt;
 git tag -d [TAG]&lt;br /&gt;
&lt;br /&gt;
Push tags to remote:&lt;br /&gt;
 git push --tags&lt;br /&gt;
&lt;br /&gt;
Get tags from remote:&lt;br /&gt;
 git fetch&lt;br /&gt;
&lt;br /&gt;
Show current tag: [http://stackoverflow.com/questions/2863756/is-there-a-single-git-command-to-get-the-current-tag-branch-and-commit] [https://stackoverflow.com/questions/4211604/show-all-tags-in-git-log]&lt;br /&gt;
 git describe&lt;br /&gt;
 git describe --always --tag&lt;br /&gt;
 git log --pretty=format:&#039;%ad %h %d&#039; --abbrev-commit --date=short -1&lt;br /&gt;
 git log --no-walk --tags --pretty=&amp;quot;%D-g%h %s&amp;quot;  # show all base tags (for &#039;git describe&#039;)&lt;br /&gt;
&lt;br /&gt;
== Remotes ==&lt;br /&gt;
&lt;br /&gt;
git-remote - manage set of tracked repositories - http://www.kernel.org/pub/software/scm/git/docs/git-remote.html&lt;br /&gt;
&lt;br /&gt;
Remote Git repository tracking&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 man git-remote&lt;br /&gt;
 git help remote&lt;br /&gt;
&lt;br /&gt;
Add remote:&lt;br /&gt;
 git remote add test git://github.com/user/test.git&lt;br /&gt;
 # add and fetch remote details&lt;br /&gt;
 git remote add test git://github.com/user/test.git -f&lt;br /&gt;
&lt;br /&gt;
List remotes:&lt;br /&gt;
 git remote&lt;br /&gt;
 git remote show&lt;br /&gt;
&lt;br /&gt;
Remote details:&lt;br /&gt;
 git remote -v&lt;br /&gt;
 git remote show [REMOTE]&lt;br /&gt;
 git remote show origin&lt;br /&gt;
&lt;br /&gt;
List origin of current checkout branch:&lt;br /&gt;
 git ls-remote&lt;br /&gt;
&lt;br /&gt;
Remove remote:&lt;br /&gt;
 git remote rm [REMOTE]&lt;br /&gt;
&lt;br /&gt;
Rename remote:&lt;br /&gt;
 git remote rename [REMOTE]&lt;br /&gt;
&lt;br /&gt;
Resources:&lt;br /&gt;
* Help.GitHub - Working with remotes - http://help.github.com/remotes/&lt;br /&gt;
&lt;br /&gt;
=== git-fetch ===&lt;br /&gt;
&lt;br /&gt;
Download objects and refs from another repository - http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html&lt;br /&gt;
&lt;br /&gt;
Fetch remote details:&lt;br /&gt;
 git fetch -v&lt;br /&gt;
 git fetch [REMOTE]&lt;br /&gt;
&lt;br /&gt;
Checkout new branch from remote:&lt;br /&gt;
 git checkout -b [LOCALNAME] [REMOTE]/[BRANCH]&lt;br /&gt;
&lt;br /&gt;
=== git-pull ===&lt;br /&gt;
&lt;br /&gt;
git-pull - Fetch from and merge with another repository or a local branch - http://www.kernel.org/pub/software/scm/git/docs/git-pull.html&lt;br /&gt;
&lt;br /&gt;
Pull changes:&lt;br /&gt;
 # Pull changes (git fetch followed by git merge)&lt;br /&gt;
 # defaults to current branch from remote&lt;br /&gt;
 git pull&lt;br /&gt;
 git pull [remote_name]/[branch]&lt;br /&gt;
 git pull origin master&lt;br /&gt;
 git pull --dry-run  # don&#039;t actually do anything&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
You asked me to pull without telling me which branch you&lt;br /&gt;
want to merge with, and &#039;branch.bob.merge&#039; in&lt;br /&gt;
your configuration file does not tell me, either. Please&lt;br /&gt;
specify which branch you want to use on the command line and&lt;br /&gt;
try again (e.g. &#039;git pull &amp;lt;repository&amp;gt; &amp;lt;refspec&amp;gt;&#039;).&lt;br /&gt;
See git-pull(1) for details.&lt;br /&gt;
&lt;br /&gt;
If you often merge with the same branch, you may want to&lt;br /&gt;
use something like the following in your configuration file:&lt;br /&gt;
&lt;br /&gt;
    [branch &amp;quot;bob&amp;quot;]&lt;br /&gt;
    remote = &amp;lt;nickname&amp;gt;&lt;br /&gt;
    merge = &amp;lt;remote-ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    [remote &amp;quot;&amp;lt;nickname&amp;gt;&amp;quot;]&lt;br /&gt;
    url = &amp;lt;url&amp;gt;&lt;br /&gt;
    fetch = &amp;lt;refspec&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See git-config(1) for details.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== git-push ===&lt;br /&gt;
&lt;br /&gt;
NOTE: only can push changes when the &#039;master&#039; branch is checked out.  Other branches do not appear to work.&lt;br /&gt;
&lt;br /&gt;
git-push - Update remote refs along with associated objects - http://www.kernel.org/pub/software/scm/git/docs/git-push.html&lt;br /&gt;
&lt;br /&gt;
Dry run:&lt;br /&gt;
 git push --dry-run [...]&lt;br /&gt;
&lt;br /&gt;
Push changes:&lt;br /&gt;
 # defaults to current branch from remote&lt;br /&gt;
 git push&lt;br /&gt;
 git push remote_name my_branch:remote_branch&lt;br /&gt;
&lt;br /&gt;
 git push REMOTENAME BRANCHNAME&lt;br /&gt;
 git push REMOTENAME LOCALBRANCHNAME:REMOTEBRANCHNAME&lt;br /&gt;
&lt;br /&gt;
NOTE: One important thing is that you should push only to remote branches that are not currently checked out on the other side (for the same reasons you never switch to a remote branch locally)! Otherwise the working copy at the remote branch will get out of date and confusion will ensue.&lt;br /&gt;
&lt;br /&gt;
Create/Push remote branch:&lt;br /&gt;
 git push [REMOTE] [BRANCH]&lt;br /&gt;
 git push [REMOTE] [LOCALBRANCH]:[BRANCH]&lt;br /&gt;
&lt;br /&gt;
 $ git push [ssh://yourserver.com/~you/proj.git] master:master&lt;br /&gt;
 $ git push [ssh://yourserver.com/~you/proj.git] master&lt;br /&gt;
 $ git push [public-repo] master&lt;br /&gt;
 You may force git push to perform the update anyway by preceding the branch name with a plus sign:&lt;br /&gt;
 $ git push ssh://yourserver.com/~you/proj.git +master&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
To git@github.com:user/repo.git&lt;br /&gt;
 ! [rejected]        master -&amp;gt; master (non-fast-forward)&lt;br /&gt;
error: failed to push some refs to &#039;git@github.com:user/repo.git&#039;&lt;br /&gt;
To prevent you from losing history, non-fast-forward updates were rejected&lt;br /&gt;
Merge the remote changes (e.g. &#039;git pull&#039;) before pushing again.  See the&lt;br /&gt;
&#039;Note about fast-forwards&#039; section of &#039;git push --help&#039; for details.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 git pull&lt;br /&gt;
 git push -f&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Failure of branch to push: http://ken-blog.krugler.org/2010/02/25/git-failed-to-push-some-refs-the-multiple-branch-variant/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Push tag: [http://help.github.com/remotes/]&lt;br /&gt;
 git push REMOTENAME TAGNAME&lt;br /&gt;
 # push all tags&lt;br /&gt;
 git push REMOTENAME BRANCHNAME --tags&lt;br /&gt;
&lt;br /&gt;
Delete tag:&lt;br /&gt;
 # You are literally telling git “push nothing into BRANCHNAME on REMOTENAME”&lt;br /&gt;
 git push REMOTENAME :BRANCHNAME&lt;br /&gt;
&lt;br /&gt;
=== change remote ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Changing a remote’s URL - There is no direct command to change a remote’s URL, so you will usually run git remote rm followed by git remote add to change a URL. You can also edit the repo’s .git/config file directly to change the URL without re-fetching the remote.&amp;quot; [http://help.github.com/remotes/]&lt;br /&gt;
 git remote rm [REMOTE]&lt;br /&gt;
 git remote add [REMOTE]&lt;br /&gt;
&lt;br /&gt;
=== Rebase ===&lt;br /&gt;
&lt;br /&gt;
To fetch new items from the git mirror, just do&lt;br /&gt;
&lt;br /&gt;
 git fetch&lt;br /&gt;
&lt;br /&gt;
Then, you&#039;ll need to merge your changes with those in the head. Two options: rebase or merge.&lt;br /&gt;
&lt;br /&gt;
If you haven&#039;t published your changes, you can just use rebase:&lt;br /&gt;
&lt;br /&gt;
 # git rebase [BRANCH]&lt;br /&gt;
 &amp;lt;s&amp;gt;git rebase master&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 git rebase origin/master&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If there are conflicts, it will ask you to resolve them. After all is done, your commits will lie on top of those in git. Note that if one of your commits exactly matches changes made in git, it will silently disappear in rebasing.&lt;br /&gt;
&lt;br /&gt;
An alternative is merging, which does not rewrite history,&lt;br /&gt;
&lt;br /&gt;
 # git merge [BRANCH]&lt;br /&gt;
 git merge master&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Staying abreast SVN - http://projects.scipy.org/numpy/wiki/GitMirror&lt;br /&gt;
&lt;br /&gt;
== Merging ==&lt;br /&gt;
&lt;br /&gt;
Merge branch into current branch&lt;br /&gt;
 git merge [BRANCH]&lt;br /&gt;
&lt;br /&gt;
Don&#039;t auto commit merge:&lt;br /&gt;
 git merge [BRANCH] --no-commit&lt;br /&gt;
&lt;br /&gt;
Git TUI merge tool:&lt;br /&gt;
 git mergetool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Git User’s Manual - Resolving a merge - http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#resolving-a-merge&lt;br /&gt;
&lt;br /&gt;
Show changes to a conflicting file:&lt;br /&gt;
 git diff [FILE]&lt;br /&gt;
&lt;br /&gt;
During the merge, the index holds three versions of each file. Each of these three &amp;quot;file stages&amp;quot; represents a different version of the file:&lt;br /&gt;
 $ git show :1:file.txt  # the file in a common ancestor of both branches&lt;br /&gt;
 $ git show :2:file.txt  # the version from HEAD.&lt;br /&gt;
 $ git show :3:file.txt  # the version from MERGE_HEAD.&lt;br /&gt;
&lt;br /&gt;
 # common base version of the file&lt;br /&gt;
 git show :1:some_file.cpp&lt;br /&gt;
 # &#039;ours&#039; version of the file&lt;br /&gt;
 git show :2:some_file.cpp&lt;br /&gt;
 # &#039;theirs&#039; version of the file&lt;br /&gt;
 git show :3:some_file.cpp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some special diff options allow diffing the working directory against any of these stages:&lt;br /&gt;
 $ git diff -1 file.txt          # diff against stage 1&lt;br /&gt;
 $ git diff --base file.txt      # same as the above&lt;br /&gt;
 $ git diff -2 file.txt          # diff against stage 2&lt;br /&gt;
 $ git diff --ours file.txt      # same as the above&lt;br /&gt;
 $ git diff -3 file.txt          # diff against stage 3&lt;br /&gt;
 $ git diff --theirs file.txt    # same as the above.&lt;br /&gt;
&lt;br /&gt;
If you get stuck and decide to just give up and throw the whole mess away, you can always return to the pre-merge state with&lt;br /&gt;
 $ git reset --hard HEAD&lt;br /&gt;
&lt;br /&gt;
Or, if you’ve already committed the merge that you want to throw away,&lt;br /&gt;
 $ git reset --hard ORIG_HEAD&lt;br /&gt;
&lt;br /&gt;
 git merge [rrepo]/[branch]            # merge remote branch to local&lt;br /&gt;
 git pull . remotes/[rrepo]/[branch]   #  alternate form of merge&lt;br /&gt;
&lt;br /&gt;
== vimdiff ==&lt;br /&gt;
&lt;br /&gt;
vimdiff:&lt;br /&gt;
 vimdiff [options] file1 file2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctrl+w ctrl+w - switch windows&lt;br /&gt;
do - diff obtain change (do below missing)&lt;br /&gt;
dp - diff push changes&lt;br /&gt;
[c - previous difference&lt;br /&gt;
]c - next difference&lt;br /&gt;
:diffupdate - diff update ;)&lt;br /&gt;
:syntax off - syntax off&lt;br /&gt;
zo - open folded text&lt;br /&gt;
zc - close folded text&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change Commit Message ==&lt;br /&gt;
&lt;br /&gt;
Change last commit message with:&lt;br /&gt;
 git commit --amend&lt;br /&gt;
 git commit --amend -m &amp;quot;some message&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Compress Repository ==&lt;br /&gt;
&lt;br /&gt;
Ensuring good performance - http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#ensuring-good-performance&lt;br /&gt;
&lt;br /&gt;
On large repositories, git depends on compression to keep the history information from taking up too much space on disk or in memory.&lt;br /&gt;
&lt;br /&gt;
This compression is not performed automatically. Therefore you should occasionally run git-gc(1):&lt;br /&gt;
&lt;br /&gt;
 $ git gc&lt;br /&gt;
&lt;br /&gt;
to recompress the archive. This can be very time-consuming, so you may prefer to run git gc when you are not doing other work.&lt;br /&gt;
&lt;br /&gt;
== Ignore ==&lt;br /&gt;
&lt;br /&gt;
gitignore - Specifies intentionally untracked files to ignore - http://www.kernel.org/pub/software/scm/git/docs/gitignore.html&lt;br /&gt;
&lt;br /&gt;
Patterns read from a .gitignore file in the same directory as the path, or in any parent directory, with patterns in the higher level files (up to the toplevel of the work tree) being overridden by those in lower level files down to the directory containing the file&lt;br /&gt;
&lt;br /&gt;
Patterns read from $GIT_DIR/info/exclude&lt;br /&gt;
&lt;br /&gt;
    $ cat Documentation/.gitignore&lt;br /&gt;
    # ignore generated html files,&lt;br /&gt;
    *.html&lt;br /&gt;
    # except foo.html which is maintained by hand&lt;br /&gt;
    !foo.html&lt;br /&gt;
&lt;br /&gt;
== Archive (Export) ==&lt;br /&gt;
&lt;br /&gt;
git-commit - Record changes to the repository&lt;br /&gt;
&lt;br /&gt;
Help:&lt;br /&gt;
 man git-archive&lt;br /&gt;
 git help archive&lt;br /&gt;
&lt;br /&gt;
SVN calls this export, Git calls this archive.&lt;br /&gt;
&lt;br /&gt;
Simple method:&lt;br /&gt;
* git clone followed by removing the .git repository directory.&lt;br /&gt;
&lt;br /&gt;
Export project:&lt;br /&gt;
 git archive master | tar -x -C /somewhere/else&lt;br /&gt;
&lt;br /&gt;
Export and compress:&lt;br /&gt;
 git archive master | bzip2 &amp;gt;source-tree.tar.bz2&lt;br /&gt;
&lt;br /&gt;
Zip archive:&lt;br /&gt;
 git archive --format zip --output /full/path master&lt;br /&gt;
&lt;br /&gt;
Prefix folder in zip:&lt;br /&gt;
 git archive --format zip --output /path/to/file.zip --prefix=newdir/ master&lt;br /&gt;
&lt;br /&gt;
Uncompressed archive (-0 for uncompressed)&lt;br /&gt;
 git archive --format zip --output &amp;quot;output.zip&amp;quot; master -0&lt;br /&gt;
&lt;br /&gt;
Archive latest:&lt;br /&gt;
 git archive -o latest.zip HEAD&lt;br /&gt;
&lt;br /&gt;
git export:&lt;br /&gt;
 git checkout-index -a -f --prefix=/destination/path/&lt;br /&gt;
 git checkout-index --prefix=git-export-dir/ -a&lt;br /&gt;
&lt;br /&gt;
with remote:&lt;br /&gt;
 git-archive --format=tar --remote=ssh://remote_server/remote_repository master | tar -xf -&lt;br /&gt;
&lt;br /&gt;
other: [http://www.clientcide.com/best-practices/exporting-files-from-git-similar-to-svn-export/]&lt;br /&gt;
 git archive HEAD | (cd ~/path/where/I/want/it/ &amp;amp;&amp;amp; tar -xvf -)&lt;br /&gt;
 rsync path/I/want/to/export/ -ri --del -m --exclude &amp;quot;.*&amp;quot; ~/path/where/I/want/it/ |grep sT&lt;br /&gt;
&lt;br /&gt;
other 2: [http://www.devdaily.com/git/git-export-project-archive-cvs-svn-export]&lt;br /&gt;
 git archive master | gzip &amp;gt; latest.tgz&lt;br /&gt;
 git archive master | bzip2 &amp;gt; latest.tar.bz2&lt;br /&gt;
&lt;br /&gt;
Resources:&lt;br /&gt;
* How to do a &amp;quot;git export&amp;quot; (like &amp;quot;svn export&amp;quot;) - Stack Overflow - http://stackoverflow.com/questions/160608/how-to-do-a-git-export-like-svn-export&lt;br /&gt;
&lt;br /&gt;
== Git Server ==&lt;br /&gt;
&lt;br /&gt;
[http://tumblr.intranation.com/post/766290565/how-set-up-your-own-private-git-server-linux How to set up your own private Git server on Linux | Bradley Wright] (using SSH)&lt;br /&gt;
&lt;br /&gt;
?? (using git-daemon)&lt;br /&gt;
 man git-daemon&lt;br /&gt;
&lt;br /&gt;
 yum install git-daemon&lt;br /&gt;
&lt;br /&gt;
== Destructive Operations ==&lt;br /&gt;
&lt;br /&gt;
=== Rewrite Commit Authors ===&lt;br /&gt;
&lt;br /&gt;
List authors:&lt;br /&gt;
 git log --all --format=&#039;%aN &amp;lt;%aE&amp;gt; - %cN &amp;lt;%cE&amp;gt;&#039; | sort -u&lt;br /&gt;
&lt;br /&gt;
Redo all commits:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for i in 1 2 ; do&lt;br /&gt;
git filter-branch -f --tag-name-filter cat --commit-filter &#039;&lt;br /&gt;
        GIT_AUTHOR_NAME=&amp;quot;Admin&amp;quot;;&lt;br /&gt;
        GIT_AUTHOR_EMAIL=&amp;quot;admin@t0e.org&amp;quot;;&lt;br /&gt;
        GIT_COMMITTER_NAME=&amp;quot;Admin&amp;quot;;&lt;br /&gt;
        GIT_COMMITTER_EMAIL=&amp;quot;admin@t0e.org&amp;quot;;&lt;br /&gt;
        git commit-tree &amp;quot;$@&amp;quot;&#039; -- --all&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: will need a &#039;-f&#039; to overwrite backup if you ever run a second time.&lt;br /&gt;
&lt;br /&gt;
Rewrite certain commits:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for i in 1 2 ; do&lt;br /&gt;
git filter-branch --tag-name-filter cat --commit-filter &#039;&lt;br /&gt;
        if [ &amp;quot;$GIT_AUTHOR_NAME&amp;quot; = &amp;quot;Ryan&amp;quot; -o &amp;quot;$GIT_AUTHOR_NAME&amp;quot; = &amp;quot;Ryan Test&amp;quot; ];&lt;br /&gt;
        then&lt;br /&gt;
                GIT_AUTHOR_NAME=&amp;quot;Ryan Test&amp;quot;;&lt;br /&gt;
                GIT_AUTHOR_EMAIL=&amp;quot;rtest@oeey.com&amp;quot;;&lt;br /&gt;
                GIT_COMMITTER_NAME=&amp;quot;Ryan Test&amp;quot;;&lt;br /&gt;
                GIT_COMMITTER_EMAIL=&amp;quot;rtest@oeey.com&amp;quot;;&lt;br /&gt;
        elif [ &amp;quot;$GIT_AUTHOR_NAME&amp;quot; = &amp;quot;Mike Test&amp;quot; ];&lt;br /&gt;
        then&lt;br /&gt;
                GIT_AUTHOR_NAME=&amp;quot;Mike Test&amp;quot;;&lt;br /&gt;
                GIT_AUTHOR_EMAIL=&amp;quot;mtest@oeey.com&amp;quot;;&lt;br /&gt;
        fi;&lt;br /&gt;
        git commit-tree &amp;quot;$@&amp;quot;&#039; -- --all&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fancier filter [http://stackoverflow.com/questions/392332/retroactively-correct-authors-with-git-svn]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
git filter-branch --env-filter &#039;&lt;br /&gt;
&lt;br /&gt;
n=$GIT_AUTHOR_NAME&lt;br /&gt;
m=$GIT_AUTHOR_EMAIL&lt;br /&gt;
&lt;br /&gt;
case ${GIT_AUTHOR_NAME} in&lt;br /&gt;
        user1) n=&amp;quot;User One&amp;quot; ; m=&amp;quot;user1@example.com&amp;quot; ;;&lt;br /&gt;
        &amp;quot;User Two&amp;quot;) n=&amp;quot;User Two&amp;quot; ; m=&amp;quot;user2@example.com&amp;quot; ;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
export GIT_AUTHOR_NAME=&amp;quot;$n&amp;quot;&lt;br /&gt;
export GIT_AUTHOR_EMAIL=&amp;quot;$m&amp;quot;&lt;br /&gt;
export GIT_COMMITTER_NAME=&amp;quot;$n&amp;quot;&lt;br /&gt;
export GIT_COMMITTER_EMAIL=&amp;quot;$m&amp;quot;&lt;br /&gt;
&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== GitHub ==&lt;br /&gt;
&lt;br /&gt;
 SSH: git@github.com:kiloforce/test.git&lt;br /&gt;
 HTTP: https://kiloforce@github.com/kiloforce/test.git&lt;br /&gt;
 Git Read-Only: git://github.com/kiloforce/test.git&lt;br /&gt;
&lt;br /&gt;
Global setup:&lt;br /&gt;
 Download and install Git&lt;br /&gt;
  git config --global user.name &amp;quot;Kilo Force&amp;quot;&lt;br /&gt;
  git config --global user.email kiloforce@oeey.com&lt;br /&gt;
&lt;br /&gt;
Next steps:&lt;br /&gt;
  mkdir test&lt;br /&gt;
  cd test&lt;br /&gt;
  git init&lt;br /&gt;
  touch README&lt;br /&gt;
  git add README&lt;br /&gt;
  git commit -m &#039;first commit&#039;&lt;br /&gt;
  git remote add origin git@github.com:kiloforce/test.git&lt;br /&gt;
  git push origin master&lt;br /&gt;
&lt;br /&gt;
Existing Git Repo?&lt;br /&gt;
  cd existing_git_repo&lt;br /&gt;
  git remote add origin git@github.com:kiloforce/test.git&lt;br /&gt;
  git push origin master&lt;br /&gt;
      &lt;br /&gt;
Importing a Subversion Repo:&lt;br /&gt;
 https://github.com/kiloforce/test/imports/new&lt;br /&gt;
      &lt;br /&gt;
When you&#039;re done:&lt;br /&gt;
 https://github.com/kiloforce/test&lt;br /&gt;
&lt;br /&gt;
Check out project:&lt;br /&gt;
 git clone git@github.com:kiloforce/test.git test&lt;br /&gt;
 ( modify files )&lt;br /&gt;
 git commit -a -m &#039;changes&#039;&lt;br /&gt;
 git push&lt;br /&gt;
 # git push git@github.com:kiloforce/test.git&lt;br /&gt;
&lt;br /&gt;
NOTE: don&#039;t check out from https://github.com/kiloforce/test or you will get this error:&lt;br /&gt;
 fatal: remote error:&lt;br /&gt;
   You can&#039;t push to git://github.com/kiloforce/test.git&lt;br /&gt;
   Use git@github.com:kiloforce/test.git&lt;br /&gt;
&lt;br /&gt;
=== SVN for GitHub ===&lt;br /&gt;
&lt;br /&gt;
Ever wanted to use SVN to grab code from GitHub? Well, now you can, and just like that GitHub is the world&#039;s biggest Subversion host. Here&#039;s a few things you might like to do with it:&lt;br /&gt;
* Use any GitHub repository as an SVN external.&lt;br /&gt;
* Use TortoiseSVN or your favorite SVN tool to view Git repositories.&lt;br /&gt;
* Use existing build tools or continuous integrations systems that only work with SVN.&lt;br /&gt;
&lt;br /&gt;
Check out projects through svn.github.com: (http or https)&lt;br /&gt;
 svn checkout https://svn.github.com/kiloforce/test.git test&lt;br /&gt;
&lt;br /&gt;
Notice, on checkout there will be the following error that can be ignored.&lt;br /&gt;
 REPORT of &#039;/kiloforce/test.git/!svn/vcc/default&#039;: 200 OK (https://svn.github.com)&lt;br /&gt;
References:&lt;br /&gt;
* Announcing SVN Support - GitHub - http://github.com/blog/626-announcing-svn-support&lt;br /&gt;
* Subversion Write Support - GitHub - https://github.com/blog/644-subversion-write-support&lt;br /&gt;
&lt;br /&gt;
=== Caching Password ===&lt;br /&gt;
&lt;br /&gt;
authentication - Git push requires username and password - Stack Overflow - http://stackoverflow.com/questions/6565357/git-push-requires-username-and-password&lt;br /&gt;
&lt;br /&gt;
The following command will save your password in memory for sometime.&lt;br /&gt;
(For git 1.7.10 or newer.)&lt;br /&gt;
&lt;br /&gt;
 # Set git to use the credential memory cache&lt;br /&gt;
 $ git config --global credential.helper cache&lt;br /&gt;
&lt;br /&gt;
 # Set the cache to timeout after 1 hour (setting is in seconds)&lt;br /&gt;
 $ git config --global credential.helper &#039;cache --timeout=3600&#039;&lt;br /&gt;
&lt;br /&gt;
You can also add to your git config (in repo or common), to remember which user name:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[credential &amp;quot;https://example.com&amp;quot;]&lt;br /&gt;
    username = kiloforce&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Credential Store ===&lt;br /&gt;
&lt;br /&gt;
 ~/.git-credentials&lt;br /&gt;
&lt;br /&gt;
 git config credential.helper &#039;store &amp;lt;options&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://git-scm.com/docs/git-credential-store&lt;br /&gt;
&lt;br /&gt;
== Notch anti Git ==&lt;br /&gt;
&lt;br /&gt;
:Oh, and I’ve finally committed the Music Blocks to the repository.&lt;br /&gt;
&lt;br /&gt;
:(Oh, wait, no, I didn’t.. Doing so broke git, so we’re changing to svn because git is horrible and evil)&lt;br /&gt;
&lt;br /&gt;
-- Notch (Jan 06, 2011)&lt;br /&gt;
&lt;br /&gt;
Source: http://notch.tumblr.com/post/2623477410/strategy-meeting-day-results&lt;br /&gt;
&lt;br /&gt;
== Git vs the World ==&lt;br /&gt;
&lt;br /&gt;
Why Git is Better Than X - http://whygitisbetterthanx.com/&lt;br /&gt;
&lt;br /&gt;
== [http://git-scm.com/ Git Quick Start] ==&lt;br /&gt;
&lt;br /&gt;
Cloning and Creating a Patch:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git clone git://github.com/git/hello-world.git&lt;br /&gt;
$ cd hello-world&lt;br /&gt;
$ (edit files)&lt;br /&gt;
$ git add (files)&lt;br /&gt;
$ git commit -m &#039;Explain what I changed&#039;&lt;br /&gt;
$ git format-patch origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating and Commiting:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cd (project-directory)&lt;br /&gt;
$ git init&lt;br /&gt;
$ (add some files)&lt;br /&gt;
$ git add .&lt;br /&gt;
$ git commit -m &#039;Initial commit&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
[http://git.or.cz/gitwiki/GitFaq GitFaq - GitWiki]&lt;br /&gt;
&lt;br /&gt;
[http://git-scm.com/documentation Git - Documentation]&lt;br /&gt;
&lt;br /&gt;
[http://www.kernel.org/pub/software/scm/git/docs/user-manual.html Git User&#039;s Manual (for version 1.5.3 or newer)]&lt;br /&gt;
&lt;br /&gt;
[http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html Official Git Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://git-scm.com/course/svn.html SVN to Git Crash Course]&lt;br /&gt;
&lt;br /&gt;
[http://www.spheredev.org/wiki/Git_for_the_lazy Git for the lazy - Spheriki]&lt;br /&gt;
&lt;br /&gt;
[http://www-cs-students.stanford.edu/~blynn/gitmagic/ Git Magic]&lt;br /&gt;
&lt;br /&gt;
[http://linux.yyz.us/git-howto.html Kernel Hackers&#039; Guide to git]&lt;br /&gt;
&lt;br /&gt;
== Ports ==&lt;br /&gt;
&lt;br /&gt;
Git uses port 9418:&lt;br /&gt;
&lt;br /&gt;
 git clone git://git.kernel.org/pub/scm/git/git.git&lt;br /&gt;
&lt;br /&gt;
If you have problems connecting (Git uses port 9418), you can try to access the repository over the HTTP protocol:&lt;br /&gt;
&lt;br /&gt;
 git clone http://www.kernel.org/pub/scm/git/git.git&lt;br /&gt;
&lt;br /&gt;
== Git vs SVN ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Git&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;SVN&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;git clone url&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;svn checkout url&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;git pull&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;svn update&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Git Turotials ==&lt;br /&gt;
&lt;br /&gt;
[http://git.or.cz/course/svn.html Git - SVN Crash Course]&lt;br /&gt;
&lt;br /&gt;
== [http://git-scm.com/download Download] ==&lt;br /&gt;
&lt;br /&gt;
This includes links for binaries and source code.&lt;br /&gt;
&lt;br /&gt;
== gerrit - code review ==&lt;br /&gt;
&lt;br /&gt;
gerrit - Gerrit Code Review - Google Project Hosting - http://code.google.com/p/gerrit/&lt;br /&gt;
&lt;br /&gt;
Web based code review and project management for Git based projects.&lt;br /&gt;
&lt;br /&gt;
Gerrit is a web based code review system, facilitating online code reviews for projects using the Git version control system.&lt;br /&gt;
&lt;br /&gt;
Gerrit makes reviews easier by showing changes in a side-by-side display, and allowing inline comments to be added by any reviewer.&lt;br /&gt;
&lt;br /&gt;
Gerrit simplifies Git based project maintainership by permitting any authorized user to submit changes to the master Git repository, rather than requiring all approved changes to be merged in by hand by the project maintainer. This functionality enables a more centralized usage of Git.&lt;br /&gt;
Resources&lt;br /&gt;
&lt;br /&gt;
See [[Gerrit Code Review]]&lt;br /&gt;
&lt;br /&gt;
== ssh config ==&lt;br /&gt;
&lt;br /&gt;
~/.ssh/config&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host myserver&lt;br /&gt;
  user bob&lt;br /&gt;
Host *&lt;br /&gt;
  user jenkins&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host gh-foo&lt;br /&gt;
    Hostname github.com&lt;br /&gt;
    User git&lt;br /&gt;
    IdentityFile ~/.ssh/foo_github_id&lt;br /&gt;
Host gh-bar&lt;br /&gt;
    Hostname github.com&lt;br /&gt;
    User git&lt;br /&gt;
    IdentityFile ~/.ssh/bar_github_id&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Specify SSH Key from Command Line ===&lt;br /&gt;
&lt;br /&gt;
 GIT_SSH_COMMAND=&amp;quot;ssh -i /path/to/id_rsa&amp;quot; git clone ssh://git@git.server.com/path/repo&lt;br /&gt;
&lt;br /&gt;
== Create Empty Branch ==&lt;br /&gt;
&lt;br /&gt;
November 2021 Update: As of git version 2.27, you can now use git switch --orphan &amp;lt;new branch&amp;gt; to create an empty branch with no history.&lt;br /&gt;
&lt;br /&gt;
 git switch --orphan &amp;lt;new branch&amp;gt;&lt;br /&gt;
 git commit --allow-empty -m &amp;quot;Initial commit on orphan branch&amp;quot;&lt;br /&gt;
 git push -u origin &amp;lt;new branch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Original solution:&lt;br /&gt;
&lt;br /&gt;
 git checkout --orphan empty-branch&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 git commit --allow-empty -m &amp;quot;root commit&amp;quot;&lt;br /&gt;
 git push origin empty-branch&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/34100048/create-empty-branch-on-github]&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Use option --orphan to create branch with no parents.&lt;br /&gt;
&lt;br /&gt;
 git checkout --orphan new-empty-branch &lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 git commit --allow-empty -m &amp;quot;Initial commit on orphan branch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ref: [https://tecadmin.net/git-create-empty-branch/]&lt;br /&gt;
&lt;br /&gt;
== Force Local Repository to Match Remote ==&lt;br /&gt;
&lt;br /&gt;
 git remote prune origin  # remove branches not on origin&lt;br /&gt;
&lt;br /&gt;
 git fetch origin --prune --tags&lt;br /&gt;
 git reset --hard origin/HEAD&lt;br /&gt;
 git clean -df&lt;br /&gt;
&lt;br /&gt;
Cleanup:&lt;br /&gt;
 git gc&lt;br /&gt;
 du --si --max-depth=1 .git&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
 git fetch --prune    # (optional) Updates the local snapshot of the remote repo. Further commands are local only.&lt;br /&gt;
 git reset --hard @{upstream}    # Puts the local branch pointer to where the snapshot of the remote is, as well as set the index and the working directory to the files of that commit.&lt;br /&gt;
 git clean -d --force    #  Removes untracked files and directories which hinder git to say “working directory clean”.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
reset-repo.sh :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# reset the current repository&lt;br /&gt;
# WF 2012-10-15&lt;br /&gt;
# AT 2012-11-09&lt;br /&gt;
# see http://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head&lt;br /&gt;
timestamp=`date &amp;quot;+%Y-%m-%d-%H_%M_%S&amp;quot;`&lt;br /&gt;
branchname=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`&lt;br /&gt;
read -p &amp;quot;Reset branch $branchname to origin (y/n)? &amp;quot;&lt;br /&gt;
[ &amp;quot;$REPLY&amp;quot; != &amp;quot;y&amp;quot; ] || &lt;br /&gt;
echo &amp;quot;about to auto-commit any changes&amp;quot;&lt;br /&gt;
git commit -a -m &amp;quot;auto commit at $timestamp&amp;quot;&lt;br /&gt;
if [ $? -eq 0 ]&lt;br /&gt;
then&lt;br /&gt;
  echo &amp;quot;Creating backup auto-save branch: auto-save-$branchname-at-$timestamp&amp;quot;&lt;br /&gt;
  git branch &amp;quot;auto-save-$branchname-at-$timestamp&amp;quot; &lt;br /&gt;
fi&lt;br /&gt;
echo &amp;quot;now resetting to origin/$branchname&amp;quot;&lt;br /&gt;
git fetch origin&lt;br /&gt;
git reset --hard origin/$branchname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ref: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/1628088/reset-local-repository-branch-to-be-just-like-remote-repository-head/13308579#13308579&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
To force your local Git repository to exactly match the remote, including branches, tags, and purging untracked files, a series of commands is typically used. This process is destructive and will discard all local changes and commits that are not on the remote.&lt;br /&gt;
&lt;br /&gt;
1. Fetch the latest changes and prune remote-tracking branches:&lt;br /&gt;
&lt;br /&gt;
 git fetch origin --prune --tags&lt;br /&gt;
&lt;br /&gt;
This command fetches all new branches and tags from the origin remote and removes any local remote-tracking branches that no longer exist on the remote.&lt;br /&gt;
&lt;br /&gt;
2. Reset your current local branch to match the remote branch:&lt;br /&gt;
&lt;br /&gt;
 git reset --hard origin/&amp;lt;branch_name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace &amp;lt;branch_name&amp;gt; with the name of the branch you are currently on and want to reset (e.g., main, master, develop). This command discards all local commits and changes on the current branch, making it identical to the specified remote branch.&lt;br /&gt;
&lt;br /&gt;
3. Clean your working directory of untracked files and directories:&lt;br /&gt;
&lt;br /&gt;
 git clean -df&lt;br /&gt;
&lt;br /&gt;
* git clean -d: Removes untracked directories in addition to untracked files.&lt;br /&gt;
* git clean -f: Forces the removal of untracked files and directories.&lt;br /&gt;
&lt;br /&gt;
4. (Optional) Delete local branches that no longer exist on the remote: &lt;br /&gt;
&lt;br /&gt;
While git fetch --prune handles remote-tracking branches, you might have local branches that are no longer relevant and don&#039;t have a remote counterpart. You can list and manually delete these:&lt;br /&gt;
Code&lt;br /&gt;
&lt;br /&gt;
 git branch -vv | grep &#039;: gone]&#039;&lt;br /&gt;
&lt;br /&gt;
This command lists local branches that are tracking remote branches that have been deleted. You can then delete them using:&lt;br /&gt;
&lt;br /&gt;
 git branch -D &amp;lt;local_branch_name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. (Optional) Delete local tags that no longer exist on the remote:&lt;br /&gt;
&lt;br /&gt;
If you need to synchronize tags, and some local tags are not present on the remote, you can delete them locally:&lt;br /&gt;
&lt;br /&gt;
 git tag -d &amp;lt;tag_name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Caution: This entire process is destructive. Ensure you have backed up any work you wish to preserve before executing these commands. You cannot easily undo a git reset --hard or git clean -f.&lt;br /&gt;
&lt;br /&gt;
ref: Google AI&lt;br /&gt;
&lt;br /&gt;
== Sign Commit ==&lt;br /&gt;
&lt;br /&gt;
Create GPG key, and set gpgsign = true&lt;br /&gt;
&lt;br /&gt;
Sign all commits with gpgsign:&lt;br /&gt;
 git config --global commit.gpgsign true&lt;br /&gt;
&lt;br /&gt;
~/.gitconfig :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[commit]&lt;br /&gt;
    gpgsign = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sign single commit:&lt;br /&gt;
 git commit -S&lt;br /&gt;
 git commit --gpg-sign&lt;br /&gt;
&lt;br /&gt;
With signing key:&lt;br /&gt;
 git config --global commit.gpgsign true&lt;br /&gt;
 git config --global gpg.format openpgp    # default&lt;br /&gt;
 git config --global user.signingkey 123456789....&lt;br /&gt;
&lt;br /&gt;
Get signing key:&lt;br /&gt;
 gpg -K&lt;br /&gt;
=== SSH Signing ===&lt;br /&gt;
&lt;br /&gt;
 git config --global gpg.format ssh&lt;br /&gt;
&lt;br /&gt;
 git config --global commit.gpgsign true&lt;br /&gt;
 git config --global gpg.format ssh&lt;br /&gt;
 git config --global user.signingkey signingkey C:/Users/username/.ssh/id_ed25519.pub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
If you get this error when doing a &amp;quot;git log --show-signature&amp;quot;&lt;br /&gt;
 error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification&lt;br /&gt;
 commit d04axxxxxxxxxxxxxxxxxx (HEAD -&amp;gt; some/branch)&lt;br /&gt;
 No signature&lt;br /&gt;
&lt;br /&gt;
Do this:&lt;br /&gt;
 git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers&lt;br /&gt;
&lt;br /&gt;
And add allowed with something like the following:&lt;br /&gt;
 echo &amp;quot;$(git config --get user.email) namespaces=\&amp;quot;git\&amp;quot; $(cat ~/.ssh/signing.pub)&amp;quot; &amp;gt;&amp;gt; ~/.ssh/allowed_signers&lt;br /&gt;
&lt;br /&gt;
=== generate GPG keys ===&lt;br /&gt;
&lt;br /&gt;
 gpg --full-generate-key&lt;br /&gt;
&lt;br /&gt;
=== Show siged commits ===&lt;br /&gt;
&lt;br /&gt;
 git log --show-signature&lt;br /&gt;
&lt;br /&gt;
=== Linux gpg ===&lt;br /&gt;
&lt;br /&gt;
 Adding a GPG key to your GitHub account - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account&lt;br /&gt;
&lt;br /&gt;
Generate key:&lt;br /&gt;
 gpg --full-generate-key&lt;br /&gt;
&lt;br /&gt;
List keys to get keyID&lt;br /&gt;
 gpg --list-keys&lt;br /&gt;
&lt;br /&gt;
Export public key by keyID, and save to Github&lt;br /&gt;
 gpg --armor --export 3AA5C34371xxx&lt;br /&gt;
&lt;br /&gt;
You will probably get an error about being unable to sign if you are in a remote console, to fix this: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/51504367/gpg-agent-forwarding-inappropriate-ioctl-for-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
 export GPG_TTY=$(tty)&lt;br /&gt;
&lt;br /&gt;
Cache password in gpg-agent:&lt;br /&gt;
 echo &amp;quot;&amp;quot; | gpg --clearsign&lt;br /&gt;
&lt;br /&gt;
 ~/.bashrc&lt;br /&gt;
 alias gpgpass=&amp;quot;echo &#039;&#039; | gpg --clearsign&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you really hate security, you can remove the passphrase:&lt;br /&gt;
 gpg --edit-key XXX&lt;br /&gt;
   passwd&lt;br /&gt;
    enter password to unlock&lt;br /&gt;
    then enter empty password twice&lt;br /&gt;
    then save&lt;br /&gt;
&lt;br /&gt;
Restart agent&lt;br /&gt;
&lt;br /&gt;
==== Reset GPG Agent ====&lt;br /&gt;
&lt;br /&gt;
Reset GPG agent: &amp;lt;ref&amp;gt;https://superuser.com/questions/1075404/how-can-i-restart-gpg-agent&amp;lt;/ref&amp;gt;&lt;br /&gt;
 gpgconf --kill gpg-agent&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
&lt;br /&gt;
 gpg-connect-agent reloadagent /bye&lt;br /&gt;
&lt;br /&gt;
 systemctl --user status gpg-agent&lt;br /&gt;
 systemctl --user stop gpg-agent&lt;br /&gt;
 systemctl --user start gpg-agent&lt;br /&gt;
&lt;br /&gt;
 gpg-connect-agent /bye&lt;br /&gt;
&lt;br /&gt;
 # kill the agent&lt;br /&gt;
 gpg-connect-agent killagent /bye&lt;br /&gt;
 # start it again&lt;br /&gt;
 gpg-connect-agent /bye&lt;br /&gt;
&lt;br /&gt;
== Mercurial ==&lt;br /&gt;
&lt;br /&gt;
=== Git for Mercurial users ===&lt;br /&gt;
&lt;br /&gt;
Command equivalence table - http://mercurial.selenic.com/wiki/GitConcepts#Command_equivalence_table&lt;br /&gt;
&lt;br /&gt;
Git vs Mercurial - WikiVS - http://www.wikivs.com/wiki/Git_vs_Mercurial&lt;br /&gt;
&lt;br /&gt;
See [[Git vs Mercurial]]&lt;br /&gt;
&lt;br /&gt;
=== Convert Git to Mercurial ===&lt;br /&gt;
&lt;br /&gt;
Really easy!&lt;br /&gt;
 hg convert [git_repo] [hg_repo]&lt;br /&gt;
&lt;br /&gt;
=== Convert Mercurial to Git ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone git://repo.or.cz/fast-export.git&lt;br /&gt;
git init git_repo&lt;br /&gt;
cd git_repo&lt;br /&gt;
~/fast-export/hg-fast-export.sh -r /path/to/old/mercurial_repo&lt;br /&gt;
git checkout HEAD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: Convert Mercurial project to Git - Stack Overflow - http://stackoverflow.com/questions/16037787/convert-mercurial-project-to-git&lt;br /&gt;
&lt;br /&gt;
=== hg id ===&lt;br /&gt;
&lt;br /&gt;
 git rev-parse HEAD&lt;br /&gt;
&lt;br /&gt;
 # git rev-parse HEAD&lt;br /&gt;
 ecf4fb28be83f2f1fcfe56b7311ee3477ab742c2&lt;br /&gt;
&lt;br /&gt;
=== incoming and outgoing ===&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
 out = log --pretty=oneline --abbrev-commit --graph @{u}..&lt;br /&gt;
 outgoing = log --pretty=oneline --abbrev-commit --graph @{u}..&lt;br /&gt;
 in = !git fetch &amp;amp;&amp;amp; git log --pretty=oneline --abbrev-commit --graph ..@{u}&lt;br /&gt;
 incoming = !git fetch &amp;amp;&amp;amp; git log --pretty=oneline --abbrev-commit --graph ..@{u}&lt;br /&gt;
&lt;br /&gt;
Note: run &amp;quot;git fetch&amp;quot; first&lt;br /&gt;
&lt;br /&gt;
Reference:&lt;br /&gt;
* Coderwall | git outgoing/incoming changes - https://coderwall.com/p/fowimq/git-outgoing-incoming-changes&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Mimic &#039;hg incoming&#039; and &#039;hg outgoing&#039;&lt;br /&gt;
&lt;br /&gt;
hg incoming:&lt;br /&gt;
 git log ..@{u}&lt;br /&gt;
hg outgoing:&lt;br /&gt;
 git log @{u}..&lt;br /&gt;
&lt;br /&gt;
 git config --global alias.incoming &#039;!git remote update -p; git log ..@{u}&#039;&lt;br /&gt;
 git config --global alias.outgoing &#039;log @{u}..&#039;&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
 incoming = &amp;quot;!git remote update -p; git log ..@{u}&amp;quot;&lt;br /&gt;
 outgoing = log @{u}..&lt;br /&gt;
&lt;br /&gt;
Reference:&lt;br /&gt;
mercurial - Using Git how do I find changes between local and remote - Stack Overflow - http://stackoverflow.com/questions/231211/using-git-how-do-i-find-changes-between-local-and-remote&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
=== Unable to find http helper ===&lt;br /&gt;
&lt;br /&gt;
Issue:&lt;br /&gt;
 $ git clone git://github.com/git/hello-world.git&lt;br /&gt;
 fatal: Unable to find remote helper for &#039;http&#039;&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* The curl library was missing when git was compiled&lt;br /&gt;
* Install curl-devel and recompile.&lt;br /&gt;
&lt;br /&gt;
=== Connection Refused ===&lt;br /&gt;
&lt;br /&gt;
Issue:&lt;br /&gt;
 $ git clone git://github.com/git/hello-world.git&lt;br /&gt;
 Initialized empty Git repository in /data/store/home/kenneth/git-1.7.1/hello-world/.git/&lt;br /&gt;
 github.com[0: 207.97.227.239]: errno=Connection refused&lt;br /&gt;
 fatal: unable to connect a socket (Connection refused)&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* Open outbound TCP port 9418 on the Firewall&lt;br /&gt;
&lt;br /&gt;
=== bash: git-upload-pack: command not found ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git clone username@host:~/project/path/contactdb&lt;br /&gt;
Initialized empty Git repository in &lt;br /&gt;
  c:/Documents and Settings/Administrator/My Documents/projects/contactdb/.git/&lt;br /&gt;
bash: git-upload-pack: command not found&lt;br /&gt;
fatal: The remote end hung up unexpectedly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why is this git clone command failing? - Stack Overflow - http://stackoverflow.com/questions/999195/why-is-this-git-clone-command-failing&lt;br /&gt;
&lt;br /&gt;
test with:&lt;br /&gt;
 ssh [server] git-upload-pack&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
* If this fails, add the path to the program to the user&#039;s .bashrc on the remote server&lt;br /&gt;
&lt;br /&gt;
=== insufficient permission ===&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
 error: insufficient permission for adding an object to repository database ./objects&lt;br /&gt;
&lt;br /&gt;
Fix:&lt;br /&gt;
 sudo chown -R git:git repo.git/&lt;br /&gt;
&lt;br /&gt;
 sudo chmod -R gituser.gituser objects&lt;br /&gt;
&lt;br /&gt;
git - Error pushing to GitHub - insufficient permission for adding an object to repository database - Stack Overflow - http://stackoverflow.com/questions/1918524/error-pushing-to-github-insufficient-permission-for-adding-an-object-to-reposit&lt;br /&gt;
&lt;br /&gt;
=== ssl certificate verify failed ===&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
 error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed&lt;br /&gt;
&lt;br /&gt;
or with Git LFS:&lt;br /&gt;
 tls: failed to verify certificate: x509: certificate signed by unknown authority&lt;br /&gt;
&lt;br /&gt;
Ignore ssl certificate verification: [http://stackoverflow.com/questions/3777075/https-github-access]&lt;br /&gt;
 export GIT_SSL_NO_VERIFY=true&lt;br /&gt;
 # or&lt;br /&gt;
 git config --global http.sslverify false&lt;br /&gt;
&lt;br /&gt;
 git clone https://github...&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none - Stack Overflow - http://stackoverflow.com/questions/21181231/server-certificate-verification-failed-cafile-etc-ssl-certs-ca-certificates-c&lt;br /&gt;
* docker - Git LFS give x509: certificate signed by unknown authority - Stack Overflow - https://stackoverflow.com/questions/60349972/git-lfs-give-x509-certificate-signed-by-unknown-authority&lt;br /&gt;
&lt;br /&gt;
=== insufficient permission for adding an object to repository database ./objects ===&lt;br /&gt;
&lt;br /&gt;
 $ git push origin master&lt;br /&gt;
 ...&lt;br /&gt;
 error: insufficient permission for adding an object to repository database ./objects&lt;br /&gt;
 fatal: failed to write object&lt;br /&gt;
 error: unpack failed: unpack-objects abnormal exit&lt;br /&gt;
&lt;br /&gt;
See shared setting:&lt;br /&gt;
 git config core.sharedRepository&lt;br /&gt;
 # &amp;quot;&amp;quot;, &amp;quot;group&amp;quot;, etc...&lt;br /&gt;
&lt;br /&gt;
 echo $?&lt;br /&gt;
 # rc 0 means shared, rc 1 means NOT shared&lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
 cd /path/to/repo.git&lt;br /&gt;
 chgrp -R groupname .&lt;br /&gt;
 chmod -R g+rwX .&lt;br /&gt;
 find . -type d -exec chmod g+s &#039;{}&#039; +&lt;br /&gt;
&lt;br /&gt;
 # set share setting&lt;br /&gt;
 git config core.sharedRepository group  # set group shared&lt;br /&gt;
&lt;br /&gt;
 # Verify:&lt;br /&gt;
 git config core.sharedRepository   # &amp;quot;group&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you really hate permissions:&lt;br /&gt;
 git config core.sharedRepository world&lt;br /&gt;
&lt;br /&gt;
Not sure what level this does:&lt;br /&gt;
 git config core.sharedRepository true&lt;br /&gt;
&lt;br /&gt;
References:&lt;br /&gt;
* Git Push Error: insufficient permission for adding an object to repository database - Stack Overflow - http://stackoverflow.com/questions/6448242/git-push-error-insufficient-permission-for-adding-an-object-to-repository-datab&lt;br /&gt;
&lt;br /&gt;
== Windows SSH Debugging ==&lt;br /&gt;
&lt;br /&gt;
 set GIT_SSH_COMMAND=ssh -vvv&lt;br /&gt;
&lt;br /&gt;
 # or if from Windows Git-Bash:&lt;br /&gt;
 export GIT_SSH_COMMAND=&amp;quot;ssh -vvv&amp;quot;&lt;br /&gt;
 export GIT_TRACE=1&lt;br /&gt;
 export GIT_CURL_VERBOSE=1&lt;br /&gt;
 export GIT_TRACE_PACKET=1&lt;br /&gt;
&lt;br /&gt;
 export GIT_TRACE=1 GIT_CURL_VERBOSE=1 GIT_TRANSFER_TRACE=1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/47318691/how-can-i-run-git-commands-on-windows-with-ssh-verbose-mode]&lt;br /&gt;
&lt;br /&gt;
== Empty Email Commit ==&lt;br /&gt;
&lt;br /&gt;
 git config --global user.name &#039;Snail Mail&#039;&lt;br /&gt;
 git config --global user.email &#039;&amp;lt;&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
 git commit --author &amp;quot;Snail Mail &amp;lt;&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ref: [https://stackoverflow.com/questions/7372970/git-commit-with-no-email]&lt;br /&gt;
&lt;br /&gt;
== Windows No Mutual Signature Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Set verbose:&lt;br /&gt;
 set GIT_SSH_COMMAND=ssh -vvv&lt;br /&gt;
&lt;br /&gt;
Try the git command:&lt;br /&gt;
 git clone...&lt;br /&gt;
&lt;br /&gt;
Error:&lt;br /&gt;
 debug1: send_pubkey_test: no mutual signature algorithm&lt;br /&gt;
&lt;br /&gt;
In order to re-enable ssh-rsa support, inserting the following line into the affected SSH client&#039;s config file can re-enable this algorithm:&lt;br /&gt;
&lt;br /&gt;
 PubkeyAcceptedKeyTypes +ssh-rsa&lt;br /&gt;
&lt;br /&gt;
ref: [https://confluence.atlassian.com/bitbucketserverkb/ssh-rsa-key-rejected-with-message-no-mutual-signature-algorithm-1026057701.html]&lt;br /&gt;
&lt;br /&gt;
== Samba Line Endings ==&lt;br /&gt;
&lt;br /&gt;
Check line endings:&lt;br /&gt;
 git ls-files --eol&lt;br /&gt;
&lt;br /&gt;
Ignore file mode:&lt;br /&gt;
 git config --system core.filemode false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remove every file from Git&#039;s index. &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/5787937/git-status-shows-files-as-changed-even-though-contents-are-the-same&amp;lt;/ref&amp;gt;&lt;br /&gt;
 git rm --cached -r .&lt;br /&gt;
&lt;br /&gt;
Rewrite the Git index to pick up all the new line endings.&lt;br /&gt;
 git reset --hard&lt;br /&gt;
&lt;br /&gt;
== Windows Auto Line Ending ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[core]&lt;br /&gt;
	# autocrlf - https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings&lt;br /&gt;
	autocrlf = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 git config --global core.autocrlf true&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
If you’re on a Linux or macOS system that uses LF line endings, then you don’t want Git to automatically convert them when you check out files; however, if a file with CRLF endings accidentally gets introduced, then you may want Git to fix it. You can tell Git to convert CRLF to LF on commit but not the other way around by setting core.autocrlf to input:&lt;br /&gt;
&lt;br /&gt;
 $ git config --global core.autocrlf input&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Warning you will git when trying to add text files:&lt;br /&gt;
 $ git add test.txt&lt;br /&gt;
 warning: in the working copy of &#039;test.txt&#039;, LF will be replaced by CRLF the next time Git touches it&lt;br /&gt;
&lt;br /&gt;
== Windows Long File Names Support ==&lt;br /&gt;
&lt;br /&gt;
Global across all your repos (~/.gitconfig)&lt;br /&gt;
 git config --global core.longpaths true&lt;br /&gt;
&lt;br /&gt;
Systemwide for all users (C:\Program Files\Git\etc\gitconfig)&lt;br /&gt;
 git config --system core.longpaths true&lt;br /&gt;
&lt;br /&gt;
== Git Gud ==&lt;br /&gt;
&lt;br /&gt;
 gud = !echo &#039;Not likely, go home you&#039;\\&#039;&#039;re drunk&#039;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
=== To Read ===&lt;br /&gt;
&lt;br /&gt;
SVN for Git:&lt;br /&gt;
* http://git-scm.com/course/svn.html&lt;br /&gt;
* https://github.com/blog/626-announcing-svn-support&lt;br /&gt;
* http://hub.witness.org/en/blog/yat-tibet&lt;br /&gt;
* http://help.github.com/svn-importing/&lt;br /&gt;
* https://github.com/blog/644-subversion-write-support&lt;br /&gt;
* https://github.com/blog/626-announcing-svn-support&lt;br /&gt;
* http://learn.github.com/p/git-svn.html&lt;br /&gt;
* http://stackoverflow.com/questions/807782/google-code-svn-or-github-git&lt;br /&gt;
* http://tomas.markauskas.net/en/blog/20100505-github-subversion-support&lt;br /&gt;
* https://github.com/blog/626-announcing-svn-support&lt;br /&gt;
* https://github.com/blog/644-subversion-write-support&lt;br /&gt;
* https://github.com/blog/31-back-to-subversion&lt;br /&gt;
* http://svnhub.com/&lt;br /&gt;
* https://github.com/blog/31-back-to-subversion&lt;br /&gt;
* http://git-scm.com/course/svn.html&lt;br /&gt;
* https://github.com/blog/626-announcing-svn-support&lt;br /&gt;
* https://github.com/blog/626-announcing-svn-support&lt;br /&gt;
* http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-rename.html&lt;br /&gt;
* http://www.devdaily.com/blog/post/svn/move-directory-with-subversion-svn&lt;br /&gt;
* http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=GitHub/gpg&amp;diff=10080</id>
		<title>GitHub/gpg</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=GitHub/gpg&amp;diff=10080"/>
		<updated>2026-07-23T20:43:39Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== gpg ==&lt;br /&gt;
&lt;br /&gt;
 Adding a GPG key to your GitHub account - GitHub Docs&lt;br /&gt;
 https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account&lt;br /&gt;
&lt;br /&gt;
Generate key:&lt;br /&gt;
 gpg --full-generate-key&lt;br /&gt;
&lt;br /&gt;
List keys to get keyID&lt;br /&gt;
 gpg --list-keys&lt;br /&gt;
&lt;br /&gt;
Export public key by keyID, and save to Github&lt;br /&gt;
 gpg --armor --export 3AA5C34371xxx&lt;br /&gt;
&lt;br /&gt;
You will probably get an error about being unable to sign if you are in a remote console, to fix this: &amp;lt;ref&amp;gt;https://stackoverflow.com/questions/51504367/gpg-agent-forwarding-inappropriate-ioctl-for-device&amp;lt;/ref&amp;gt;&lt;br /&gt;
 export GPG_TTY=$(tty)&lt;br /&gt;
&lt;br /&gt;
Cache password in gpg-agent:&lt;br /&gt;
 echo &amp;quot;&amp;quot; | gpg --clearsign&lt;br /&gt;
&lt;br /&gt;
 ~/.bashrc&lt;br /&gt;
 alias gpgpass=&amp;quot;echo &#039;&#039; | gpg --clearsign&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you really hate security, you can remove the passphrase:&lt;br /&gt;
 gpg --edit-key XXX&lt;br /&gt;
   passwd&lt;br /&gt;
    enter password to unlock&lt;br /&gt;
    then enter empty password twice&lt;br /&gt;
    then save&lt;br /&gt;
&lt;br /&gt;
Restart agent&lt;br /&gt;
&lt;br /&gt;
==== Reset GPG Agent ====&lt;br /&gt;
&lt;br /&gt;
Reset GPG agent: &amp;lt;ref&amp;gt;https://superuser.com/questions/1075404/how-can-i-restart-gpg-agent&amp;lt;/ref&amp;gt;&lt;br /&gt;
 gpgconf --kill gpg-agent&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
&lt;br /&gt;
 gpg-connect-agent reloadagent /bye&lt;br /&gt;
&lt;br /&gt;
 systemctl --user status gpg-agent&lt;br /&gt;
 systemctl --user stop gpg-agent&lt;br /&gt;
 systemctl --user start gpg-agent&lt;br /&gt;
&lt;br /&gt;
 gpg-connect-agent /bye&lt;br /&gt;
&lt;br /&gt;
 # kill the agent&lt;br /&gt;
 gpg-connect-agent killagent /bye&lt;br /&gt;
 # start it again&lt;br /&gt;
 gpg-connect-agent /bye&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Linux/git&amp;diff=10079</id>
		<title>Linux/git</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Linux/git&amp;diff=10079"/>
		<updated>2026-07-23T20:41:32Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: Created page with &amp;quot;See Git&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See [[Git]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
	<entry>
		<id>https://aznot.com/index.php?title=Artifactory&amp;diff=10078</id>
		<title>Artifactory</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=Artifactory&amp;diff=10078"/>
		<updated>2026-07-23T20:38:55Z</updated>

		<summary type="html">&lt;p&gt;Kenneth: /* Access Token Creation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== jfrog cli ==&lt;br /&gt;
&lt;br /&gt;
Installation - https://jfrog.com/getcli/&lt;br /&gt;
&lt;br /&gt;
Debian/Ubuntu:&lt;br /&gt;
 # Create the keyrings directory if it doesn&#039;t exist&lt;br /&gt;
 sudo mkdir -p /usr/share/keyrings;&lt;br /&gt;
&lt;br /&gt;
 # Download and save the JFrog GPG key to a keyring file&lt;br /&gt;
 wget -qO - https://releases.jfrog.io/artifactory/api/v2/repositories/jfrog-debs/keyPairs/primary/public | sudo gpg --dearmor -o /usr/share/keyrings/jfrog.gpg&lt;br /&gt;
&lt;br /&gt;
 # Add the JFrog repository to your APT sources with the signed-by option&lt;br /&gt;
 echo &amp;quot;deb [signed-by=/usr/share/keyrings/jfrog.gpg] https://releases.jfrog.io/artifactory/jfrog-debs focal contrib&amp;quot; | sudo tee /etc/apt/sources.list.d/jfrog.list&lt;br /&gt;
&lt;br /&gt;
 # Update the package list&lt;br /&gt;
 sudo apt update&lt;br /&gt;
&lt;br /&gt;
 # Install the JFrog CLI&lt;br /&gt;
 sudo apt install -y jfrog-cli-v2-jf&lt;br /&gt;
&lt;br /&gt;
 # Run the JFrog CLI intro command&lt;br /&gt;
 jf intro&lt;br /&gt;
&lt;br /&gt;
 OLD:&lt;br /&gt;
 # wget -qO - https://releases.jfrog.io/artifactory/jfrog-gpg-public/jfrog_public_gpg.key | sudo apt-key add -&lt;br /&gt;
 # # echo &amp;quot;deb https://releases.jfrog.io/artifactory/jfrog-debs xenial contrib&amp;quot; | sudo tee -a /etc/apt/sources.list.d/jfrog.list &amp;amp;&amp;amp;  sudo apt update&lt;br /&gt;
 # echo &amp;quot;deb https://releases.jfrog.io/artifactory/jfrog-debs noble contrib&amp;quot; | sudo tee -a /etc/apt/sources.list.d/jfrog.list &amp;amp;&amp;amp;  sudo apt update&lt;br /&gt;
 # sudo apt install -y jfrog-cli-v2-jf&lt;br /&gt;
 # jf intro&lt;br /&gt;
&lt;br /&gt;
Redhat:&lt;br /&gt;
 # Create and configure the JFrog CLI YUM repository&lt;br /&gt;
 echo &amp;quot;[jfrog-cli]&amp;quot; &amp;gt; jfrog-cli.repo &amp;amp;&amp;amp;&lt;br /&gt;
 echo &amp;quot;name=JFrog CLI&amp;quot; &amp;gt;&amp;gt; jfrog-cli.repo &amp;amp;&amp;amp;&lt;br /&gt;
 echo &amp;quot;baseurl=https://releases.jfrog.io/artifactory/jfrog-rpms&amp;quot; &amp;gt;&amp;gt; jfrog-cli.repo &amp;amp;&amp;amp;&lt;br /&gt;
 echo &amp;quot;enabled=1&amp;quot; &amp;gt;&amp;gt; jfrog-cli.repo &amp;amp;&amp;amp;&lt;br /&gt;
 echo &amp;quot;gpgcheck=1&amp;quot; &amp;gt;&amp;gt; jfrog-cli.repo &amp;amp;&amp;amp; &lt;br /&gt;
&lt;br /&gt;
 # Import GPG keys for verifying packages&lt;br /&gt;
 # Note: Two keys are imported for backward compatibility with older versions&lt;br /&gt;
 rpm --import https://releases.jfrog.io/artifactory/api/v2/repositories/jfrog-rpms/keyPairs/primary/public &amp;amp;&amp;amp;&lt;br /&gt;
 rpm --import https://releases.jfrog.io/artifactory/api/v2/repositories/jfrog-rpms/keyPairs/secondary/public &amp;amp;&amp;amp;&lt;br /&gt;
&lt;br /&gt;
 # Move the repository file to the YUM configuration directory&lt;br /&gt;
 sudo mv jfrog-cli.repo /etc/yum.repos.d/ &amp;amp;&amp;amp;&lt;br /&gt;
&lt;br /&gt;
 # Install the JFrog CLI package&lt;br /&gt;
 yum install -y jfrog-cli-v2-jf &amp;amp;&amp;amp;&lt;br /&gt;
&lt;br /&gt;
 # Display an introductory message for JFrog CLI&lt;br /&gt;
 jf intro&lt;br /&gt;
&lt;br /&gt;
== Artifactory JFrog Client Commands ==&lt;br /&gt;
&lt;br /&gt;
=== Ping server ===&lt;br /&gt;
 jf rt ping&lt;br /&gt;
  ok&lt;br /&gt;
&lt;br /&gt;
=== Show config ===&lt;br /&gt;
 jf c s  # jf config show&lt;br /&gt;
&lt;br /&gt;
=== Add artifactory ===&lt;br /&gt;
 jf c add  # jf config add&lt;br /&gt;
     server id: simple name&lt;br /&gt;
     url: http://artifactory.example.com/&lt;br /&gt;
       save and continue (assuming the urls are correct)&lt;br /&gt;
     username: your username&lt;br /&gt;
     pass/api: your password or api key&lt;br /&gt;
     reverse proxy?  likely no&lt;br /&gt;
&lt;br /&gt;
 jf c add ...&lt;br /&gt;
 CI=true  jf c add sandisk --url [url] --artifactory-url [url]/artifactory&lt;br /&gt;
 CI=true  jf c add sandisk --url https://artifactory.example.com/ --artifactory-url https://artifactory.example.com/artifactory&lt;br /&gt;
&lt;br /&gt;
=== Search file ===&lt;br /&gt;
 jf rt s [repo/pattern]  # pattern can use wild cards&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
# jf rt s myrepo/test/BUILD_NUMBER&lt;br /&gt;
13:42:58 [🔵Info] Searching artifacts...&lt;br /&gt;
13:42:58 [🔵Info] Found 1 artifact.&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;path&amp;quot;: &amp;quot;myrepo/test/BUILD_NUMBER&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;file&amp;quot;,&lt;br /&gt;
    &amp;quot;size&amp;quot;: 38,&lt;br /&gt;
    &amp;quot;created&amp;quot;: &amp;quot;2023-07-26T18:25:55.912Z&amp;quot;,&lt;br /&gt;
    &amp;quot;modified&amp;quot;: &amp;quot;2023-07-28T00:32:13.868Z&amp;quot;,&lt;br /&gt;
    &amp;quot;sha1&amp;quot;: &amp;quot;b43cda47086846025ca5aaa6256372bc2550xxxx&amp;quot;,&lt;br /&gt;
    &amp;quot;sha256&amp;quot;: &amp;quot;62cce4682d3700b62d5dba0a098b65af928149576f614c51f5c7a03b99xxxxx&amp;quot;,&lt;br /&gt;
    &amp;quot;md5&amp;quot;: &amp;quot;bd11639e2c9022ce8ab12d1eda61xxx&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Access Token Creation ===&lt;br /&gt;
&lt;br /&gt;
 jf access-token-create&lt;br /&gt;
 jf atc&lt;br /&gt;
&lt;br /&gt;
Refresh tokens are commonly UUID-like strings&lt;br /&gt;
 eg. f1782ce5-5683-444d-8c17-1f62bdace278&lt;br /&gt;
&lt;br /&gt;
Access tokens typically start with:&lt;br /&gt;
 eyJ...&lt;br /&gt;
&lt;br /&gt;
Reference tokens often start with something resembling:&lt;br /&gt;
 cmVm...&lt;br /&gt;
&lt;br /&gt;
Create a token that expires in 90 days:&lt;br /&gt;
 jf atc --expiry=7776000 --description=&amp;quot;CLI token&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 90 days * 24 hours per day * 60 minutes per hour * 60 seconds per minute = 7776000 seconds&lt;br /&gt;
&lt;br /&gt;
Create a token that expires in 180 days:&lt;br /&gt;
 jf atc --expiry=15552000 --description=&amp;quot;CLI token&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 180 days * 24 hours per day * 60 minutes per hour * 60 seconds per minute = 15552000 seconds&lt;br /&gt;
&lt;br /&gt;
Create a refreshable token:&lt;br /&gt;
 jf atc --refreshable=true&lt;br /&gt;
 jf atc --refreshable&lt;br /&gt;
&lt;br /&gt;
Return a reference token as well:&lt;br /&gt;
 jf atc --reference=true&lt;br /&gt;
 jf atc --reference&lt;br /&gt;
&lt;br /&gt;
Create a 90 day refreshable token with short reference token:&lt;br /&gt;
 jf atc --expiry=7776000 --description=&amp;quot;CLI token&amp;quot; --refreshable --reference&lt;br /&gt;
&lt;br /&gt;
 Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;scope&amp;quot;: &amp;quot;applied-permissions/user&amp;quot;,&lt;br /&gt;
  &amp;quot;access_token&amp;quot;: &amp;quot;eyJ....xxx_REALLY_REALLY_LONG_TOKEN_xxx&amp;quot;,&lt;br /&gt;
  &amp;quot;expires_in&amp;quot;: 7776000,&lt;br /&gt;
  &amp;quot;token_type&amp;quot;: &amp;quot;Bearer&amp;quot;,&lt;br /&gt;
  &amp;quot;refresh_token&amp;quot;: &amp;quot;59372fb0-xxxx-xxxx-xxxx-xxxxxxxxxxxx&amp;quot;,&lt;br /&gt;
  &amp;quot;reference_token&amp;quot;: &amp;quot;cmVxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;quot;,&lt;br /&gt;
  &amp;quot;token_id&amp;quot;: &amp;quot;f28a7682-xxxx-xxxx-xxxx-xxxxxxxxxxxx&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Refresh refreshable access token:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ACCESS_TOKEN=&amp;quot;access_token content&amp;quot;&lt;br /&gt;
REFRESH_TOKEN=&amp;quot;refresh_token content&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -v \&lt;br /&gt;
  -X POST \&lt;br /&gt;
  &amp;quot;https://artifactory.example.com/access/api/v1/tokens&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ACCESS_TOKEN}&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/x-www-form-urlencoded&amp;quot; \&lt;br /&gt;
  -d &amp;quot;grant_type=refresh_token&amp;quot; \&lt;br /&gt;
  -d &amp;quot;refresh_token=${REFRESH_TOKEN}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to include a reference token:&lt;br /&gt;
 -d &amp;quot;include_reference_token=true&amp;quot; \&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -v \&lt;br /&gt;
  -X POST \&lt;br /&gt;
  &amp;quot;https://artifactory.example.com/access/api/v1/tokens&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer ${ACCESS_TOKEN}&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/x-www-form-urlencoded&amp;quot; \&lt;br /&gt;
  -d &amp;quot;grant_type=refresh_token&amp;quot; \&lt;br /&gt;
  -d &amp;quot;include_reference_token=true&amp;quot; \&lt;br /&gt;
  -d &amp;quot;refresh_token=${REFRESH_TOKEN}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decode the expiration date:  (expiration = creation_time + expires_in)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TOKEN=&amp;quot;eyJhbGciOi...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
python3 -c &#039;&lt;br /&gt;
import base64,json,time&lt;br /&gt;
t=&amp;quot;&#039;$TOKEN&#039;&amp;quot;&lt;br /&gt;
payload=t.split(&amp;quot;.&amp;quot;)[1]&lt;br /&gt;
payload += &amp;quot;=&amp;quot; * (-len(payload) % 4)&lt;br /&gt;
d=json.loads(base64.urlsafe_b64decode(payload))&lt;br /&gt;
print(json.dumps(d, indent=2))&lt;br /&gt;
print(&amp;quot;Expires:&amp;quot;, time.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;, time.localtime(d[&amp;quot;exp&amp;quot;])))&lt;br /&gt;
&#039;&lt;br /&gt;
&lt;br /&gt;
 # or&lt;br /&gt;
 echo $TOKEN | cut -d. -f2 | base64 -d | jq .&lt;br /&gt;
   # &amp;quot;exp&amp;quot;: 1787423456&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get tokens:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl \&lt;br /&gt;
  -H &amp;quot;Authorization: Bearer $ACCESS_TOKEN&amp;quot; \&lt;br /&gt;
  https://artifactory.example.com/access/api/v1/tokens&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;tokens&amp;quot; : [ {&lt;br /&gt;
    &amp;quot;token_id&amp;quot; : &amp;quot;961cad32-...&amp;quot;,&lt;br /&gt;
    &amp;quot;subject&amp;quot; : &amp;quot;jf-access@a0a259fa-.../users/some.user@example.com&amp;quot;,&lt;br /&gt;
    &amp;quot;expiry&amp;quot; : 1800379731,&lt;br /&gt;
    &amp;quot;issued_at&amp;quot; : 1784827731,&lt;br /&gt;
    &amp;quot;issuer&amp;quot; : &amp;quot;jf-access@a0a259fa-...&amp;quot;,&lt;br /&gt;
    &amp;quot;description&amp;quot; : &amp;quot;CLI token&amp;quot;,&lt;br /&gt;
    &amp;quot;refreshable&amp;quot; : true,&lt;br /&gt;
    &amp;quot;scope&amp;quot;: &amp;quot;applied-permissions/user&amp;quot;&lt;br /&gt;
  }, {&lt;br /&gt;
  ...&lt;br /&gt;
  } ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NOTE: this also worked:&lt;br /&gt;
&lt;br /&gt;
curl -H &amp;quot;Authorization: Bearer $REFERENCE_TOKEN&amp;quot; \&lt;br /&gt;
     https://artifactory.sandisk.com/access/api/v1/tokens&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
&lt;br /&gt;
=== Test Connection ===&lt;br /&gt;
&lt;br /&gt;
 GET /api/v1/system/ping&lt;br /&gt;
&lt;br /&gt;
 curl -X GET &amp;quot;http://ARTIFACTORY_SERVER_HOSTNAME:8082/distribution/api/v1/system/ping&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ref: https://jfrog.com/help/r/jfrog-rest-apis/test-connection&lt;br /&gt;
&lt;br /&gt;
=== Get System Info ===&lt;br /&gt;
&lt;br /&gt;
 GET /api/v1/system/info&lt;br /&gt;
&lt;br /&gt;
 curl -u myUser:myP455w0rd! -X GET &amp;quot;http://ARTIFACTORY_SERVER_HOSTNAME:8082/distribution/api/v1/system/info&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ref: https://jfrog.com/help/r/jfrog-rest-apis/get-system-info&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
</feed>